]> git.sur5r.net Git - i3/i3/commitdiff
Handle ResizeRequests for tray clients. (#2495)
authorIngo Bürk <admin@airblader.de>
Tue, 11 Oct 2016 18:46:25 +0000 (20:46 +0200)
committerMichael Stapelberg <stapelberg@users.noreply.github.com>
Tue, 11 Oct 2016 18:46:25 +0000 (11:46 -0700)
Some tray clients such as VLC use override_redirect on their tray window. As per
specification this means i3bar won't receive a ConfigureRequest, but instead a
ResizeRequest will be triggered. If not selected, the X server will simply confirm
the request which leads to a broken tray window size.

This commit selects and handles the event just like a configure request is handled.

fixes #2494

i3bar/src/xcb.c

index d44da4582f5f47539cee32ed7ee1883a7e9e8c54..321874459579cbb7dff3d8ff871a9d40b7119d74 100644 (file)
@@ -685,15 +685,17 @@ static void handle_client_message(xcb_client_message_event_t *event) {
         if (op == SYSTEM_TRAY_REQUEST_DOCK) {
             xcb_window_t client = event->data.data32[2];
 
-            /* Listen for PropertyNotify events to get the most recent value of
-             * the XEMBED_MAPPED atom, also listen for UnmapNotify events */
             mask = XCB_CW_EVENT_MASK;
-            values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
-                        XCB_EVENT_MASK_STRUCTURE_NOTIFY;
-            xcb_change_window_attributes(xcb_connection,
-                                         client,
-                                         mask,
-                                         values);
+
+            /* Needed to get the most recent value of XEMBED_MAPPED. */
+            values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
+            /* Needed for UnmapNotify events. */
+            values[0] |= XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+            /* Needed because some tray applications (e.g., VLC) use
+             * override_redirect which causes no ConfigureRequest to be sent. */
+            values[0] |= XCB_EVENT_MASK_RESIZE_REDIRECT;
+
+            xcb_change_window_attributes(xcb_connection, client, mask, values);
 
             /* Request the _XEMBED_INFO property. The XEMBED specification
              * (which is referred by the tray specification) says this *has* to
@@ -1004,13 +1006,11 @@ static void handle_property_notify(xcb_property_notify_event_t *event) {
 }
 
 /*
- * Handle ConfigureRequests by denying them and sending the client a
- * ConfigureNotify with its actual size.
+ * If a tray client attempts to change its size we deny the request and respond
+ * by telling it its actual size.
  *
  */
-static void handle_configure_request(xcb_configure_request_event_t *event) {
-    DLOG("ConfigureRequest for window = %08x\n", event->window);
-
+static void handle_configuration_change(xcb_window_t window) {
     trayclient *trayclient;
     i3_output *output;
     SLIST_FOREACH(output, outputs, slist) {
@@ -1023,7 +1023,7 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
                 continue;
             clients++;
 
-            if (trayclient->win != event->window)
+            if (trayclient->win != window)
                 continue;
 
             xcb_rectangle_t rect;
@@ -1033,7 +1033,7 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
             rect.height = icon_size;
 
             DLOG("This is a tray window. x = %d\n", rect.x);
-            fake_configure_notify(xcb_connection, rect, event->window, 0);
+            fake_configure_notify(xcb_connection, rect, window, 0);
             return;
         }
     }
@@ -1041,6 +1041,16 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
     DLOG("WARNING: Could not find corresponding tray window.\n");
 }
 
+static void handle_configure_request(xcb_configure_request_event_t *event) {
+    DLOG("ConfigureRequest for window = %08x\n", event->window);
+    handle_configuration_change(event->window);
+}
+
+static void handle_resize_request(xcb_resize_request_event_t *event) {
+    DLOG("ResizeRequest for window = %08x\n", event->window);
+    handle_configuration_change(event->window);
+}
+
 /*
  * This function is called immediately before the main loop locks. We flush xcb
  * then (and only then)
@@ -1166,6 +1176,9 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
             case XCB_CONFIGURE_REQUEST:
                 /* ConfigureRequest, sent by a tray child */
                 handle_configure_request((xcb_configure_request_event_t *)event);
+            case XCB_RESIZE_REQUEST:
+                /* ResizeRequest sent by a tray child using override_redirect. */
+                handle_resize_request((xcb_resize_request_event_t *)event);
                 break;
         }
         free(event);