diff --git a/src/scratchpad.c b/src/scratchpad.c index 39f18546..9fceb2d7 100644 --- a/src/scratchpad.c +++ b/src/scratchpad.c @@ -108,8 +108,10 @@ void scratchpad_show(Con *con) { Con *output = con_get_output(con); con->rect.width = output->rect.width * 0.5; con->rect.height = output->rect.height * 0.75; - con->rect.x = (output->rect.width / 2.0) - (con->rect.width / 2.0); - con->rect.y = (output->rect.height / 2.0) - (con->rect.height / 2.0); + con->rect.x = output->rect.x + + ((output->rect.width / 2.0) - (con->rect.width / 2.0)); + con->rect.y = output->rect.y + + ((output->rect.height / 2.0) - (con->rect.height / 2.0)); con->scratchpad_state = SCRATCHPAD_CHANGED; } diff --git a/testcases/lib/i3test.pm b/testcases/lib/i3test.pm index 87758777..f9cec64e 100644 --- a/testcases/lib/i3test.pm +++ b/testcases/lib/i3test.pm @@ -271,7 +271,34 @@ sub get_unused_workspace { $tmp } +=head2 fresh_workspace(...) + +Switches to an unused workspace and returns the name of that workspace. + +Optionally switches to the specified output first. + + my $ws = fresh_workspace; + + # Get a fresh workspace on the second output. + my $ws = fresh_workspace(output => 1); + +=cut sub fresh_workspace { + my %args = @_; + if (exists($args{output})) { + my $i3 = i3(get_socket_path()); + my $tree = $i3->get_tree->recv; + my $output = first { $_->{name} eq "xinerama-$args{output}" } + @{$tree->{nodes}}; + die "BUG: Could not find output $args{output}" unless defined($output); + # Get the focused workspace on that output and switch to it. + my $content = first { $_->{type} == 2 } @{$output->{nodes}}; + my $focused = $content->{focus}->[0]; + my $workspace = first { $_->{id} == $focused } @{$content->{nodes}}; + $workspace = $workspace->{name}; + cmd("workspace $workspace"); + } + my $unused = get_unused_workspace; cmd("workspace $unused"); $unused diff --git a/testcases/t/501-scratchpad.t b/testcases/t/501-scratchpad.t new file mode 100644 index 00000000..ef57ffad --- /dev/null +++ b/testcases/t/501-scratchpad.t @@ -0,0 +1,95 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Verifies that scratchpad windows show up on the proper output. +# ticket #596, bug present until up to commit +# 89dded044b4fffe78f9d70778748fabb7ac533e9. +# +use i3test; + +my $i3 = i3(get_socket_path()); + +################################################################################ +# Open a workspace on the second output, put a window to scratchpad, display +# it, verify it’s on the same workspace. +################################################################################ + +sub verify_scratchpad_on_same_ws { + my ($ws) = @_; + + is(scalar @{get_ws($ws)->{nodes}}, 0, 'no nodes on this ws'); + + my $window = open_window; + + is(scalar @{get_ws($ws)->{nodes}}, 1, 'one nodes on this ws'); + + cmd 'move scratchpad'; + + is(scalar @{get_ws($ws)->{nodes}}, 0, 'no nodes on this ws'); + + cmd 'scratchpad show'; + is(scalar @{get_ws($ws)->{nodes}}, 0, 'no nodes on this ws'); + is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws'); +} + +my $second = fresh_workspace(output => 1); + +verify_scratchpad_on_same_ws($second); + +################################################################################ +# The same thing, but on the first output. +################################################################################ + +my $first = fresh_workspace(output => 0); + +verify_scratchpad_on_same_ws($first); + +################################################################################ +# Now open the scratchpad on one output and switch to another. +################################################################################ + +sub verify_scratchpad_switch { + my ($first, $second) = @_; + + cmd "workspace $first"; + + is(scalar @{get_ws($first)->{nodes}}, 0, 'no nodes on this ws'); + + my $window = open_window; + + is(scalar @{get_ws($first)->{nodes}}, 1, 'one nodes on this ws'); + + cmd 'move scratchpad'; + + is(scalar @{get_ws($first)->{nodes}}, 0, 'no nodes on this ws'); + + cmd "workspace $second"; + + cmd 'scratchpad show'; + my $ws = get_ws($second); + is(scalar @{$ws->{nodes}}, 0, 'no nodes on this ws'); + is(scalar @{$ws->{floating_nodes}}, 1, 'one floating node on this ws'); + + # Verify that the coordinates are within bounds. + my $srect = $ws->{floating_nodes}->[0]->{rect}; + my $rect = $ws->{rect}; + cmd 'nop before bounds check'; + cmp_ok($srect->{x}, '>=', $rect->{x}, 'x within bounds'); + cmp_ok($srect->{y}, '>=', $rect->{y}, 'y within bounds'); + cmp_ok($srect->{x} + $srect->{width}, '<=', $rect->{x} + $rect->{width}, + 'width within bounds'); + cmp_ok($srect->{y} + $srect->{height}, '<=', $rect->{y} + $rect->{height}, + 'height within bounds'); +} + +$first = fresh_workspace(output => 0); +$second = fresh_workspace(output => 1); + +verify_scratchpad_switch($first, $second); + +$first = fresh_workspace(output => 1); +$second = fresh_workspace(output => 0); + +verify_scratchpad_switch($first, $second); + +done_testing;