diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-30 11:58:56 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-30 11:58:56 +1000 |
commit | 24bcb507ecf9b656fb9d5532dab9d1cac9c84a33 (patch) | |
tree | ddf2f811de08756472336e6ee09139db1746ee86 | |
parent | Merge pull request #2698 from ianyfan/hide-cursor (diff) | |
download | sway-24bcb507ecf9b656fb9d5532dab9d1cac9c84a33.tar.gz sway-24bcb507ecf9b656fb9d5532dab9d1cac9c84a33.tar.zst sway-24bcb507ecf9b656fb9d5532dab9d1cac9c84a33.zip |
Fix hotplugging down to zero outputs
When the last output is disconnected, output_disable is called like
usual and evacuates the output to the root->saved_workspaces list. It
then calls root_for_each_container to remove (untrack) the output from
each container's outputs list. However root_for_each_container did not
iterate the saved workspaces, so when the output gets freed the
containers would have a dangling pointer in their outputs list. Upon
reconnect, container_discover_outputs would attempt to use the dangling
pointer, causing a crash.
This makes root_for_each_container check the saved workspaces list,
which fixes the problem.
-rw-r--r-- | sway/tree/root.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sway/tree/root.c b/sway/tree/root.c index d6f67bd7..6748e9c9 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c | |||
@@ -273,6 +273,12 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data), | |||
273 | container_for_each_child(container, f, data); | 273 | container_for_each_child(container, f, data); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | |||
277 | // Saved workspaces | ||
278 | for (int i = 0; i < root->saved_workspaces->length; ++i) { | ||
279 | struct sway_workspace *ws = root->saved_workspaces->items[i]; | ||
280 | workspace_for_each_container(ws, f, data); | ||
281 | } | ||
276 | } | 282 | } |
277 | 283 | ||
278 | struct sway_output *root_find_output( | 284 | struct sway_output *root_find_output( |
@@ -320,6 +326,15 @@ struct sway_container *root_find_container( | |||
320 | } | 326 | } |
321 | } | 327 | } |
322 | } | 328 | } |
329 | |||
330 | // Saved workspaces | ||
331 | for (int i = 0; i < root->saved_workspaces->length; ++i) { | ||
332 | struct sway_workspace *ws = root->saved_workspaces->items[i]; | ||
333 | if ((result = workspace_find_container(ws, test, data))) { | ||
334 | return result; | ||
335 | } | ||
336 | } | ||
337 | |||
323 | return NULL; | 338 | return NULL; |
324 | } | 339 | } |
325 | 340 | ||