diff --git a/sway/desktop/output.c b/sway/desktop/output.c index aec1d0a6b..e6fe2ee4d 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -422,13 +422,6 @@ void force_modeset(void) { } static void begin_destroy(struct sway_output *output) { - if (output->enabled) { - output_disable(output); - } - - output_begin_destroy(output); - - wl_list_remove(&output->link); wl_list_remove(&output->layout_destroy.link); wl_list_remove(&output->destroy.link); @@ -436,8 +429,17 @@ static void begin_destroy(struct sway_output *output) { wl_list_remove(&output->frame.link); wl_list_remove(&output->request_state.link); + // Remove the scene_output first to ensure that the scene does not emit + // events for this output. wlr_scene_output_destroy(output->scene_output); output->scene_output = NULL; + + if (output->enabled) { + output_disable(output); + } + output_begin_destroy(output); + wl_list_remove(&output->link); + output->wlr_output->data = NULL; output->wlr_output = NULL; diff --git a/sway/tree/output.c b/sway/tree/output.c index 65d9e3e71..bc3806298 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -205,11 +205,8 @@ static void output_evacuate(struct sway_output *output) { return; } struct sway_output *fallback_output = NULL; - if (root->outputs->length > 1) { + if (root->outputs->length > 0) { fallback_output = root->outputs->items[0]; - if (fallback_output == output) { - fallback_output = root->outputs->items[1]; - } } while (output->workspaces->length) { @@ -289,11 +286,13 @@ void output_disable(struct sway_output *output) { sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name); wl_signal_emit_mutable(&output->events.disable, output); - output_evacuate(output); - + // Remove the output now to avoid interacting with it during e.g., + // transactions, as the output might be physically removed with the scene + // output destroyed. list_del(root->outputs, index); - output->enabled = false; + + output_evacuate(output); } void output_begin_destroy(struct sway_output *output) {