From: Ingo Bürk Date: Tue, 11 Oct 2016 18:46:25 +0000 (+0200) Subject: Handle ResizeRequests for tray clients. (#2495) X-Git-Tag: 4.13~19 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;ds=sidebyside;h=e82e26a24d22e2f92cd90d9547c213493e94ea63;p=i3%2Fi3 Handle ResizeRequests for tray clients. (#2495) 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 --- diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index d44da458..32187445 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -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);