i3bar: send XEMBED_EMBEDDED_NOTIFY after reparenting/mapping tray clients

This commit is contained in:
Michael Stapelberg 2011-08-17 00:44:03 +02:00
parent 737cd10bdf
commit 893878cbcc
4 changed files with 31 additions and 4 deletions

View File

@ -18,6 +18,7 @@ TAILQ_HEAD(tc_head, trayclient);
struct trayclient { struct trayclient {
xcb_window_t win; /* The window ID of the tray client */ xcb_window_t win; /* The window ID of the tray client */
bool mapped; /* Whether this window is mapped */ bool mapped; /* Whether this window is mapped */
int xe_version; /* The XEMBED version supported by the client */
TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */ TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */
}; };

View File

@ -16,6 +16,7 @@
#define SYSTEM_TRAY_BEGIN_MESSAGE 1 #define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2 #define SYSTEM_TRAY_CANCEL_MESSAGE 2
#define XEMBED_MAPPED (1 << 0) #define XEMBED_MAPPED (1 << 0)
#define XEMBED_EMBEDDED_NOTIFY 0
struct xcb_color_strings_t { struct xcb_color_strings_t {
char *bar_fg; char *bar_fg;

View File

@ -9,4 +9,5 @@ ATOM_DO(_NET_SYSTEM_TRAY_VISUAL)
ATOM_DO(CARDINAL) ATOM_DO(CARDINAL)
ATOM_DO(_NET_SYSTEM_TRAY_OPCODE) ATOM_DO(_NET_SYSTEM_TRAY_OPCODE)
ATOM_DO(_XEMBED_INFO) ATOM_DO(_XEMBED_INFO)
ATOM_DO(_XEMBED)
#undef ATOM_DO #undef ATOM_DO

View File

@ -435,6 +435,7 @@ void handle_client_message(xcb_client_message_event_t* event) {
* (which is referred by the tray specification) says this *has* to * (which is referred by the tray specification) says this *has* to
* be set, but VLC does not set it */ * be set, but VLC does not set it */
bool map_it = true; bool map_it = true;
int xe_version = 1;
xcb_get_property_cookie_t xembedc; xcb_get_property_cookie_t xembedc;
xembedc = xcb_get_property_unchecked(xcb_connection, xembedc = xcb_get_property_unchecked(xcb_connection,
0, 0,
@ -453,6 +454,9 @@ void handle_client_message(xcb_client_message_event_t* event) {
DLOG("xembed version = %d\n", xembed[0]); DLOG("xembed version = %d\n", xembed[0]);
DLOG("xembed flags = %d\n", xembed[1]); DLOG("xembed flags = %d\n", xembed[1]);
map_it = ((xembed[1] & XEMBED_MAPPED) == XEMBED_MAPPED); map_it = ((xembed[1] & XEMBED_MAPPED) == XEMBED_MAPPED);
xe_version = xembed[0];
if (xe_version > 1)
xe_version = 1;
free(xembedr); free(xembedr);
} else { } else {
ELOG("Window %08x violates the XEMBED protocol, _XEMBED_INFO not set\n", client); ELOG("Window %08x violates the XEMBED protocol, _XEMBED_INFO not set\n", client);
@ -484,6 +488,24 @@ void handle_client_message(xcb_client_message_event_t* event) {
mask, mask,
values); values);
/* send the XEMBED_EMBEDDED_NOTIFY message */
void *event = calloc(32, 1);
xcb_client_message_event_t *ev = event;
ev->response_type = XCB_CLIENT_MESSAGE;
ev->window = client;
ev->type = atoms[_XEMBED];
ev->format = 32;
ev->data.data32[0] = XCB_CURRENT_TIME;
ev->data.data32[1] = atoms[XEMBED_EMBEDDED_NOTIFY];
ev->data.data32[2] = output->bar;
ev->data.data32[3] = xe_version;
xcb_send_event(xcb_connection,
0,
client,
XCB_EVENT_MASK_NO_EVENT,
(char*)ev);
free(event);
if (map_it) { if (map_it) {
DLOG("Mapping dock client\n"); DLOG("Mapping dock client\n");
xcb_map_window(xcb_connection, client); xcb_map_window(xcb_connection, client);
@ -493,6 +515,7 @@ void handle_client_message(xcb_client_message_event_t* event) {
trayclient *tc = malloc(sizeof(trayclient)); trayclient *tc = malloc(sizeof(trayclient));
tc->win = client; tc->win = client;
tc->mapped = map_it; tc->mapped = map_it;
tc->xe_version = xe_version;
TAILQ_INSERT_TAIL(output->trayclients, tc, tailq); 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
@ -533,12 +556,12 @@ static void handle_property_notify(xcb_property_notify_event_t *event) {
event->state == XCB_PROPERTY_NEW_VALUE) { event->state == XCB_PROPERTY_NEW_VALUE) {
DLOG("xembed_info updated\n"); DLOG("xembed_info updated\n");
trayclient *trayclient = NULL, *walk; trayclient *trayclient = NULL, *walk;
i3_output *output; i3_output *o_walk;
SLIST_FOREACH(output, outputs, slist) { SLIST_FOREACH(o_walk, outputs, slist) {
if (!output->active) if (!o_walk->active)
continue; continue;
TAILQ_FOREACH(walk, output->trayclients, tailq) { TAILQ_FOREACH(walk, o_walk->trayclients, tailq) {
if (walk->win != event->window) if (walk->win != event->window)
continue; continue;
trayclient = walk; trayclient = walk;
@ -907,6 +930,7 @@ void init_tray() {
xcb_root, xcb_root,
XCB_EVENT_MASK_STRUCTURE_NOTIFY, XCB_EVENT_MASK_STRUCTURE_NOTIFY,
(char*)ev); (char*)ev);
free(event);
} }
/* /*