bindings: Do not grab pointer when executing bindings (#5755)
Grabing the pointer produces a `GrabFrozen` error in applications that
are run from key bindings. Since we don't need the pointer in such
cases, we can change the call to use ASYNC. This seems to be a
historical leftover.
I've tested locally that these still work:
- bindsym $mod+x ...
- bindsym --release $mod+x ...
- bindsym $mod+button1 ...
- bindsym --release $mod+button1 ...
- bindsym --release $mod+x exec program that grabs the keyboard
now works (see original issue)
Even in the main branch, I actually couldn't get `import` and `xdotool`
to fail with the pointer being frozen, potentially because these
programs wait a bit for the pointer to be unfrozen like i3lock does.
This patch came up in
https://github.com/i3/i3/issues/5735#issuecomment-1781321011
I wonder why the pointer is actually grabbed.
The argument I change in `xcb_grab_key` there, is `pointer_mode`, from
https://www.x.org/releases/X11R7.7/doc/man/man3/xcb_grab_key.3.xhtml:
```
pointer_mode
One of the following values:
XCB_GRAB_MODE_SYNC
The state of the keyboard appears to freeze: No further keyboard events are generated by the server until the grabbing client issues a releasing AllowEvents request or until the keyboard grab is released.
XCB_GRAB_MODE_ASYNC
Keyboard event processing continues normally.
```
I traced via `git blame` the usage of `xcb_grab_key` throughout 14 years
of i3 development and it seems that `pointer_mode` was always set to
`XCB_GRAB_MODE_SYNC`, going all the way back to
b664456706
.
Fixes #5735
This commit is contained in:
parent
f1f2282947
commit
b42dc21068
@ -512,8 +512,8 @@ your bindings in the same physical location on the keyboard, use keycodes.
|
||||
If you don’t switch layouts, and want a clean and simple config file, use
|
||||
keysyms.
|
||||
|
||||
Some tools (such as +import+ or +xdotool+) might be unable to run upon a
|
||||
KeyPress event, because the keyboard/pointer is still grabbed. For these
|
||||
Some tools (such as +xdotool+) might be unable to run upon a
|
||||
KeyPress event, because the keyboard is still grabbed. For these
|
||||
situations, the +--release+ flag can be used, which will execute the command
|
||||
after the keys have been released.
|
||||
|
||||
|
1
release-notes/changes/1-grab-pointer
Normal file
1
release-notes/changes/1-grab-pointer
Normal file
@ -0,0 +1 @@
|
||||
do not grab pointer when executing bindings
|
@ -126,9 +126,9 @@ static bool binding_in_current_group(const Binding *bind) {
|
||||
|
||||
static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint32_t keycode) {
|
||||
/* Grab the key in all combinations */
|
||||
#define GRAB_KEY(modifier) \
|
||||
do { \
|
||||
xcb_grab_key(conn, 0, root, modifier, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); \
|
||||
#define GRAB_KEY(modifier) \
|
||||
do { \
|
||||
xcb_grab_key(conn, 0, root, modifier, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); \
|
||||
} while (0)
|
||||
const int mods = (bind->event_state_mask & 0xFFFF);
|
||||
DLOG("Binding %p Grabbing keycode %d with event state mask 0x%x (mods 0x%x)\n",
|
||||
@ -166,7 +166,7 @@ void grab_all_keys(xcb_connection_t *conn) {
|
||||
const int keycode = binding_keycode->keycode;
|
||||
const int mods = (binding_keycode->modifiers & 0xFFFF);
|
||||
DLOG("Binding %p Grabbing keycode %d with mods %d\n", bind, keycode, mods);
|
||||
xcb_grab_key(conn, 0, root, mods, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
||||
xcb_grab_key(conn, 0, root, mods, keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user