Fix segfaults on output destruction

This fixes two causes of segfaulting when an output is destroyed.

The first occurred when an output was never enabled. The issue was that
the destroy signal was never initialized so when it was emitted, sway
segfaulted. This was fixed by moving the initialization into
`output_create` since all outputs, regardless of whether they have ever
been enabled, will be destroyed at some point.

The second occurred when the cursor was on an output that was being
destroyed. The sway output would have already been removed, but if there
are other outputs, a cursor rebase would still occur. Since the
wlr_output still existed and the sway output was destroyed, the cursor
could be over nothing, resulting in a segfault when trying to get the
sway output, which was destroyed.
This commit is contained in:
Brian Ashworth 2019-01-10 03:07:36 -05:00
parent 14cab78612
commit 8fd3f32c79
2 changed files with 5 additions and 1 deletions

View File

@ -85,6 +85,10 @@ static struct sway_node *node_at_coords(
return NULL;
}
struct sway_output *output = wlr_output->data;
if (!output) {
// output is being destroyed
return NULL;
}
double ox = lx, oy = ly;
wlr_output_layout_output_coords(root->output_layout, wlr_output, &ox, &oy);

View File

@ -58,6 +58,7 @@ struct sway_output *output_create(struct wlr_output *wlr_output) {
wlr_output->data = output;
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
wl_signal_init(&output->events.destroy);
wl_list_insert(&root->all_outputs, &output->link);
@ -76,7 +77,6 @@ void output_enable(struct sway_output *output, struct output_config *oc) {
for (size_t i = 0; i < len; ++i) {
wl_list_init(&output->layers[i]);
}
wl_signal_init(&output->events.destroy);
output->enabled = true;
list_add(root->outputs, output);