diff --git a/objects/client.c b/objects/client.c index 5a61869a..53ffb22a 100644 --- a/objects/client.c +++ b/objects/client.c @@ -211,6 +211,32 @@ DO_CLIENT_SET_STRING_PROPERTY(role) DO_CLIENT_SET_STRING_PROPERTY(machine) #undef DO_CLIENT_SET_STRING_PROPERTY +void +client_find_transient_for(client_t *c) +{ + int counter; + client_t *tc, *tmp; + + tmp = tc = client_getbywin(c->transient_for_window); + + /* Verify that there are no loops in the transient_for relation after we are done */ + for(counter = 0; tmp != NULL && counter <= globalconf.stack.len; counter++) + { + if (tmp == c) + /* We arrived back at the client we started from, so there is a loop */ + counter = globalconf.stack.len+1; + tmp = tmp->transient_for; + } + if (counter <= globalconf.stack.len) + { + lua_State *L = globalconf_get_lua_State(); + + luaA_object_push(L, c); + client_set_transient_for(L, -1, tc); + lua_pop(L, 1); + } +} + void client_set_class_instance(lua_State *L, int cidx, const char *class, const char *instance) { @@ -634,6 +660,11 @@ HANDLE_GEOM(height) /* update all properties */ client_update_properties(L, -1, c); + /* check if this is a TRANSIENT_FOR of another client */ + foreach(oc, globalconf.clients) + if ((*oc)->transient_for_window == w) + client_find_transient_for(*oc); + /* Then check clients hints */ ewmh_client_check_hints(c); diff --git a/objects/client.h b/objects/client.h index 86a28c9c..f921646e 100644 --- a/objects/client.h +++ b/objects/client.h @@ -121,6 +121,8 @@ struct client_t uint32_t pid; /** Window it is transient for */ client_t *transient_for; + /** Value of WM_TRANSIENT_FOR */ + xcb_window_t transient_for_window; /** Titelbar information */ struct { /** The size of this bar. */ @@ -181,6 +183,7 @@ void client_restore_enterleave_events(void); void client_refresh_partial(client_t *, int16_t, int16_t, uint16_t, uint16_t); void client_class_setup(lua_State *); void client_send_configure(client_t *); +void client_find_transient_for(client_t *); drawable_t *client_get_drawable(client_t *, int, int); drawable_t *client_get_drawable_offset(client_t *, int *, int *); diff --git a/property.c b/property.c index 8069884c..d48747c1 100644 --- a/property.c +++ b/property.c @@ -105,32 +105,20 @@ property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie) { lua_State *L = globalconf_get_lua_State(); xcb_window_t trans; - int counter; - client_t *tc, *tmp; if(!xcb_icccm_get_wm_transient_for_reply(globalconf.connection, cookie, &trans, NULL)) return; - tmp = tc = client_getbywin(trans); + c->transient_for_window = trans; luaA_object_push(L, c); client_set_type(L, -1, WINDOW_TYPE_DIALOG); client_set_above(L, -1, false); - - /* Verify that there are no loops in the transient_for relation after we are done */ - for(counter = 0; tmp != NULL && counter <= globalconf.stack.len; counter++) - { - if (tmp == c) - /* We arrived back at the client we started from, so there is a loop */ - counter = globalconf.stack.len+1; - tmp = tmp->transient_for; - } - if (counter <= globalconf.stack.len) - client_set_transient_for(L, -1, tc); - lua_pop(L, 1); + + client_find_transient_for(c); } xcb_get_property_cookie_t