Repository: qtile/qtile

Issue:
Qtile ignores keystrokes on an alternative keyboard layout
### The issue:

When I am holding down the volume key (`fn + f3`), the key is pressed only once. (on non-default layout)
Although, when I am using default(english) layout  the key press is repeated few times.
I use `setxkbmap` to switch layouts: 
```bash
setxkbmap -layout us,ru,ua -option grp:alt_shift_toggle
```

**Qtile version**: 0.21.0
**Server**: X11
**Qtile logs in debug mode** (when I am holding down the volume up key):
```vim
Ignoring unknown keysym: 269025043, mask: 128
```
Seems legit, because the key is binded to 0 mask `(269025043, 0): <Key ([], XF86AudioRaiseVolume)>`
But why does the key mask is different between the default layout and the non-default layout?


### Required:

- [X] I have searched past issues to see if this bug has already been reported.
Qtile ignores keystrokes on an alternative keyboard layout
### The issue:

When I am holding down the volume key (`fn + f3`), the key is pressed only once. (on non-default layout)
Although, when I am using default(english) layout  the key press is repeated few times.
I use `setxkbmap` to switch layouts: 
```bash
setxkbmap -layout us,ru,ua -option grp:alt_shift_toggle
```

**Qtile version**: 0.21.0
**Server**: X11
**Qtile logs in debug mode** (when I am holding down the volume up key):
```vim
Ignoring unknown keysym: 269025043, mask: 128
```
Seems legit, because the key is binded to 0 mask `(269025043, 0): <Key ([], XF86AudioRaiseVolume)>`
But why does the key mask is different between the default layout and the non-default layout?


### Required:

- [X] I have searched past issues to see if this bug has already been reported.


Discussion:
You can configure key repeated with `xset`. It can be configured on a per-key basis, so maybe that underlies the difference observed between the two layouts.
@m-col `xset` does not help here because it used to set a delay before the key is pressed again. But the problem here, that qtile doesn't recognize the key press, because of mask mismatch. (maybe I should rename the issue)

I will attach the video, so it's easier to understand. (see the volume widget)

Default layout: 

https://user-images.githubusercontent.com/54082016/169531593-8245ba93-ce1a-4d86-a47c-b11b37878fe5.mp4

Non-default layout:



https://user-images.githubusercontent.com/54082016/169532408-4a35d6e2-7a48-4cc9-ad99-fb9c202a813e.mp4





Do you see any differences in `xev`?
As far as I understand, the only difference is the `state`

Xev (default layout):
```vim
KeyPress event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3320554, (-153,968), root:(817,1003),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3321215, (-153,968), root:(817,1003),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3322419, (-153,968), root:(817,1003),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3322459, (-153,968), root:(817,1003),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
```

Xev (non-default layout):
```vim
KeyPress event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3392204, (-99,527), root:(871,562),
    state 0x2010, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3392244, (-99,527), root:(871,562),
    state 0x2010, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3393155, (-99,527), root:(871,562),
    state 0x2010, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3393196, (-99,527), root:(871,562),
    state 0x2010, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
```

I think I may have a solution, though I don't fully understand why the issue is arising (and why it hasn't arisen before).

Please could you run Qtile from source, applying this diff?:
```diff
diff --git a/libqtile/backend/x11/core.py b/libqtile/backend/x11/core.py
index 9800d26c..efd1311e 100644
--- a/libqtile/backend/x11/core.py
+++ b/libqtile/backend/x11/core.py
@@ -155,7 +155,7 @@ class Core(base.Core):
 
         numlock_code = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"])[0]
         self._numlock_mask = xcbq.ModMasks.get(self.conn.get_modifier(numlock_code), 0)
-        self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask)
+        self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask | 0x80)
 
     @property
     def name(self):
```
Or alternatively just insert the change into your installation, it's only small.

Then please could you post any behaviour that changes, whether its fixed or other bugs are introduced?
Wow, thank you! It works perfectly for me. At first glance, it didn't introduce any other bugs, so the issue can be closed.
You can configure key repeated with `xset`. It can be configured on a per-key basis, so maybe that underlies the difference observed between the two layouts.
@m-col `xset` does not help here because it used to set a delay before the key is pressed again. But the problem here, that qtile doesn't recognize the key press, because of mask mismatch. (maybe I should rename the issue)

I will attach the video, so it's easier to understand. (see the volume widget)

Default layout: 

https://user-images.githubusercontent.com/54082016/169531593-8245ba93-ce1a-4d86-a47c-b11b37878fe5.mp4

Non-default layout:



https://user-images.githubusercontent.com/54082016/169532408-4a35d6e2-7a48-4cc9-ad99-fb9c202a813e.mp4





Do you see any differences in `xev`?
As far as I understand, the only difference is the `state`

Xev (default layout):
```vim
KeyPress event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3320554, (-153,968), root:(817,1003),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3321215, (-153,968), root:(817,1003),
    state 0x10, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3322419, (-153,968), root:(817,1003),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x4600001,
    root 0x728, subw 0x0, time 3322459, (-153,968), root:(817,1003),
    state 0x10, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
```

Xev (non-default layout):
```vim
KeyPress event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3392204, (-99,527), root:(871,562),
    state 0x2010, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3392244, (-99,527), root:(871,562),
    state 0x2010, keycode 122 (keysym 0x1008ff11, XF86AudioLowerVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyPress event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3393155, (-99,527), root:(871,562),
    state 0x2010, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 35, synthetic NO, window 0x5c00001,
    root 0x728, subw 0x0, time 3393196, (-99,527), root:(871,562),
    state 0x2010, keycode 123 (keysym 0x1008ff13, XF86AudioRaiseVolume), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
```

I think I may have a solution, though I don't fully understand why the issue is arising (and why it hasn't arisen before).

Please could you run Qtile from source, applying this diff?:
```diff
diff --git a/libqtile/backend/x11/core.py b/libqtile/backend/x11/core.py
index 9800d26c..efd1311e 100644
--- a/libqtile/backend/x11/core.py
+++ b/libqtile/backend/x11/core.py
@@ -155,7 +155,7 @@ class Core(base.Core):
 
         numlock_code = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"])[0]
         self._numlock_mask = xcbq.ModMasks.get(self.conn.get_modifier(numlock_code), 0)
-        self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask)
+        self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask | 0x80)
 
     @property
     def name(self):
```
Or alternatively just insert the change into your installation, it's only small.

Then please could you post any behaviour that changes, whether its fixed or other bugs are introduced?
Wow, thank you! It works perfectly for me. At first glance, it didn't introduce any other bugs, so the issue can be closed.

Resolving patch:
diff --git a/libqtile/backend/x11/core.py b/libqtile/backend/x11/core.py
--- a/libqtile/backend/x11/core.py
+++ b/libqtile/backend/x11/core.py
@@ -155,7 +155,12 @@ def __init__(self, display_name: str | None = None) -> None:
 
         numlock_code = self.conn.keysym_to_keycode(xcbq.keysyms["Num_Lock"])[0]
         self._numlock_mask = xcbq.ModMasks.get(self.conn.get_modifier(numlock_code), 0)
-        self._valid_mask = ~(self._numlock_mask | xcbq.ModMasks["lock"] | xcbq.AllButtonsMask)
+        self._valid_mask = ~(
+            self._numlock_mask
+            | xcbq.ModMasks["lock"]
+            | xcbq.AllButtonsMask
+            | xcbq.PointerMotionHintMask
+        )
 
     @property
     def name(self):
diff --git a/libqtile/backend/x11/xcbq.py b/libqtile/backend/x11/xcbq.py
--- a/libqtile/backend/x11/xcbq.py
+++ b/libqtile/backend/x11/xcbq.py
@@ -86,6 +86,7 @@ def rdict(d):
 AllButtonsMask = 0b11111 << 8
 ButtonMotionMask = 1 << 13
 ButtonReleaseMask = 1 << 3
+PointerMotionHintMask = 1 << 7
 
 NormalHintsFlags = {
     "USPosition": 1,  # User-specified x, y


Test patch: