FarManager
FarManager copied to clipboard
0002856: Не распознаются комбинации с LCtrlRAlt (AltGr)
English
This PR is not a definitive solution, but an attempt to discuss and find one.
The description of the problem is in the header, reported earlier here https://bugs.farmanager.com/view.php?id=2856
The essence of the problem: in some keyboard layouts, some combinations with AltGr are Dead keys, and should not be handled by Far so as not to conflict with their purpose.
However, at the moment Far cannot detect such keys, and just in case, it prohibits handling ALL combinations with AltGr that do not have a character in UnicodeChar
field.
The right way probably exists, but even if not - I think it's wrong to ban dozens of combinations "just in case", taking care of rather rare cases. As a last resort, it could be removed in far:config
leaving it up to the user to decide if they want these keys or not.
There's one line commented out in the code, and it gives access to all AltGr combinations. For a complete solution, you need to
- either find a way to determine if the pressed key is a Dead key
- or create a new flag for far:config (like
System.EnableAltGrShortcuts
) and add it to the condition.
Этот PR является не окончательным решением, а попыткой обсудить и найти его.
Описание проблемы в заголовке, репортилось ранее тут https://bugs.farmanager.com/view.php?id=2856
Суть проблемы: в некоторых клавиатурных раскладках некоторые комбинации с AltGr являются Dead keys, и не должны обрабатываться фаром, чтобы не конфликтовать со своим предназначением.
Однако в настоящий момент Фар не умеет определять такие клавиши, и на всякий случай запрещает обработку ВСЕХ комбинаций с AltGr, не имеющих символа в поле UnicodeChar
.
Правильный способ вероятно существует, но даже если нет - я считаю неверным запрещать десятки комбинаций "на всякий случай", заботясь об довольно редких кейсах. В крайнем случае можно было бы убрать это в far:config
предоставив пользователю решать нужны ему эти клавиши или нет.
В коде закомментирована одна строка, и это даёт доступ ко всем комбинациям AltGr. Для полноценного решения необходимо
- либо найти способ определения является ли нажатая клавиша Dead key
- либо создать новый флаг для
far:config
(типаSystem.EnableAltGrShortcuts
) и добавить его в условие.
Вот немного контекста: https://github.com/FarGroup/FarManager/blob/f15c2b4224ed12b16f7613ea5a9883d59aeb28bb/far/keyboard.cpp#L2162-L2176
В комментарии говорится о шведской раскладке, её можно увидеть например тут https://kbdlayout.info/KBDSW/overview+virtualkeys
+1 for
[С]оздать новый флаг для far:config (типа System.EnableAltGrShortcuts) и добавить его в условие.
найти способ определения является ли нажатая клавиша Dead key
bool IsDead = (MapVirtualKeyEx(Key, MAPVK_VK_TO_CHAR, Layout) & 0x80000000) != 0;
Unfortunately, you have to specify the layout, and console apps are not allowed to see this sacred information. Why? Because such things are only relevant to the local user and may not work over SSH, that's why.
создать новый флаг для far:config (типа System.EnableAltGrShortcuts)
It does not work like that. We cannot opt out of AltGr and dead keys on application level. When you press such a key, the OS sends multiple key events, and subsequent events will be affected regardless of how you process the first one. If we do not try to process them together as designed, we will simply get a mess.
For example, if you have Swedish layout and press RAlt+]
, the next a
will always produce ã
and the next RAlt+]
will always produce ~~
, no matter what lines you have commented in Far.
Для полноценного решения необходимо
Switch to a layout without funny keys if you don't like them, or get MSKLC and create your own. Unfortunately, there are no other proper solutions.
For example, if you have Swedish layout and press RAlt+], the next a will always produce ã and the next RAlt+] will always produce ~~, no matter what lines you have commented in Far.
English
Of course, I tried that, too. Nevertheless, I think that the solution with far:config
parameter is quite reasonable.
Activation of this parameter by the user is a way to tell Far that "although I use AltGr layout, it has no dead keys".
Far cannot check this by itself, so we report this information explicitly.
Разумеется, и я это пробовал. Тем не менее, считаю что решение с параметром far:config
вполне обоснованно.
Активация этого параметра пользователем - это способ сообщить фару что "хоть я и использую раскладку с AltGr, но в ней нет dead keys".
Фар не может это проверить сам, поэтому мы сообщаем эту информацию явно.
Switch to a layout without funny keys if you don't like them, or get MSKLC and create your own.
English
For the Russian layout it's easy, just reassign the ruble symbol. But for other layouts it is problematic, and in fact almost all national layouts use AltGr, i.e. to get rid of the use of this modifier is not easy at all. At the same time dead keys in combination with AltGr - is rare, and if necessary, you can really fix that Swedish layout with MSKLC reassigning the only (sole one) problematic key.
Для русской раскладки это легко, достаточно переназначить символ рубля. Но для других раскладок это проблематично, и ведь практически все национальные раскладки используют AltGr, т.е. избавиться от использования этого модификатора совсем не просто. При этом dead keys на комбинации с AltGr - встречается редко, и при необходимости действительно можно исправить с помощью MSKLC ту же шведскую раскладку, переназначив единственную проблемную клавишу.
"хоть я и использую раскладку с AltGr, но в ней нет dead keys"
So you're ok with the fact that core things like Alt+F1, Alt+F7, Alt+F9 etc. don't work with RAlt (because it's LCtrlRAlt), only non-working LCtrlRAlt combinations is a problem?
So you're ok with the fact that core things like Alt+F1, Alt+F7, Alt+F9 etc. don't work with RAlt (because it's LCtrlRAlt), only non-working LCtrlRAlt combinations is a problem?
English
As it follows from the code comment, the piece of code under discussion blocks keypresses because of the possible presence of dead keys, not because AltGr is in place of RAlt. But yes, LCtrl+RAlt combinations are of course better than full keypresses suppression. I can't say that it's right "ok" for me, but it's something I can work with.
offtopic
If we develop the topic, now Far (though heuristically, but successfully) detects that it deals with AltGr, because it is in Far that LCtrl+LAlt turns into LCtrl+RAlt, if I am interpreting this code correctly: https://github.com/FarGroup/FarManager/blob/f15c2b4224ed12b16f7613ea5a9883d59aeb28bb/far/keyboard.cpp#L1022-L1026
It's only one step from here to trying to remove LCtrl from the equation as well. I suspect that this approach is potentially tricky, but in 99.9% it could work, and in my humble opinion it would be worth trying to implement this as well, under a separate far:config
flag. But that's still a subject for a separate discussion.
Как следует из комментария, обсуждаемый кусок кода блокирует нажатия из-за возможного наличия dead keys, а не потому, что AltGr располагается на месте RAlt. Но да, комбинации LCtrl+RAlt конечно же лучше чем полное подавление нажатий. Не могу сказать что это прямо "ок" для меня, но с этим можно как-то работать.
оффтопик
Если развить тему, то сейчас Фар (хоть и эвристически, но успешно) определяет что имеет дело с AltGr, ведь именно в фаре LCtrl+LAlt превращается в LCtrl+RAlt, если я верно интерпретирую этот код: https://github.com/FarGroup/FarManager/blob/f15c2b4224ed12b16f7613ea5a9883d59aeb28bb/far/keyboard.cpp#L1022-L1026
Отсюда лишь один шаг до того, чтобы попытаться убрать и LCtrl из уравнения. Подозреваю что с этим подходом потенциально не всё гладко, но в 99.9% он мог бы работать, и по моему скромному мнению стоило бы попробовать реализовать и это, под отдельным флагом far:config
. Но это всё же предмет отдельного разговора.
With something like
this
diff --git a/far/console.cpp b/far/console.cpp
index 3a500a548..8e93e508b 100644
--- a/far/console.cpp
+++ b/far/console.cpp
@@ -955,6 +955,16 @@ protected:
}
}
+ static void ungray_alt(span<INPUT_RECORD> const Buffer, size_t const NumberOfEventsRead)
+ {
+ if (
+ NumberOfEventsRead &&
+ Buffer[0].EventType == KEY_EVENT &&
+ (Buffer[0].Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED)) == (LEFT_CTRL_PRESSED | RIGHT_ALT_PRESSED)
+ )
+ Buffer[0].Event.KeyEvent.dwControlKeyState &= ~LEFT_CTRL_PRESSED;
+ }
+
bool console::PeekInput(span<INPUT_RECORD> const Buffer, size_t& NumberOfEventsRead) const
{
DWORD dwNumberOfEventsRead = 0;
@@ -970,6 +980,9 @@ protected:
{
AdjustMouseEvents({Buffer.data(), NumberOfEventsRead}, GetDelta());
}
+
+ ungray_alt(Buffer, NumberOfEventsRead);
+
return true;
}
@@ -995,6 +1008,8 @@ protected:
AdjustMouseEvents({Buffer.data(), NumberOfEventsRead}, GetDelta());
}
+ ungray_alt(Buffer, NumberOfEventsRead);
+
return true;
}
Naturally, this will turn the "real" LCtrlRAlt into RAlt as well, but that's the price.
you can make Far believe that AltGr is RAlt
Seems working, except that sole AlrGr press/release still produces "CtrlRAlt
".
So, what do you think - can discussed here two set of changes go into the master?
two set of changes
The second change makes the first one redundant: if we eliminate LCtrlRAlt entirely, we will never enter that block, so no need to modify it.
go into the master
Perhaps. It's quite questionable, so I'd prefer to see more feedback first.
The second change makes the first one redundant: if we eliminate LCtrlRAlt entirely [...]
Well, it may be safer to preserve some way to opt out of this behavior, just in case. You said you need more feedback - to get it we can change default behavior and wait for feedback. But in case of issues we need some way to compare behavior with and without AltGr...-
I'd prefer to see more feedback first.
Major issue: it's impossible now to enter AltGr-chars. I wish there would be more compatible solution.
Unfortunately, you have to specify the layout, and console apps are not allowed to see this sacred information.
Since 6286 we have the layout information.
@alabuzhev
Quality Gate passed
Issues
1 New issue
0 Accepted issues
Measures
0 Security Hotspots
No data about Coverage
3.9% Duplication on New Code
An issue likely caused by this change: Ctrl+\ doesn't work I expect more issues like this to be reported by other users.
An issue likely caused by this change: Ctrl+\ doesn't work
Wrong, that issue is caused by d1bd437105c571482db230bfb38acd3f722600b8
I expect more issues like this to be reported by other users.
So? What exactly do you propose?
What exactly do you propose?
I added my comment merely for tracking purposes, so that any reader can easily get the wider context. I'm not proposing any action ATM.
An issue likely caused by this change: Ctrl+\ doesn't work
Wrong, that issue is caused by d1bd437
Thanks for the correction