i3bar: Correctly handle removal of tray clients
This commit is contained in:
parent
6efa7a754d
commit
2046e4112f
@ -29,6 +29,7 @@ struct rect_t {
|
|||||||
#include "outputs.h"
|
#include "outputs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
|
#include "trayclients.h"
|
||||||
#include "xcb.h"
|
#include "xcb.h"
|
||||||
#include "ucs2_to_utf8.h"
|
#include "ucs2_to_utf8.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -46,9 +46,8 @@ struct i3_output {
|
|||||||
xcb_pixmap_t buffer; /* An extra pixmap for double-buffering */
|
xcb_pixmap_t buffer; /* An extra pixmap for double-buffering */
|
||||||
xcb_gcontext_t bargc; /* The graphical context of the bar */
|
xcb_gcontext_t bargc; /* The graphical context of the bar */
|
||||||
|
|
||||||
int traypx; /* Amount of pixels reserved for tray icons */
|
|
||||||
|
|
||||||
struct ws_head *workspaces; /* The workspaces on this output */
|
struct ws_head *workspaces; /* The workspaces on this output */
|
||||||
|
struct tc_head *trayclients; /* The tray clients on this output */
|
||||||
|
|
||||||
SLIST_ENTRY(i3_output) slist; /* Pointer for the SLIST-Macro */
|
SLIST_ENTRY(i3_output) slist; /* Pointer for the SLIST-Macro */
|
||||||
};
|
};
|
||||||
|
24
i3bar/include/trayclients.h
Normal file
24
i3bar/include/trayclients.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* i3bar - an xcb-based status- and ws-bar for i3
|
||||||
|
*
|
||||||
|
* © 2010-2011 Axel Wagner and contributors
|
||||||
|
*
|
||||||
|
* See file LICNSE for license information
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef TRAYCLIENT_H_
|
||||||
|
#define TRAYCLIENT_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
typedef struct trayclient trayclient;
|
||||||
|
|
||||||
|
TAILQ_HEAD(tc_head, trayclient);
|
||||||
|
|
||||||
|
struct trayclient {
|
||||||
|
xcb_window_t win; /* The window ID of the tray client */
|
||||||
|
|
||||||
|
TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -157,11 +157,13 @@ static int outputs_start_map_cb(void *params_) {
|
|||||||
new_output->ws = 0,
|
new_output->ws = 0,
|
||||||
memset(&new_output->rect, 0, sizeof(rect));
|
memset(&new_output->rect, 0, sizeof(rect));
|
||||||
new_output->bar = XCB_NONE;
|
new_output->bar = XCB_NONE;
|
||||||
new_output->traypx = 0;
|
|
||||||
|
|
||||||
new_output->workspaces = malloc(sizeof(struct ws_head));
|
new_output->workspaces = malloc(sizeof(struct ws_head));
|
||||||
TAILQ_INIT(new_output->workspaces);
|
TAILQ_INIT(new_output->workspaces);
|
||||||
|
|
||||||
|
new_output->trayclients = malloc(sizeof(struct tc_head));
|
||||||
|
TAILQ_INIT(new_output->trayclients);
|
||||||
|
|
||||||
params->outputs_walk = new_output;
|
params->outputs_walk = new_output;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -408,16 +408,32 @@ void handle_client_message(xcb_client_message_event_t* event) {
|
|||||||
client,
|
client,
|
||||||
output->bar,
|
output->bar,
|
||||||
output->rect.w - font_height - 2, /* TODO: why -2? */
|
output->rect.w - font_height - 2, /* TODO: why -2? */
|
||||||
0);
|
2);
|
||||||
|
/* We reconfigure the window to use a reasonable size. The systray
|
||||||
|
* specification explicitly says:
|
||||||
|
* Tray icons may be assigned any size by the system tray, and
|
||||||
|
* should do their best to cope with any size effectively
|
||||||
|
*/
|
||||||
uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
|
||||||
uint32_t values[] = { font_height, font_height };
|
uint32_t values[] = { font_height, font_height };
|
||||||
xcb_configure_window(xcb_connection,
|
xcb_configure_window(xcb_connection,
|
||||||
client,
|
client,
|
||||||
mask,
|
mask,
|
||||||
values);
|
values);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
xcb_map_window(xcb_connection, client);
|
xcb_map_window(xcb_connection, client);
|
||||||
/* XXX: We assume that icons are quadratic. Is that so? */
|
trayclient *tc = malloc(sizeof(trayclient));
|
||||||
output->traypx += font_height;
|
tc->win = client;
|
||||||
|
TAILQ_INSERT_TAIL(output->trayclients, tc, tailq);
|
||||||
|
|
||||||
/* Trigger an update to copy the statusline text to the appropriate
|
/* Trigger an update to copy the statusline text to the appropriate
|
||||||
* position */
|
* position */
|
||||||
@ -426,6 +442,29 @@ void handle_client_message(xcb_client_message_event_t* event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_unmap_notify(xcb_unmap_notify_event_t* event) {
|
||||||
|
DLOG("UnmapNotify 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("Removing tray client with window ID %08x\n", event->window);
|
||||||
|
TAILQ_REMOVE(walk->trayclients, trayclient, tailq);
|
||||||
|
|
||||||
|
/* Trigger an update, we now have more space for the statusline */
|
||||||
|
draw_bars();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
@ -461,6 +500,10 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
|
|||||||
* example system tray widgets talk to us directly via client messages. */
|
* example system tray widgets talk to us directly via client messages. */
|
||||||
handle_client_message((xcb_client_message_event_t*) event);
|
handle_client_message((xcb_client_message_event_t*) event);
|
||||||
break;
|
break;
|
||||||
|
case XCB_UNMAP_NOTIFY:
|
||||||
|
/* UnmapNotifies are received when a tray window unmaps itself */
|
||||||
|
handle_unmap_notify((xcb_unmap_notify_event_t*) event);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
FREE(event);
|
FREE(event);
|
||||||
}
|
}
|
||||||
@ -1053,7 +1096,14 @@ void draw_bars() {
|
|||||||
/* Luckily we already prepared a seperate pixmap containing the rendered
|
/* Luckily we already prepared a seperate pixmap containing the rendered
|
||||||
* statusline, we just have to copy the relevant parts to the relevant
|
* statusline, we just have to copy the relevant parts to the relevant
|
||||||
* position */
|
* position */
|
||||||
int traypx = outputs_walk->traypx;
|
trayclient *trayclient;
|
||||||
|
int traypx = 0;
|
||||||
|
TAILQ_FOREACH(trayclient, outputs_walk->trayclients, tailq) {
|
||||||
|
/* We assume the tray icons are quadratic (we use the font
|
||||||
|
* *height* as *width* of the icons) because we configured them
|
||||||
|
* like this. */
|
||||||
|
traypx += font_height;
|
||||||
|
}
|
||||||
/* Add 2px of padding if there are any tray icons */
|
/* Add 2px of padding if there are any tray icons */
|
||||||
if (traypx > 0)
|
if (traypx > 0)
|
||||||
traypx += 2;
|
traypx += 2;
|
||||||
@ -1063,7 +1113,7 @@ void draw_bars() {
|
|||||||
outputs_walk->bargc,
|
outputs_walk->bargc,
|
||||||
MAX(0, (int16_t)(statusline_width - outputs_walk->rect.w + 4)), 0,
|
MAX(0, (int16_t)(statusline_width - outputs_walk->rect.w + 4)), 0,
|
||||||
MAX(0, (int16_t)(outputs_walk->rect.w - statusline_width - traypx - 4)), 3,
|
MAX(0, (int16_t)(outputs_walk->rect.w - statusline_width - traypx - 4)), 3,
|
||||||
MIN(outputs_walk->rect.w - outputs_walk->traypx - 4, statusline_width), font_height);
|
MIN(outputs_walk->rect.w - traypx - 4, statusline_width), font_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.disable_ws) {
|
if (config.disable_ws) {
|
||||||
|
Loading…
Reference in New Issue
Block a user