Browse Source

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 <david@mcbf.net>
Signed-off-by: Uli Schlachter <psychon@znc.in>
Uli Schlachter 6 years ago
parent
commit
ed66fda1f1
1 changed files with 11 additions and 1 deletions
  1. 11
    1
      property.c

+ 11
- 1
property.c View File

@@ -105,16 +105,26 @@ void
105 105
 property_update_wm_transient_for(client_t *c, xcb_get_property_cookie_t cookie)
106 106
 {
107 107
     xcb_window_t trans;
108
+    int counter;
109
+    client_t *tc, *tmp;
108 110
 
109 111
     if(!xcb_icccm_get_wm_transient_for_reply(globalconf.connection,
110 112
 					     cookie,
111 113
 					     &trans, NULL))
112 114
             return;
113 115
 
116
+    tmp = tc = client_getbywin(trans);
117
+
114 118
     luaA_object_push(globalconf.L, c);
115 119
     client_set_type(globalconf.L, -1, WINDOW_TYPE_DIALOG);
116 120
     client_set_above(globalconf.L, -1, false);
117
-    client_set_transient_for(globalconf.L, -1, client_getbywin(trans));
121
+
122
+    /* Verify that there are no loops in the transient_for relation */
123
+    for(counter = 0; tmp != NULL && counter <= globalconf.stack.len; counter++)
124
+        tmp = tmp->transient_for;
125
+    if (counter <= globalconf.stack.len)
126
+        client_set_transient_for(globalconf.L, -1, tc);
127
+
118 128
     lua_pop(globalconf.L, 1);
119 129
 }
120 130
 

Loading…
Cancel
Save