Stop a window parent cycle from hanging
a09d7a06b9807fd779aa1d91e556ea011ceb68b8
1 parent
8fcdc95a
swm.c
+5 -1
| 3081 | 3081 | } |
|
| 3082 | 3082 | ||
| 3083 | 3083 | /* Return the main client in a related client group. */ |
|
| 3084 | 3084 | client_t *client_main(client_t *c) { |
|
| 3085 | 3085 | client_t *p; |
|
| 3086 | + | int steps = MAX_CLIENTS; |
|
| 3086 | 3087 | ||
| 3087 | - | while (c && (p = client_get_parent(c)) && p != c) |
|
| 3088 | + | /* Windows can form a parent cycle: X11 clients may point WM_TRANSIENT_FOR |
|
| 3089 | + | * at each other, and nothing validates the chain. Take at most one step per |
|
| 3090 | + | * window so a cycle stops the walk instead of hanging the compositor. */ |
|
| 3091 | + | while (c && steps-- > 0 && (p = client_get_parent(c)) && p != c) |
|
| 3088 | 3092 | c = p; |
|
| 3089 | 3093 | return c; |
|
| 3090 | 3094 | } |
|
| 3091 | 3095 | ||
| 3092 | 3096 | /* Return whether a mapped modal XDG child blocks this direct parent. */ |