diff --git a/src/con.c b/src/con.c index 3861f046..d8c30dcf 100644 --- a/src/con.c +++ b/src/con.c @@ -1209,12 +1209,19 @@ static bool _con_move_to_con(Con *con, Con *target, bool behind_focused, bool fi /* We need to save the focused workspace on the output in case the * new workspace is hidden and it's necessary to immediately switch * back to the originally-focused workspace. */ - Con *old_focus = TAILQ_FIRST(&(output_get_content(dest_output)->focus_head)); + Con *old_focus_ws = TAILQ_FIRST(&(output_get_content(dest_output)->focus_head)); + Con *old_focus = focused; con_activate(con_descend_focused(con)); /* Restore focus if the output's focused workspace has changed. */ - if (con_get_workspace(focused) != old_focus) + if (con_get_workspace(focused) != old_focus_ws) { con_focus(old_focus); + } + + /* Restore focus to the currently focused container. */ + if (old_focus_ws == current_ws && old_focus->type != CT_WORKSPACE) { + con_activate(old_focus); + } } /* 7: when moving to another workspace, we leave the focus on the current diff --git a/src/output.c b/src/output.c index c76dfd03..571c01cf 100644 --- a/src/output.c +++ b/src/output.c @@ -101,6 +101,12 @@ void output_push_sticky_windows(Con *to_focus) { if (con_is_sticky(current)) { bool ignore_focus = (to_focus == NULL) || (current != to_focus->parent); con_move_to_workspace(current, visible_ws, true, false, ignore_focus); + if (!ignore_focus) { + Con *current_ws = con_get_workspace(focused); + con_activate(con_descend_focused(current)); + /* Pushing sticky windows shouldn't change the focused workspace. */ + con_activate(con_descend_focused(current_ws)); + } } } } diff --git a/testcases/t/294-focus-order.t b/testcases/t/294-focus-order.t index 71f19ded..217cc844 100644 --- a/testcases/t/294-focus-order.t +++ b/testcases/t/294-focus-order.t @@ -141,4 +141,39 @@ cmd '[con_mark=a] move to workspace ' . get_unused_workspace; is(@{get_ws_content($ws)}, 2, 'Sanity check: marked window moved'); confirm_focus('Move unfocused window from split container'); +###################################################################### +# Moving containers to another workspace puts them on the top of the +# focus stack but behind the focused container. +###################################################################### + +for my $new_workspace (0 .. 1) { + fresh_workspace; + $windows[2] = open_window; + $windows[1] = open_window; + fresh_workspace if $new_workspace; + $windows[3] = open_window; + $windows[0] = open_window; + cmd 'mark target'; + + cmd '[id=' . $windows[2]->id . '] move to mark target'; + cmd '[id=' . $windows[1]->id . '] move to mark target'; + confirm_focus('\'move to mark\' focus order' . ($new_workspace ? ' when moving containers from other workspace' : '')); +} + +###################################################################### +# Same but with workspace commands. +###################################################################### + +fresh_workspace; +$windows[2] = open_window; +$windows[1] = open_window; +$ws = fresh_workspace; +$windows[3] = open_window; +$windows[0] = open_window; +cmd 'mark target'; + +cmd '[id=' . $windows[2]->id . '] move to workspace ' . $ws; +cmd '[id=' . $windows[1]->id . '] move to workspace ' . $ws; +confirm_focus('\'move to workspace\' focus order when moving containers from other workspace'); + done_testing;