aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrestis Floros <orestisflo@gmail.com>2023-11-05 11:04:04 +0100
committerGitHub <noreply@github.com>2023-11-05 11:04:04 +0100
commitb42dc21068196dd60a0806575f0f8bb01610fd0e (patch)
treeb21a81a2edd03f92676f4fe8fa6a255de05f3fb6
parentf1f2282947965403fe3e5ac9eda71931841ad37b (diff)
downloadi3-b42dc21068196dd60a0806575f0f8bb01610fd0e.tar.gz
i3-b42dc21068196dd60a0806575f0f8bb01610fd0e.zip
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 b66445670695f48f52988e2cc81d2ea7f03cf237. Fixes #5735
-rw-r--r--docs/userguide4
-rw-r--r--release-notes/changes/1-grab-pointer1
-rw-r--r--src/bindings.c8
3 files changed, 7 insertions, 6 deletions
diff --git a/docs/userguide b/docs/userguide
index d211c1d5..9f11cd2b 100644
--- a/docs/userguide
+++ b/docs/userguide
@@ -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.
diff --git a/release-notes/changes/1-grab-pointer b/release-notes/changes/1-grab-pointer
new file mode 100644
index 00000000..99166644
--- /dev/null
+++ b/release-notes/changes/1-grab-pointer
@@ -0,0 +1 @@
+do not grab pointer when executing bindings
diff --git a/src/bindings.c b/src/bindings.c
index e5804919..88d7182a 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -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);
}
}
}