From ed66fda1f1d390db18383810c6f91e5aec6ebf16 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 4 Oct 2013 14:31:48 +0200 Subject: [PATCH] client: Ignore transient_for causing loops (FS#1124) Lots of code assumes that it can recursively follow a client's transient_for field until it reached an end without a transient_for client. Instead of fixing all those places to properly handle loops, this patch just makes us ignore WM_TRANSIENT_FOR if the property causes a loop. This means that it can be a little random which WM_TRANSIENT_FOR property is ignored, because it will always be the one that happens to complete the cycle. I don't think that this is bad, because there shouldn't be any loops in the first place. Lots-of-kudos-to: David Mohr Signed-off-by: Uli Schlachter --- property.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/property.c b/property.c index 534bd085..ea239dfa 100644 --- a/property.c +++ b/property.c @@ -105,16 +105,26 @@ void property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie) { 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); + luaA_object_push(globalconf.L, c); client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG); client_set_above(globalconf.L, -1, false); - client_set_transient_for(globalconf.L, -1, client_getbywin(trans)); + + /* Verify that there are no loops in the transient_for relation */ + for(counter = 0; tmp != NULL && counter <= globalconf.stack.len; counter++) + tmp = tmp->transient_for; + if (counter <= globalconf.stack.len) + client_set_transient_for(globalconf.L, -1, tc); + lua_pop(globalconf.L, 1); }