keyd
keyd copied to clipboard
Extra `ctrl` for remap from `alt+altgr` layer
Hi)
Operating System: Arch Linux
Kernel: Linux 5.18.5-arch1-1 Architecture: x86-64 keyd: v2.4.1 (bb49007)
altgr + alt + h
maps to left
. When I press alt
then altgr
then h
it works as expected. However, if I first press altgr
then alt
then h
, extra ctrl
presses and releases are generated.
rasaro ~ $ sudo keyd -m
device added: 0fac:0ade (keyd virtual device)
device added: 1532:022b (Razer Razer Tartarus V2)
device added: 1532:022b (Razer Razer Tartarus V2 Keyboard)
device added: 1532:022b (Razer Razer Tartarus V2)
device added: 045e:082c (Microsoft Microsoft Ergonomic Keyboard Mouse)
device added: 045e:082c (Microsoft Microsoft Ergonomic Keyboard)
device added: 1b1c:1b70 (Corsair CORSAIR M55 RGB PRO Gaming Mouse)
device added: 1b1c:1b70 (Corsair CORSAIR M55 RGB PRO Gaming Mouse)
keyd virtual device 0fac:0ade enter up
# when pres `alt+altgr+h` all ok
# press `alt+altgr`
keyd virtual device 0fac:0ade leftalt down
keyd virtual device 0fac:0ade rightalt down
# press `h`
keyd virtual device 0fac:0ade leftalt up
keyd virtual device 0fac:0ade rightalt up
keyd virtual device 0fac:0ade left down
# release `h`
keyd virtual device 0fac:0ade left up
keyd virtual device 0fac:0ade leftalt down
keyd virtual device 0fac:0ade rightalt down
# release `alt+altgr`
keyd virtual device 0fac:0ade leftalt up
keyd virtual device 0fac:0ade rightalt up
# when pres `altgr+alt+h` got `ctrl` press and release
# press `altgr+alt`
keyd virtual device 0fac:0ade rightalt down
keyd virtual device 0fac:0ade leftalt down
# press `h`
keyd virtual device 0fac:0ade leftcontrol down # ???
keyd virtual device 0fac:0ade leftalt up
keyd virtual device 0fac:0ade leftcontrol up # ???
keyd virtual device 0fac:0ade rightalt up
keyd virtual device 0fac:0ade left down
# release `h`
keyd virtual device 0fac:0ade left up
keyd virtual device 0fac:0ade leftalt down
keyd virtual device 0fac:0ade rightalt down
# release `altgr+alt`
keyd virtual device 0fac:0ade rightalt up
keyd virtual device 0fac:0ade leftalt up
Config:
# Microsoft Ergonomic Keyboard (LXM-00001)
[ids]
045e:082c
[main]
[control]
leftshift = timeout(swap(for_fakemeta_C_S), 1, layer(shift))
[shiftr:S]
#### FAKE META ################################################################
[for_fakemeta_C_S:C-S]
leftalt = timeout(swap(for_fakemeta_C_S_A), 1, layer(alt))
[for_fakemeta_C_S_A:C-S-A]
leftmeta = swap(fakemeta)
[fakemeta:M]
#### ALT VIM ##################################################################
[altgr+alt]
h = left
j = down
k = up
l = right
w = C-right
b = C-left
d = delete
a = home
; = end
/ = C-f
[altgr+alt+meta]
h = A-left
j = A-down
k = A-up
l = A-right
[altgr+alt+control]
f = pagedown
b = pageup
The same happens for j
, k
, l
. Didn't check the rest.
Help me please.
This is by design to prevent certain issues, see here. Does this impact functionality in your case?
Yes it does imact functionality in my case.
This is usually not noticeable, but in the application for training hotkeys, I prescribe a sequence of keystrokes and ambiguity is critical here.
Oh, I see. In my case, I'm happy that the functionality is there, otherwise it would mess up my firefox sessions. For the moment, you could fix this by inserting the additional control key presses in your prescriptions.
@rvaiya would it make sense to add a deactivation flag in [global]?
@andrey-shigantsov
Can you elaborate on your use case? The obvious solution is to temporarily disable keyd while you are running such a program (e.g alias train="sudo systemctl stop keyd; <program>; sudo systemctl start keyd"
), but I'm curious to know why you find keyd macros insufficient.
@rvaiya would it make sense to add a deactivation flag in [global]?
I might consider adding a config option to disable the default behaviour, but I will have to think about the potential implications.
disable keyd
It would be possible to go for it, but this is an unnecessary inconvenience.
but I'm curious to know why you find keyd macros insufficient
I don't understand how macros can help me with this. I'll think about it.
@rvaiya would it make sense to add a deactivation flag in [global]?
It would be nice if you add the ability to disable the default behavior.
Also, a normal solution would be to unify the behavior for both orders of pressing: alt
then altgr
and altgr
then alt
... Although I still think the solution to generate control is a crutch.
I also have problems with some programs when using remapping. For example, the slack captures the first alt
press and shifts the focus to the menu... So a crutch with controls is not a panacea.
I don't understand how macros can help me with this. I'll think about it.
My understanding is that you are using another remapping tool to achieve some kind of macro behaviour. In general, you should try to do all your remapping in keyd. Is there a usecase you feel is not covered?
Also, a normal solution would be to unify the behavior for both orders of pressing: alt then altgr and altgr then alt ... Although I still think the solution to generate control is a crutch.
This is by design. The goal is to minimize unnecessary interference. altgr
acts an intervening stroke obviating the need for control
. If you reverse the order, the window manager sees <alt down> <alt up>
which it interprets as an alt tap, necessitating the use of an additional control
to prevent it from misinterpreting the result.
I also have problems with some programs when using remapping. For example, the slack captures the first alt press and shifts the focus to the menu...
Can you elaborate on this? What is the problematic key sequence in this case?
So a crutch with controls is not a panacea.
There are no panaceas, only better approximations of sane default behaviour. This shouldn't be an issue for the vast majority of software, but when you get into the realm of overloading there are some inherently ambiguous cases for which there is no obviously 'correct' solution.
My understanding is that you are using another remapping tool to achieve some kind of macro behaviour.
No) I use keyd only)
Here is my view regarding this issue:
If any control on the automatically inserted modifiers is given to the end user, I think it would not be enough to simply allow a global disable flag. Instead, there should be full control, i.e. the ability to optionally specify the type of inserted modifier (or none, disabling insertion) on a per-layer layer level as well, and in addition for each overload command (for example by introducing a separate overload2 command).
However, as these changes not only require quite some work, but also increase complexity, I think that a rather strong use case is needed. In my opinion, the case of the hotkey training application is not strong enough, as such applications are typically run in isolation (without any multitasking) and thus keyd can simply be disabled during use.
@andrey-shigantsov: I would be very interested in the concrete usability problems you're having with slack as well, i.e. details on
I also have problems with some programs when using remapping. For example, the slack captures the first alt press and shifts the focus to the menu...
Also, there is always the (rather cumbersome) possibility to fix the issue by mapping alt to a new layer without any modifiers set and then explicitly binding keys with modifier prefix (a = A-a
, b= A-b
), leaving those out which should differ from standard behaviour.
Another use case where the additional inserted modifiers break expected behavior: If a mouse button is mapped to an overloaded key, then some programs expecting mouse clicks get confused. For example, scrot exits prematurely when called with the -s
flag (which expects two successive mouse clicks to determine the rectangle it then takes a screenshot of).
No) I use keyd only)
Can you elaborate? What are you using the 'hotkey training' program for?
However, as these changes not only require quite some work, but also increase complexity, I think that a rather strong use case is needed. In my opinion, the case of the hotkey training application is not strong enough, as such applications are typically run in isolation (without any multitasking) and thus keyd can simply be disabled during use.
+1
: If a mouse button is mapped to an overloaded key, then some programs expecting mouse clicks get confused. For example, scrot exits prematurely when called with the -s flag (which expects two successive mouse clicks to determine the rectangle it then takes a screenshot of).
Can you provide an example of this? Overloading necessarily sends the associated modifiers immediately on key (or button) down, this is by design and is distinct from the additional modifiers being discussed (if I've understood you correctly).
: If a mouse button is mapped to an overloaded key, then some programs expecting mouse clicks get confused. For example, scrot exits prematurely when called with the -s flag (which expects two successive mouse clicks to determine the rectangle it then takes a screenshot of).
Can you provide an example of this? Overloading necessarily sends the associated modifiers immediately on key (or button) down, this is by design and is distinct from the additional modifiers being discussed (if I've understood you correctly).
My apologies, you are absolutely correct, this has nothing to do with the additional modifiers being sent. The behaviour of scrot -s
is to exit immediately when anything else than a mouse key is pressed. I think there is nothing keyd can do better to remedy this problem. Sending layer modifiers only when some other keys are pressed incurs other usability issues, but this could of course be achieved by “inverting” the layer mappings, i.e. removing the associated modifiers from the layer definition and explicitly defining all (or at least most) non-modifier keys on the layer with their desired modifiers. A much simpler solution though would be to alter the behaviour of scrot, for example making it ignore all modifier key presses.
Genesis of the current behaviour: #128
I am contemplating adding an option to disable the default behaviour, but I am still having trouble convincing myself that this isn't an implementation detail that probably shouldn't be toggleable.
@andrey-shigantsov Can you elaborate on what you are trying to achieve? Can't you just train your program on left
? If you really care about event order, can't you just train on both output sequences independently?
The current behaviour is designed to prevent issues in programs which care about alt keypresses (e.g firefox). Without the modifier guard in place altgr+alt+h
will produce <rightalt down> <leftalt down> <leftalt up> <rightalt up> <left>
which the likes of firefox will interpret as <alt> <left>
, opening the menu and causing you to shake your fist at the heavens.
The way I see it is as follows:
Acting on alt tap (as firefox does) by default is bad style, in fact it already bothered me (not enough to do anything about it) before keyd even existed. Besides, I don't know any other mainstream program showing this behavior. Therefore, the inserted control presses can be considered as an ad-hoc fix for firefox users, with side effects which are non-noticeable to the end user in most of the cases.
However, even though the number of users using firefox should by far outweigh those experiencing problems, there is still no reason to exclusively cater to the former.
Therefore, I'm vouching for an option to disable the default behaviour, including proper documentation (to anticipate future complaints here). It would also be nice if the feature could be toggled through the IPC mechanism, allowing hybrid setups where guards are enabled via the application mapper during firefox use only.
I don't know any other mainstream program showing this behavior.
I believe some UI toolkits (GTK?) do this by default. There is also the matter of Gnome, which binds the meta key to the launcher. I agree that this is bad form, but it is a reality that must be accounted for.
However, even though the number of users using firefox should by far outweigh those experiencing problems, there is still no reason to exclusively cater to the former.
I remain unconvinced that disabling the guard is good idea in any instance, though I am open to persuasion on the point if a use case can be presented.
If another remapping tool (the use of which which is generally advised against) relies on sequence order, then it will still need to account for the difference between <alt> <altgr> <left>
and <altgr> <alt> <left>
, even with the guard disabled. This is a fundamental part of the problem of modifier remapping. keyd tries to make as painless as possible, but it is impossible to eliminate all extraneous events.
I don't know any other mainstream program showing this behavior.
I believe some UI toolkits (GTK?) do this by default. There is also the matter of Gnome, which binds the meta key to the launcher. I agree that this is bad form, but it is a reality that must be accounted for.
I was not aware of this, at least for GTK one can deactivate it (I'm using some GTK-programs which do not show this behaviour).
However, even though the number of users using firefox should by far outweigh those experiencing problems, there is still no reason to exclusively cater to the former.
I remain unconvinced that disabling the guard is good idea in any instance, though I am open to persuasion on the point if a use case can be presented.
For me personally, the guard does not cause any usability issue, and because of Gnome and Firefox, it should in any case remain enabled by default.
I think the question whether or not to implement a switch to disable it is at the same level as the question whether or not keyd should map left and right versions of the modifiers to the respective key events instead of using the left version only: Probably completely irrelevant in 99.9% of use cases and purely of value from a theoretical point of view, as both the switch and proper mapping to left and right versions can be perceived as being “cleaner” and more correct. Again, speaking for myself, both of these changes would give me some satisfaction but would have no effect on usability.
What should be done however is mentioning the guard in the documentation.
If another remapping tool (the use of which which is generally advised against) relies on sequence order, then it will still need to account for the difference between
<alt> <altgr> <left>
and<altgr> <alt> <left>
, even with the guard disabled. This is a fundamental part of the problem of modifier remapping. keyd tries to make as painless as possible, but it is impossible to eliminate all extraneous events.
I completely agree, in particular to the part that no other remapping tool should be used.
@rvaiya @herrsimon Sorry for not replying for a long time. A lot has been going on lately...
Can you elaborate on what you are trying to achieve? Can't you just train your program on left? If you really care about event order, can't you just train on both output sequences independently?
Of course I can and it's not an important problem for me. However, I want maximum convenience without having to disable the service in particular cases. Therefore, I think it would be useful to disable the default behavior, which solves the problem for firefox and some other applications that I do not use, but does not solve my problem when using slack.
About problems with the Slack.
I also have problems with some programs when using remapping. For example, the slack captures the first alt press and shifts the focus to the menu...
Can you elaborate on this? What is the problematic key sequence in this case?
I would be very interested in the concrete usability problems you're having with slack as well, i.e. details on
When I press alt (or altgr) inside the slack, the focus shifts from the input field to the menu bar and to return to the input field I need to release and press alt (or altgr) again. See https://user-images.githubusercontent.com/18098085/192240785-72baf38f-ce7e-491a-bd61-e28a1869a23d.mp4.
At the same time, when I hold down two altos, the alt-vim mode is activated (and I have long been accustomed to this) and the focus shift is terribly annoying!
To remedy this, I vouch to make this configurable via a global option, including the modifier to insert (unless there are good reasons why control is superior to, say, shift). In my case, I would probably disable insertion compeletely, purely for cleanliness as it does not cause any usability issues.
However the outcome of this, the functionality should be mentioned somewhere in the documentation.
I've added a flag which allows the user to disable this behaviour to the latest commit. @andrey-shigantsov Let me know if this solves your problem.
Including the modifier to insert (unless there are good reasons why control is superior to, say, shift).
This seems like an implementation detail. I am inclined to leave a hard coded control until it can be demonstrated that alternative modifiers are useful in the real world.
Including the modifier to insert (unless there are good reasons why control is superior to, say, shift).
This seems like an implementation detail. I am inclined to leave a hard coded control until it can be demonstrated that alternative modifiers are useful in the real world.
I now completely agree to this.
For those who would like to use slack and firefox at the same time: Would it make sense to allow setting globals during runtime (keyd set disable_modifier_guard=1
) and expanding the application mapper to support this?
I thought about my proposal of dynamically changing globals a bit more and came to the conclusion that it makes no sense. The only potentially useful option to change dynamically would be disable_modifier_guard
, but in fact changing the global does not solve the problem, at least not in a simple way. It would be much simpler to have the application remapper rebind the alt key or bind an explicit leftalt on some layer for firefox windows.