Properly support the XEMBED_MAPPED bit

The XEmbed protocol defines a special property that defines if the embedded
window wants to be visible or not. Up to now, awesome always ignored this entry
and instead behaved as if the bit was set. This commit makes it properly respect
the bit.

Testing done: None. No idea how. Apparently nothing really uses this bit,
because we didn't get bug reports about it yet.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-05-14 14:30:22 +02:00
parent e801df1ee3
commit ec076ca4bd
3 changed files with 35 additions and 6 deletions

View File

@ -24,6 +24,9 @@
#include "common/util.h" #include "common/util.h"
#include "common/atoms.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. /** Send an XEMBED message to a window.
* \param connection Connection to the X server. * \param connection Connection to the X server.
* \param towin Destination window * \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_window_deactivate(connection, emwin->win);
xembed_focus_out(connection, emwin->win); xembed_focus_out(connection, emwin->win);
} }
luaA_systray_invalidate();
} }
} }

10
event.c
View File

@ -711,6 +711,7 @@ static void
event_handle_maprequest(xcb_map_request_event_t *ev) event_handle_maprequest(xcb_map_request_event_t *ev)
{ {
client_t *c; client_t *c;
xembed_window_t *em;
xcb_get_window_attributes_cookie_t wa_c; xcb_get_window_attributes_cookie_t wa_c;
xcb_get_window_attributes_reply_t *wa_r; xcb_get_window_attributes_reply_t *wa_r;
xcb_get_geometry_cookie_t geom_c; 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) if(wa_r->override_redirect)
goto bailout; goto bailout;
if(xembed_getbywin(&globalconf.embedded, ev->window)) if((em = xembed_getbywin(&globalconf.embedded, ev->window)))
{ {
xcb_map_window(globalconf.connection, ev->window); xcb_map_window(globalconf.connection, ev->window);
xembed_window_activate(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))) else if((c = client_getbywin(ev->window)))
{ {

View File

@ -247,6 +247,16 @@ xembed_process_client_message(xcb_client_message_event_t *ev)
return 0; 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. /** Inform lua that the systray needs to be updated.
*/ */
void void
@ -256,7 +266,7 @@ luaA_systray_invalidate(void)
signal_object_emit(L, &global_signals, "systray::update", 0); signal_object_emit(L, &global_signals, "systray::update", 0);
/* Unmap now if the systray became empty */ /* 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); 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; return;
/* Give the systray window the correct size */ /* 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 }; uint32_t config_vals[4] = { base_size, base_size, 0, 0 };
if(horizontal) 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 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, xcb_configure_window(globalconf.connection,
globalconf.systray.window, globalconf.systray.window,
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, 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 else
em = &globalconf.embedded.tab[i]; 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_configure_window(globalconf.connection, em->win,
XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
config_vals); config_vals);
@ -362,7 +379,7 @@ luaA_systray(lua_State *L)
globalconf.systray.parent = w; globalconf.systray.parent = w;
if(globalconf.embedded.len != 0) if(systray_num_visible_entries() != 0)
{ {
systray_update(base_size, horiz, revers, spacing, force_redraw); systray_update(base_size, horiz, revers, spacing, force_redraw);
xcb_map_window(globalconf.connection, 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); luaA_object_push(L, globalconf.systray.parent);
return 2; return 2;
} }