From 0045cfa637b802801fb0b2e27013f1e61264d081 Mon Sep 17 00:00:00 2001 From: Simon Elsbrock Date: Fri, 21 Dec 2012 22:13:31 +0100 Subject: [PATCH] move visible scratchpad window to focused workspace If there is a visible scratchpad on another (non-internal) workspace, bring it to the focused workspace instead of doing nothing. closes #784 --- src/scratchpad.c | 18 ++++++++++ testcases/t/185-scratchpad.t | 64 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/src/scratchpad.c b/src/scratchpad.c index 7b309095..c38e63b1 100644 --- a/src/scratchpad.c +++ b/src/scratchpad.c @@ -94,6 +94,24 @@ void scratchpad_show(Con *con) { con_toggle_fullscreen(focused, CF_OUTPUT); } + /* If this was 'scratchpad show' without criteria, we check if there is a + * visible scratchpad window on another workspace. In this case we move it + * to the current workspace. */ + Con *walk_con; + Con *focused_ws = con_get_workspace(focused); + TAILQ_FOREACH(walk_con, &all_cons, all_cons) { + Con *walk_ws = con_get_workspace(walk_con); + if (walk_ws && + !con_is_internal(walk_ws) && focused_ws != walk_ws && + (floating = con_inside_floating(walk_con)) && + floating->scratchpad_state != SCRATCHPAD_NONE) { + DLOG("Found a visible scratchpad window on another workspace,\n"); + DLOG("moving it to this workspace: con = %p\n", walk_con); + con_move_to_workspace(walk_con, focused_ws, true, false); + return; + } + } + /* If this was 'scratchpad show' without criteria, we check if the * currently focused window is a scratchpad window and should be hidden * again. */ diff --git a/testcases/t/185-scratchpad.t b/testcases/t/185-scratchpad.t index af881a29..598f2b36 100644 --- a/testcases/t/185-scratchpad.t +++ b/testcases/t/185-scratchpad.t @@ -336,6 +336,70 @@ verify_scratchpad_move_multiple_win(0); $tmp = fresh_workspace; verify_scratchpad_move_multiple_win(1); +################################################################################ +# 12: open a scratchpad window on a workspace, switch to another workspace and +# call 'scratchpad show' again +################################################################################ + +sub verify_scratchpad_move_with_visible_scratch_con { + my ($first, $second, $cross_output) = @_; + + cmd "workspace $first"; + + my $window1 = open_window; + cmd 'move scratchpad'; + + my $window2 = open_window; + cmd 'move scratchpad'; + + # this should bring up window 1 + cmd 'scratchpad show'; + + my $ws = get_ws($first); + is(scalar @{$ws->{floating_nodes}}, 1, 'one floating node on ws1'); + is($x->input_focus, $window1->id, "showed the correct scratchpad window1"); + + # this should bring up window 1 + cmd "workspace $second"; + cmd 'scratchpad show'; + is($x->input_focus, $window1->id, "showed the correct scratchpad window1"); + + my $ws2 = get_ws($second); + is(scalar @{$ws2->{floating_nodes}}, 1, 'one floating node on ws2'); + unless ($cross_output) { + ok(!workspace_exists($first), 'ws1 was empty and therefore closed'); + } else { + $ws = get_ws($first); + is(scalar @{$ws->{floating_nodes}}, 0, 'ws1 has no floating nodes'); + } + + # hide window 1 again + cmd 'move scratchpad'; + + # this should bring up window 2 + cmd "workspace $first"; + cmd 'scratchpad show'; + is($x->input_focus, $window2->id, "showed the correct scratchpad window"); +} + +# let's clear the scratchpad first +sub clear_scratchpad { + while (scalar @{get_ws('__i3_scratch')->{floating_nodes}}) { + cmd 'scratchpad show'; + cmd 'kill'; + } +} + +clear_scratchpad; +is (scalar @{get_ws('__i3_scratch')->{floating_nodes}}, 0, "scratchpad is empty"); + +my ($first, $second); +$first = fresh_workspace; +$second = fresh_workspace; + +verify_scratchpad_move_with_visible_scratch_con($first, $second, 0); +does_i3_live; + # TODO: make i3bar display *something* when a window on the scratchpad has the urgency hint done_testing;