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
This commit is contained in:
parent
3cba06f7b9
commit
e82e26a24d
|
@ -685,15 +685,17 @@ static void handle_client_message(xcb_client_message_event_t *event) {
|
||||||
if (op == SYSTEM_TRAY_REQUEST_DOCK) {
|
if (op == SYSTEM_TRAY_REQUEST_DOCK) {
|
||||||
xcb_window_t client = event->data.data32[2];
|
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;
|
mask = XCB_CW_EVENT_MASK;
|
||||||
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
||||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
/* Needed to get the most recent value of XEMBED_MAPPED. */
|
||||||
xcb_change_window_attributes(xcb_connection,
|
values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
client,
|
/* Needed for UnmapNotify events. */
|
||||||
mask,
|
values[0] |= XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
values);
|
/* 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
|
/* Request the _XEMBED_INFO property. The XEMBED specification
|
||||||
* (which is referred by the tray specification) says this *has* to
|
* (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
|
* If a tray client attempts to change its size we deny the request and respond
|
||||||
* ConfigureNotify with its actual size.
|
* by telling it its actual size.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void handle_configure_request(xcb_configure_request_event_t *event) {
|
static void handle_configuration_change(xcb_window_t window) {
|
||||||
DLOG("ConfigureRequest for window = %08x\n", event->window);
|
|
||||||
|
|
||||||
trayclient *trayclient;
|
trayclient *trayclient;
|
||||||
i3_output *output;
|
i3_output *output;
|
||||||
SLIST_FOREACH(output, outputs, slist) {
|
SLIST_FOREACH(output, outputs, slist) {
|
||||||
|
@ -1023,7 +1023,7 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
continue;
|
continue;
|
||||||
clients++;
|
clients++;
|
||||||
|
|
||||||
if (trayclient->win != event->window)
|
if (trayclient->win != window)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xcb_rectangle_t rect;
|
xcb_rectangle_t rect;
|
||||||
|
@ -1033,7 +1033,7 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
rect.height = icon_size;
|
rect.height = icon_size;
|
||||||
|
|
||||||
DLOG("This is a tray window. x = %d\n", rect.x);
|
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;
|
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");
|
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
|
* This function is called immediately before the main loop locks. We flush xcb
|
||||||
* then (and only then)
|
* 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:
|
case XCB_CONFIGURE_REQUEST:
|
||||||
/* ConfigureRequest, sent by a tray child */
|
/* ConfigureRequest, sent by a tray child */
|
||||||
handle_configure_request((xcb_configure_request_event_t *)event);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
free(event);
|
free(event);
|
||||||
|
|
Loading…
Reference in New Issue