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.
This commit is contained in:
Ryan Dwyer 2018-09-30 11:58:56 +10:00
parent a53171669a
commit 24bcb507ec

View File

@ -273,6 +273,12 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data),
container_for_each_child(container, f, data); container_for_each_child(container, f, data);
} }
} }
// Saved workspaces
for (int i = 0; i < root->saved_workspaces->length; ++i) {
struct sway_workspace *ws = root->saved_workspaces->items[i];
workspace_for_each_container(ws, f, data);
}
} }
struct sway_output *root_find_output( struct sway_output *root_find_output(
@ -320,6 +326,15 @@ struct sway_container *root_find_container(
} }
} }
} }
// Saved workspaces
for (int i = 0; i < root->saved_workspaces->length; ++i) {
struct sway_workspace *ws = root->saved_workspaces->items[i];
if ((result = workspace_find_container(ws, test, data))) {
return result;
}
}
return NULL; return NULL;
} }