diff --git a/common/xembed.c b/common/xembed.c index bb70ab1f..3f4c8673 100644 --- a/common/xembed.c +++ b/common/xembed.c @@ -24,6 +24,9 @@ #include "common/util.h" #include "common/atoms.h" +/* I should really include the correct header instead... */ +void luaA_systray_invalidate(void); + /** Send an XEMBED message to a window. * \param connection Connection to the X server. * \param towin Destination window @@ -141,6 +144,7 @@ xembed_property_update(xcb_connection_t *connection, xembed_window_t *emwin, xembed_window_deactivate(connection, emwin->win); xembed_focus_out(connection, emwin->win); } + luaA_systray_invalidate(); } } diff --git a/event.c b/event.c index 6e2ea836..c4e2ea3d 100644 --- a/event.c +++ b/event.c @@ -711,6 +711,7 @@ static void event_handle_maprequest(xcb_map_request_event_t *ev) { client_t *c; + xembed_window_t *em; xcb_get_window_attributes_cookie_t wa_c; xcb_get_window_attributes_reply_t *wa_r; xcb_get_geometry_cookie_t geom_c; @@ -724,10 +725,17 @@ event_handle_maprequest(xcb_map_request_event_t *ev) if(wa_r->override_redirect) goto bailout; - if(xembed_getbywin(&globalconf.embedded, ev->window)) + if((em = xembed_getbywin(&globalconf.embedded, ev->window))) { xcb_map_window(globalconf.connection, ev->window); xembed_window_activate(globalconf.connection, ev->window); + /* The correct way to set this is via the _XEMBED_INFO property. Neither + * of the XEMBED not the systray spec talk about mapping windows. + * Apparently, Qt doesn't care and does not set an _XEMBED_INFO + * property. Let's simulate the XEMBED_MAPPED bit. + */ + em->info.flags |= XEMBED_MAPPED; + luaA_systray_invalidate(); } else if((c = client_getbywin(ev->window))) { diff --git a/systray.c b/systray.c index b4e66acd..f0d7369d 100644 --- a/systray.c +++ b/systray.c @@ -247,6 +247,16 @@ xembed_process_client_message(xcb_client_message_event_t *ev) return 0; } +static int +systray_num_visible_entries(void) +{ + int result = 0; + foreach(em, globalconf.embedded) + if (em->info.flags & XEMBED_MAPPED) + result++; + return result; +} + /** Inform lua that the systray needs to be updated. */ void @@ -256,7 +266,7 @@ luaA_systray_invalidate(void) signal_object_emit(L, &global_signals, "systray::update", 0); /* Unmap now if the systray became empty */ - if(globalconf.embedded.len == 0) + if(systray_num_visible_entries() == 0) xcb_unmap_window(globalconf.connection, globalconf.systray.window); } @@ -267,11 +277,12 @@ systray_update(int base_size, bool horizontal, bool reverse, int spacing, bool f return; /* Give the systray window the correct size */ + int num_entries = systray_num_visible_entries(); uint32_t config_vals[4] = { base_size, base_size, 0, 0 }; if(horizontal) - config_vals[0] = base_size * globalconf.embedded.len + spacing * (globalconf.embedded.len - 1); + config_vals[0] = base_size * num_entries + spacing * (num_entries - 1); else - config_vals[1] = base_size * globalconf.embedded.len + spacing * (globalconf.embedded.len - 1); + config_vals[1] = base_size * num_entries + spacing * (num_entries - 1); xcb_configure_window(globalconf.connection, globalconf.systray.window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, @@ -289,6 +300,12 @@ systray_update(int base_size, bool horizontal, bool reverse, int spacing, bool f else em = &globalconf.embedded.tab[i]; + if (!(em->info.flags & XEMBED_MAPPED)) + { + xcb_unmap_window(globalconf.connection, em->win); + continue; + } + xcb_configure_window(globalconf.connection, em->win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, config_vals); @@ -362,7 +379,7 @@ luaA_systray(lua_State *L) globalconf.systray.parent = w; - if(globalconf.embedded.len != 0) + if(systray_num_visible_entries() != 0) { systray_update(base_size, horiz, revers, spacing, force_redraw); xcb_map_window(globalconf.connection, @@ -370,7 +387,7 @@ luaA_systray(lua_State *L) } } - lua_pushinteger(L, globalconf.embedded.len); + lua_pushinteger(L, systray_num_visible_entries()); luaA_object_push(L, globalconf.systray.parent); return 2; }