From b09090fa7d2c8c278181c1b2c9429dcfec6a8b35 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Thu, 11 Oct 2018 12:06:17 +0300 Subject: [PATCH] Fix sticky focus when switching to workspace on different output See the testcase for the exact steps to reproduce the problem. --- src/workspace.c | 8 +++++++- testcases/t/285-sticky.t | 27 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/workspace.c b/src/workspace.c index 5f5c8d4f..6fe9a128 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -410,7 +410,6 @@ static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents */ void workspace_show(Con *workspace) { Con *current, *old = NULL; - Con *old_focus = focused; /* safe-guard against showing i3-internal workspaces like __i3_scratch */ if (con_is_internal(workspace)) @@ -433,6 +432,13 @@ void workspace_show(Con *workspace) { return; } + /* Used to correctly update focus when pushing sticky windows. Holds the + * previously focused container in the same output as workspace. For + * example, if a sticky window is focused and then we switch focus to a + * workspace in another output and then switch to a third workspace in the + * first output, the sticky window needs to be refocused. */ + Con *old_focus = old ? con_descend_focused(old) : NULL; + /* Remember currently focused workspace for switching back to it later with * the 'workspace back_and_forth' command. * NOTE: We have to duplicate the name as the original will be freed when diff --git a/testcases/t/285-sticky.t b/testcases/t/285-sticky.t index 927d3d74..8dfe9aea 100644 --- a/testcases/t/285-sticky.t +++ b/testcases/t/285-sticky.t @@ -16,7 +16,14 @@ # # Tests sticky windows. # Ticket: #1455 -use i3test; +use i3test i3_config => <{floating_nodes}}, 1, 'the sticky window jumps to the front'); kill_all_windows; +############################################################################### +# 7: Given a sticky floating container and a workspace on another output, when +# a new workspace assigned to the first output is focused, then the sticky +# container should jump to the new workspace and have input focus correctly. +############################################################################### +$ws = fresh_workspace(output => 0); +open_floating_window; +cmd 'sticky enabled'; +$focused = get_focused($ws); +$ws = fresh_workspace(output => 1); + +is(@{get_ws($ws)->{floating_nodes}}, 0, 'the sticky window didn\'t jump to a workspace on a different output'); +$ws = 'ws-on-0'; +cmd "workspace $ws"; +is(@{get_ws($ws)->{floating_nodes}}, 1, 'the sticky window moved to new workspace on first output'); +is(get_focused($ws), $focused, 'the sticky window has focus'); +kill_all_windows; + ############################################################################### done_testing; -- 2.39.5