FarManager icon indicating copy to clipboard operation
FarManager copied to clipboard

0002856: Не распознаются комбинации с LCtrlRAlt (AltGr)

Open johnd0e opened this issue 1 year ago • 11 comments

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) и добавить его в условие.

johnd0e avatar Jun 19 '23 11:06 johnd0e

Вот немного контекста: https://github.com/FarGroup/FarManager/blob/f15c2b4224ed12b16f7613ea5a9883d59aeb28bb/far/keyboard.cpp#L2162-L2176

В комментарии говорится о шведской раскладке, её можно увидеть например тут https://kbdlayout.info/KBDSW/overview+virtualkeys

johnd0e avatar Jun 19 '23 11:06 johnd0e

+1 for

[С]оздать новый флаг для far:config (типа System.EnableAltGrShortcuts) и добавить его в условие.

MKadaner avatar Jun 19 '23 18:06 MKadaner

найти способ определения является ли нажатая клавиша 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.

alabuzhev avatar Jun 19 '23 20:06 alabuzhev

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 ту же шведскую раскладку, переназначив единственную проблемную клавишу.

johnd0e avatar Jun 19 '23 20:06 johnd0e

"хоть я и использую раскладку с 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?

alabuzhev avatar Jun 19 '23 22:06 alabuzhev

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. Но это всё же предмет отдельного разговора.

johnd0e avatar Jun 20 '23 07:06 johnd0e

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;
 	}
 
you can make Far believe that AltGr is RAlt.

Naturally, this will turn the "real" LCtrlRAlt into RAlt as well, but that's the price.

alabuzhev avatar Jun 20 '23 17:06 alabuzhev

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?

johnd0e avatar Jun 20 '23 20:06 johnd0e

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.

alabuzhev avatar Jun 21 '23 06:06 alabuzhev

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...-

johnd0e avatar Jun 21 '23 11:06 johnd0e

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.

johnd0e avatar Jun 21 '23 16:06 johnd0e

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

johnd0e avatar Apr 25 '24 11:04 johnd0e

An issue likely caused by this change: Ctrl+\ doesn't work I expect more issues like this to be reported by other users.

HamRusTal avatar May 02 '24 18:05 HamRusTal

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?

johnd0e avatar May 02 '24 19:05 johnd0e

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.

HamRusTal avatar May 02 '24 20:05 HamRusTal

An issue likely caused by this change: Ctrl+\ doesn't work

Wrong, that issue is caused by d1bd437

Thanks for the correction

HamRusTal avatar May 02 '24 20:05 HamRusTal