New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mouse binding with --whole-window and --release does not work #3459

tasnad opened this Issue Oct 15, 2018 · 3 comments


None yet
3 participants

tasnad commented Oct 15, 2018

I'm submitting a…

[x] Bug
[ ] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)

Current Behavior

Assignling this (from the i3 docs, --release added):
bindsym --whole-window --release $mod+button2 kill
only works in the title bar of windows (thus the --whloe-window flag is ignored).
In contrast, these work as intended:
bindsym --whole-window $mod+button2 kill
bindsym --release $mod+button2 kill

Expected Behavior

Kill the window with middle mouse button wherever I click in the window, as long as $mod is pressed.


i3 version: 4.15 (2018-03-10) 
set $mod mod4
bindsym --whole-window --release $mod+button2 kill
Supposedly relevant line from the log:
bindings.c:configure_binding:62 - Binding 0x561a457973f0 bindtype bindsym, modifiers Mod4, input code button2, release --release
- Arch Linux (Kernel 4.18.12-arch1-1-ARCH)
- compton (but issue is also there without compton)

This comment has been minimized.

i3bot commented Oct 15, 2018

I don’t see a link to Did you follow (In case you actually provided a link to a logfile, please ignore me.)


This comment has been minimized.


orestisf1993 commented Oct 17, 2018

2 problems: first one is easy, we need to request ButtonRelease events for windows:


Line 312 in 02284ac

xcb_grab_button(conn, false, window, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC,

Second one is complicated. Apparently, we never get the ButtonRelease event if we use XCB_ALLOW_REPLAY_POINTER in


Line 324 in 02284ac

xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
awesomewm also has this problem: awesomeWM/awesome#275 (@psychon). We can't always use XCB_ALLOW_ASYNC_POINTER because it "eats" the event.

What we could do, if we can't find a solution with AllowEvents, is similar to what we do with key grabs: specify button modifiers when grabbing and don't replay events. Buttons 1,2,3 are an exception since we always grab them for all windows: if there isn't a ButtonPress or ButtonRelease binding configured for one of these we should replay the event if we don't handle it elsewhere in route_click.

Or we could just check if we have a pending B_UPON_KEYRELEASE_IGNORE_MODS (applies to buttons as well) and if we do, use XCB_ALLOW_ASYNC_POINTER:

diff --git a/src/click.c b/src/click.c
index 1218a4c2..3f254d91 100644
--- a/src/click.c
+++ b/src/click.c
@@ -194,6 +194,15 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
             return 0;
+        } else if (event->response_type == XCB_BUTTON_PRESS) {
+            Binding *bind;
+            TAILQ_FOREACH(bind, bindings, bindings) {
+                if (bind->input_type == B_MOUSE && bind->release == B_UPON_KEYRELEASE_IGNORE_MODS) {
+                    xcb_allow_events(conn, XCB_ALLOW_ASYNC_POINTER, event->time);
+                    xcb_flush(conn);
+                    return 0;
+                }
+            }
diff --git a/src/xcb.c b/src/xcb.c
index bdfb08bc..5d349271 100644
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -309,7 +309,7 @@ release_grab:
 void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, int *buttons) {
     int i = 0;
     while (buttons[i] > 0) {
-        xcb_grab_button(conn, false, window, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC,
+        xcb_grab_button(conn, false, window, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_SYNC,
                         XCB_GRAB_MODE_ASYNC, root, XCB_NONE, buttons[i], XCB_BUTTON_MASK_ANY);

This comment has been minimized.


orestisf1993 commented Oct 17, 2018

I think this should also work and it's even simpler: when grabbing a button use the appropriate event mask according to Binding->release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment