Really ignore loops in transient_for (FS#1124)

The code in property_update_wm_transient_for() looked at the transient_for
relation before the new transient got set. However, the code is supposed to
check if we get a loop after introducing this new transient_for.

Thus, if we arrive back at the client that we started from, we can be sure that
there is a cycle. Signal this by setting the loop counter high enough to abort
the loop and make the rest of this function do nothing.

No idea how I missed this case before nor why I cannot reproduce this on debian,
but can reproduce it on Arch just fine.

Reported-By: Kasimir Knallkopf at http://article.gmane.org/gmane.comp.window-managers.awesome/10415
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2013-11-23 14:42:56 +01:00
parent 15f0881966
commit 389a54e356
1 changed files with 6 additions and 1 deletions

View File

@ -119,9 +119,14 @@ property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie)
client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG); client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG);
client_set_above(globalconf.L, -1, false); client_set_above(globalconf.L, -1, false);
/* Verify that there are no loops in the transient_for relation */ /* 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++) 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; tmp = tmp->transient_for;
}
if (counter <= globalconf.stack.len) if (counter <= globalconf.stack.len)
client_set_transient_for(globalconf.L, -1, tc); client_set_transient_for(globalconf.L, -1, tc);