From 63d076dc2abba0cab6fb78bb2e36088f0b4f9ae5 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 26 Oct 2018 19:15:12 +1000 Subject: [PATCH] Fix focus after a non-visible workspace's last container is destroyed The code being changed is responsible for updating the focus stack when a container is destroyed in a different part of the tree to where the real focus is. It's attempting to set focus_inactive to a sibling (or parent if no siblings) of the container that is being destroyed, then put our real focus back on the end of the focus stack. The problem occurs when the container being destroyed is in a different workspace. For example: * Have a focused view on workspace 1 * Have workspace 2 not visible with a single view that is unmapping * The first call to seat_set_raw_focus sets focus to workspace 2 because it's the parent * Prior to this patch, the second call to seat_set_raw_focus would set focus to the view on workspace 1 * Later, when using output_get_active_workspace, this function would return workspace 2 because it's the first workspace it finds in the focus stack. To fix this, workspace 1 must be placed on the focus stack between workspace 2 and the focused view. That's what this patch does. Lastly, it also uses seat_get_focus_inactive to choose the focus. This fixes a crash when a view unmaps while a non-container is focused (eg. swaylock), because focus is NULL. --- sway/input/seat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sway/input/seat.c b/sway/input/seat.c index 577619a7..9d4dc7af 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -185,7 +185,11 @@ static void handle_seat_node_destroy(struct wl_listener *listener, void *data) { seat_set_focus(seat, next_focus); } else { // Setting focus_inactive + focus = seat_get_focus_inactive(seat, &root->node); seat_set_raw_focus(seat, next_focus); + if (focus->type == N_CONTAINER) { + seat_set_raw_focus(seat, &focus->sway_container->workspace->node); + } seat_set_raw_focus(seat, focus); } }