i3bar: Realign tray clients on map/unmap notify
UnmapNotify events are interpreted by i3bar as an action taken by an application to hide its tray window. Likewise, MapNotify events are interpreted as an action taken by by an application to show its tray window. The actual cause of these events may be the application itself, or the result of some action taken by i3bar itself at the request of the application in the course of the XEmbed protocol. We respond by adjusting the size of the tray window and realigning any tray clients that remain. This will make room for the mapping window or close the gap left by the unmapping window when the bar is redrawn. fixes #1110
This commit is contained in:
parent
eca5e4598a
commit
80df764e55
|
@ -433,8 +433,9 @@ void handle_button(xcb_button_press_event_t *event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Configures the x coordinate of all trayclients. To be called after adding a
|
* Adjusts the size of the tray window and alignment of the tray clients by
|
||||||
* new tray client or removing an old one.
|
* configuring their respective x coordinates. To be called when mapping or
|
||||||
|
* unmapping a tray client window.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void configure_trayclients(void) {
|
static void configure_trayclients(void) {
|
||||||
|
@ -610,7 +611,6 @@ static void handle_client_message(xcb_client_message_event_t* event) {
|
||||||
}
|
}
|
||||||
trayclient *tc = smalloc(sizeof(trayclient));
|
trayclient *tc = smalloc(sizeof(trayclient));
|
||||||
tc->win = client;
|
tc->win = client;
|
||||||
tc->mapped = map_it;
|
|
||||||
tc->xe_version = xe_version;
|
tc->xe_version = xe_version;
|
||||||
TAILQ_INSERT_TAIL(output->trayclients, tc, tailq);
|
TAILQ_INSERT_TAIL(output->trayclients, tc, tailq);
|
||||||
|
|
||||||
|
@ -656,8 +656,36 @@ static void handle_destroy_notify(xcb_destroy_notify_event_t* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handles UnmapNotify events. These events happen when a tray window unmaps
|
* Handles MapNotify events. These events happen when a tray client shows its
|
||||||
* itself. We then update our data structure
|
* window. We respond by realigning the tray clients.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void handle_map_notify(xcb_map_notify_event_t* event) {
|
||||||
|
DLOG("MapNotify for window = %08x, event = %08x\n", event->window, event->event);
|
||||||
|
|
||||||
|
i3_output *walk;
|
||||||
|
SLIST_FOREACH(walk, outputs, slist) {
|
||||||
|
if (!walk->active)
|
||||||
|
continue;
|
||||||
|
DLOG("checking output %s\n", walk->name);
|
||||||
|
trayclient *trayclient;
|
||||||
|
TAILQ_FOREACH(trayclient, walk->trayclients, tailq) {
|
||||||
|
if (trayclient->win != event->window)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DLOG("Tray client mapped (window ID %08x). Adjusting tray.\n", event->window);
|
||||||
|
trayclient->mapped = true;
|
||||||
|
|
||||||
|
/* Trigger an update, we now have more space for the statusline */
|
||||||
|
configure_trayclients();
|
||||||
|
draw_bars(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Handles UnmapNotify events. These events happen when a tray client hides its
|
||||||
|
* window. We respond by realigning the tray clients.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void handle_unmap_notify(xcb_unmap_notify_event_t* event) {
|
static void handle_unmap_notify(xcb_unmap_notify_event_t* event) {
|
||||||
|
@ -673,8 +701,8 @@ static void handle_unmap_notify(xcb_unmap_notify_event_t* event) {
|
||||||
if (trayclient->win != event->window)
|
if (trayclient->win != event->window)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DLOG("Removing tray client with window ID %08x\n", event->window);
|
DLOG("Tray client unmapped (window ID %08x). Adjusting tray.\n", event->window);
|
||||||
TAILQ_REMOVE(walk->trayclients, trayclient, tailq);
|
trayclient->mapped = false;
|
||||||
|
|
||||||
/* Trigger an update, we now have more space for the statusline */
|
/* Trigger an update, we now have more space for the statusline */
|
||||||
configure_trayclients();
|
configure_trayclients();
|
||||||
|
@ -741,15 +769,9 @@ static void handle_property_notify(xcb_property_notify_event_t *event) {
|
||||||
if (trayclient->mapped && !map_it) {
|
if (trayclient->mapped && !map_it) {
|
||||||
/* need to unmap the window */
|
/* need to unmap the window */
|
||||||
xcb_unmap_window(xcb_connection, trayclient->win);
|
xcb_unmap_window(xcb_connection, trayclient->win);
|
||||||
trayclient->mapped = map_it;
|
|
||||||
configure_trayclients();
|
|
||||||
draw_bars(false);
|
|
||||||
} else if (!trayclient->mapped && map_it) {
|
} else if (!trayclient->mapped && map_it) {
|
||||||
/* need to map the window */
|
/* need to map the window */
|
||||||
xcb_map_window(xcb_connection, trayclient->win);
|
xcb_map_window(xcb_connection, trayclient->win);
|
||||||
trayclient->mapped = map_it;
|
|
||||||
configure_trayclients();
|
|
||||||
draw_bars(false);
|
|
||||||
}
|
}
|
||||||
free(xembedr);
|
free(xembedr);
|
||||||
}
|
}
|
||||||
|
@ -836,9 +858,12 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
|
||||||
handle_destroy_notify((xcb_destroy_notify_event_t*) event);
|
handle_destroy_notify((xcb_destroy_notify_event_t*) event);
|
||||||
break;
|
break;
|
||||||
case XCB_UNMAP_NOTIFY:
|
case XCB_UNMAP_NOTIFY:
|
||||||
/* UnmapNotifies are received when a tray window unmaps itself */
|
/* UnmapNotify is received when a tray client hides its window. */
|
||||||
handle_unmap_notify((xcb_unmap_notify_event_t*) event);
|
handle_unmap_notify((xcb_unmap_notify_event_t*) event);
|
||||||
break;
|
break;
|
||||||
|
case XCB_MAP_NOTIFY:
|
||||||
|
handle_map_notify((xcb_map_notify_event_t*) event);
|
||||||
|
break;
|
||||||
case XCB_PROPERTY_NOTIFY:
|
case XCB_PROPERTY_NOTIFY:
|
||||||
/* PropertyNotify */
|
/* PropertyNotify */
|
||||||
handle_property_notify((xcb_property_notify_event_t*) event);
|
handle_property_notify((xcb_property_notify_event_t*) event);
|
||||||
|
|
Loading…
Reference in New Issue