Handle unsetting of .transient_for

When a window has a WM_TRANSIENT_FOR property that is later unset,
awesome would still keep c.transient_for pointing to the previous
"parent client". This commit fixes that.

First, property_update_wm_transient_for() is fixed so that it unsets
c->transient_for_window if the WM_TRANSIENT_FOR property is deleted.
Additionally, this then calls client_find_transient_for() to update the
c->transient_for pointer.

Secondly (and a bit unrelated), this changes client_find_transient_for()
so that it always sets c->transient_for. Previously, if updating this
property would introduce a cycle in the transient_for relation, it would
just leave c->transient_for with its old value. After this change, it
gets explicitly set to NULL instead.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2018-08-10 16:39:46 +02:00
parent 3aefce7ccb
commit 297003126d
2 changed files with 17 additions and 9 deletions

View File

@ -983,7 +983,9 @@ client_find_transient_for(client_t *c)
{
int counter;
client_t *tc, *tmp;
lua_State *L = globalconf_get_lua_State();
/* This might return NULL, in which case we unset transient_for */
tmp = tc = client_getbywin(c->transient_for_window);
/* Verify that there are no loops in the transient_for relation after we are done */
@ -994,15 +996,17 @@ client_find_transient_for(client_t *c)
counter = globalconf.stack.len+1;
tmp = tmp->transient_for;
}
if (counter <= globalconf.stack.len)
if (counter > globalconf.stack.len)
{
lua_State *L = globalconf_get_lua_State();
/* There was a loop, so unset .transient_for */
tc = NULL;
}
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)

View File

@ -109,7 +109,11 @@ property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie)
if(!xcb_icccm_get_wm_transient_for_reply(globalconf.connection,
cookie,
&trans, NULL))
{
c->transient_for_window = XCB_NONE;
client_find_transient_for(c);
return;
}
c->transient_for_window = trans;