Closed lierdakil closed 2 years ago
Additionally, the mask is stripped of its high bits, because apparently X likes to encode current layout group information in bits 13 and up, and we don't really want our control keys to depend on the current layout group.
Looks like xmonad core doesn't do this, though. I am puzzled why it'd be needed here and not there.
Otherwise this looks good, although I must admit I know very little about the intricacies of X11 KeySyms and KeyCodes. Oh and it seems like XMonad.Prompt and XMonad.Actions.TreeSelect probably suffer from the same problem?
Looks like xmonad core doesn't do this, though. I am puzzled why it'd be needed here and not there.
Honestly, likewise. Couldn't figure out why core isn't affected. Hence the question on how to handle this better.
FWIW, Prompt also filters high bits out (has been for a while):
but apparently it overfilters, since Button5Mask
is (1<<12)
-- pretty sure the mask should be 1 << 13 - 1
aka 0x1fff
; also the docstring is misleading here -- this isn't really a duplicate of core cleanMask
anymore.
seems like XMonad.Prompt and XMonad.Actions.TreeSelect probably suffer from the same problem?
I don't use TreeSelect, so can't tell you from the top of my head, but looking at the source code it seems very likely. As for Prompt, I didn't notice it being affected. However, there isn't many opportunities to notice, keysym is only used to bind the completion key there. Again, looking at the source, it is also likely. I will try to test and fix as needed over the weekend.
Honestly, likewise. Couldn't figure out why core isn't affected.
Do you have a simple reproducer (xkb layouts, xmonad config and steps to take) so that I can try to figure this out?
Not so sure about simple, but here goes...
XKB layout:
setxkbmap us,de winkeys 'grp:caps_toggle,grp_led:caps,terminate:ctrl_alt_bksp'
this will set layout to US+German with caps lock as layout group toggle key (regular caps lock is on shift+caps). Fair warning, it also enables X termination via ctrl+alt+backspace, which I find useful when debugging X-related stuff, but YMMV.
XMonad config can be almost arbitrary, with GridSelect bound to something. For example:
import XMonad
import qualified XMonad.Actions.GridSelect as GS
import XMonad.Util.EZConfig (additionalKeys)
main = xmonad $ def `additionalKeys`
[ ((controlMask, xK_g), GS.goToSelected def)]
Now, ctrl+g should bring up GridSelect's "go to window" regardless of the currently active layout group (which, reminder, are switched with caps lock key). However, navigation keys (arrows, hjkl, escape, enter) won't work on the grid select when the second layout group is active. So, the steps:
The question is, why ctrl+g in this example works for either layout group.
^^ This is an excellent writeup! 👍
I'll be off for a week or two now so please excuse me for not trying it right away, but I (or perhaps someone else) will get to it later.
FWIW, I've verified that both tree select and prompt have the same issue (with the notable exception of prompt already stripping high bits from the key mask). So I've also fixed those.
Also, with my initial patch, the event handler triggered on key release in addition to key press, while before the patch it only triggered on key press. I've amended that in https://github.com/xmonad/xmonad-contrib/pull/590/commits/68b58694c9abc0024a1d3a593f521389a28bf4ac ; changes to Prompt and TreeSelect also include this additional check.
The question is, why ctrl+g in this example works for either layout group.
I think that the reason is that xmonad core already "does the right thing" here; i.e., we correctly respond to MappingNotify events. According to the Xlib docs this indicates that the keyboard mapping changed and hence we need to refresh our grab.
I think that the reason is that xmonad core already "does the right thing" here; […] refresh our grab.
Hm, so does refreshing the grab mean that subsequent KeyPress events no longer need cleaning the mask? Sounds a bit suspicious.
(Oh and I'm so sorry I totally forgot about this. I mean, not exactly forgot, it's still fairly up in my taskwarrior "soon" list, I'm just really good at inventing other stuff that needs to be done even sooner. 😿)
Hm, so does refreshing the grab mean that subsequent KeyPress events no longer need cleaning the mask? Sounds a bit suspicious.
Mh you're right, refreshing the grab is mainly for KeySym's, but the problem in this case is masks
Finally got to this.
Additionally, the mask is stripped of its high bits, because apparently X likes to encode current layout group information in bits 13 and up, and we don't really want our control keys to depend on the current layout group.
Looks like xmonad core doesn't do this, though. I am puzzled why it'd be needed here and not there.
Turns out this is an XKB compatibility feature. A nice summary of it is here: https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Delivering_a_Key_or_Button_Event_to_a_Client Additional information: https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Setting_a_Passive_Grab_for_an_XKB_State, https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Group_Compatibility_Map, https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Compatibility_Components_of_Keyboard_State, https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State
So I guess that answers all the questions and we can merge this at last. (Actually we should've merged it right away and let me satisfy my curiosity later…) Need to log off now but I'll rebase and merge tomorrow. Sorry again for the delay!
I decided to clean this up a bit and tackle some other related issues, so I opened https://github.com/xmonad/xmonad-contrib/pull/686 instead. Merging that one will close this one.
Description
This changes
makeXEventhandler
to behave much closer to how xmonad itself handles keypresses. The primary difference lies in that xmonad reads raw keycode and then converts it to unmodified keysym, whilemakeXEventhandler
was reading actual keysyms. As a consequence, key definitions like(shiftMap, xK_Tab)
didn't work withmakeXEventhandler
on many layouts because an actual keysym for 'Shift+Tab' is commonlyISO_LEFT_TAB
, and notTab
.Additionally, the mask is stripped of its high bits, because apparently X likes to encode current layout group information in bits 13 and up, and we don't really want our control keys to depend on the current layout group. Please let me know if there is a better way to handle this.
Not updating the changelog just yet, awaiting feedback.
Checklist
[X] I've read CONTRIBUTING.md
[X] I've considered how to best test these changes (property, unit, manually, ...) and concluded:
There were no automated tests for this; I don't know how to make them, either. The code has been tested manually with my xmonad config.
[ ] I updated the
CHANGES.md
file[ ]
I updated theN/AXMonad.Doc.Extending
file (if appropriate)