]> git.sur5r.net Git - i3/i3/blobdiff - i3bar/src/xcb.c
i3bar: make modifier behave like floating_modifier
[i3/i3] / i3bar / src / xcb.c
index 77822544e72e5df3de2a0cc532850f965c7b6cfb..7bfeb12e90dd7d8cd20e31e0a8e6accfba0fb745 100644 (file)
@@ -79,7 +79,7 @@ int bar_height;
 
 /* These are only relevant for XKB, which we only need for grabbing modifiers */
 int xkb_base;
-int mod_pressed = 0;
+bool mod_pressed = 0;
 
 /* Event watchers, to interact with the user */
 ev_prepare *xcb_prep;
@@ -523,7 +523,8 @@ void handle_button(xcb_button_press_event_t *event) {
                 block_x += render->width + render->x_offset + render->x_append + get_sep_offset(block) + sep_offset_remainder;
 
                 if (statusline_x <= block_x && statusline_x >= last_block_x) {
-                    send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y);
+                    send_block_clicked(event->detail, block->name, block->instance,
+                                       event->root_x, event->root_y, statusline_x - last_block_x, event->event_y, block_x - last_block_x, bar_height);
                     return;
                 }
 
@@ -693,21 +694,12 @@ static void handle_client_message(xcb_client_message_event_t *event) {
     if (event->type == atoms[I3_SYNC]) {
         xcb_window_t window = event->data.data32[0];
         uint32_t rnd = event->data.data32[1];
-        DLOG("[i3 sync protocol] Forwarding random value %d, X11 window 0x%08x to i3\n", rnd, window);
-
-        void *reply = scalloc(32, 1);
-        xcb_client_message_event_t *ev = reply;
-
-        ev->response_type = XCB_CLIENT_MESSAGE;
-        ev->window = window;
-        ev->type = atoms[I3_SYNC];
-        ev->format = 32;
-        ev->data.data32[0] = window;
-        ev->data.data32[1] = rnd;
-
-        xcb_send_event(conn, false, xcb_root, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)ev);
-        xcb_flush(conn);
-        free(reply);
+        /* Forward the request to i3 via the IPC interface so that all pending
+         * IPC messages are guaranteed to be handled. */
+        char *payload = NULL;
+        sasprintf(&payload, "{\"rnd\":%d, \"window\":%d}", rnd, window);
+        i3_send_msg(I3_IPC_MESSAGE_TYPE_SYNC, payload);
+        free(payload);
     } else if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] &&
                event->format == 32) {
         DLOG("_NET_SYSTEM_TRAY_OPCODE received\n");
@@ -1116,49 +1108,15 @@ void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
             DLOG("received an xkb event\n");
 
             xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
+            const uint32_t mod = (config.modifier & 0xFFFF);
+            mod_pressed = (mod != 0 && (state->mods & mod) == mod);
             if (state->xkbType == XCB_XKB_STATE_NOTIFY && config.modifier != XCB_NONE) {
-                int modstate = state->mods & config.modifier;
-
-#define DLOGMOD(modmask, status)                        \
-    do {                                                \
-        switch (modmask) {                              \
-            case ShiftMask:                             \
-                DLOG("ShiftMask got " #status "!\n");   \
-                break;                                  \
-            case ControlMask:                           \
-                DLOG("ControlMask got " #status "!\n"); \
-                break;                                  \
-            case Mod1Mask:                              \
-                DLOG("Mod1Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod2Mask:                              \
-                DLOG("Mod2Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod3Mask:                              \
-                DLOG("Mod3Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod4Mask:                              \
-                DLOG("Mod4Mask got " #status "!\n");    \
-                break;                                  \
-            case Mod5Mask:                              \
-                DLOG("Mod5Mask got " #status "!\n");    \
-                break;                                  \
-        }                                               \
-    } while (0)
-
-                if (modstate != mod_pressed) {
-                    if (modstate == 0) {
-                        DLOGMOD(config.modifier, released);
-                        if (!activated_mode)
-                            hide_bars();
-                    } else {
-                        DLOGMOD(config.modifier, pressed);
-                        activated_mode = false;
-                        unhide_bars();
-                    }
-                    mod_pressed = modstate;
+                if (mod_pressed) {
+                    activated_mode = false;
+                    unhide_bars();
+                } else if (!activated_mode) {
+                    hide_bars();
                 }
-#undef DLOGMOD
             }
 
             free(event);