sway

i3-compatible Wayland compositor
git clone https://git.awy.one/sway
Log | Files | Refs | README | LICENSE

commit ed771a6a6e147d667c3791f897ad62e307b260fe
parent 5b8257b88f703f48466f3b917f1ceaee7c457355
Author: Ryan Dwyer <ryandwyer1@gmail.com>
Date:   Sat, 20 Oct 2018 12:34:39 +1000

Fix crash when view unmaps while no outputs connected

When a view unmaps, we call workspace_consider_destroy. This function
assumed the workspace would always have an output, but this is not the
case when hotplugged down to zero. The function now handles this and
allows itself to be destroyed when there is no output.

This means that workspace_begin_destroy must remove the workspace from
the root->saved_workspaces list to avoid an eventual dangling pointer,
so it does that now.

Lastly, when an output is plugged in again and it has to create a new
initial workspace for it, we must emit the workspace::init IPC event
otherwise swaybar shows no workspaces at all. I guess when you start
sway, swaybar is started after the workspace has been created which is
why this hasn't been needed earlier.

Diffstat:
Msway/tree/output.c | 1+
Msway/tree/workspace.c | 14+++++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/sway/tree/output.c b/sway/tree/output.c @@ -89,6 +89,7 @@ void output_enable(struct sway_output *output, struct output_config *oc) { } } free(ws_name); + ipc_event_workspace(NULL, ws, "init"); } size_t len = sizeof(output->layers) / sizeof(output->layers[0]); diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c @@ -119,6 +119,11 @@ void workspace_begin_destroy(struct sway_workspace *workspace) { if (workspace->output) { workspace_detach(workspace); + } else { + int index = list_find(root->saved_workspaces, workspace); + if (index != -1) { + list_del(root->saved_workspaces, index); + } } workspace->node.destroying = true; @@ -126,10 +131,13 @@ void workspace_begin_destroy(struct sway_workspace *workspace) { } void workspace_consider_destroy(struct sway_workspace *ws) { - if (ws->tiling->length == 0 && ws->floating->length == 0 - && output_get_active_workspace(ws->output) != ws) { - workspace_begin_destroy(ws); + if (ws->tiling->length || ws->floating->length) { + return; + } + if (ws->output && output_get_active_workspace(ws->output) == ws) { + return; } + workspace_begin_destroy(ws); } char *prev_workspace_name = NULL;