diff --git a/docs/userguide b/docs/userguide index e8240390..a8b35f3e 100644 --- a/docs/userguide +++ b/docs/userguide @@ -2320,7 +2320,9 @@ If you want to resize containers/windows using your keyboard, you can use the *Syntax*: ------------------------------------------------------- resize grow|shrink [ px [or ppt]] -resize set [px | ppt] [px | ppt] +resize set [width] [px | ppt] +resize set height [px | ppt] +resize set [width] [px | ppt] [height] [px | ppt] ------------------------------------------------------- Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index 106dac99..c0c32933 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -254,12 +254,24 @@ state RESIZE_TILING_FINAL: -> call cmd_resize($way, $direction, &resize_px, &resize_ppt) state RESIZE_SET: + 'height' + -> RESIZE_HEIGHT_GET_NUMBER + 'width' + -> width = number -> RESIZE_WIDTH state RESIZE_WIDTH: mode_width = 'px', 'ppt' -> + end + -> call cmd_resize_set(&width, $mode_width, 0, 0) + 'height' + -> RESIZE_HEIGHT_GET_NUMBER + height = number + -> RESIZE_HEIGHT + +state RESIZE_HEIGHT_GET_NUMBER: height = number -> RESIZE_HEIGHT diff --git a/src/commands.c b/src/commands.c index 0c5b8bcb..c7b57ab3 100644 --- a/src/commands.c +++ b/src/commands.c @@ -644,12 +644,12 @@ void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, c if ((floating_con = con_inside_floating(current->con))) { Con *output = con_get_output(floating_con); if (cwidth == 0) { - cwidth = output->rect.width; + cwidth = floating_con->rect.width; } else if (mode_width && strcmp(mode_width, "ppt") == 0) { cwidth = output->rect.width * ((double)cwidth / 100.0); } if (cheight == 0) { - cheight = output->rect.height; + cheight = floating_con->rect.height; } else if (mode_height && strcmp(mode_height, "ppt") == 0) { cheight = output->rect.height * ((double)cheight / 100.0); } @@ -686,7 +686,7 @@ void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, c } } - if (cheight > 0 && mode_width && strcmp(mode_width, "ppt") == 0) { + if (cheight > 0 && mode_height && strcmp(mode_height, "ppt") == 0) { /* get the appropriate current container (skip stacked/tabbed cons) */ Con *target = current->con; Con *dummy; diff --git a/testcases/t/252-floating-size.t b/testcases/t/252-floating-size.t index 2c8edf39..5c746de9 100644 --- a/testcases/t/252-floating-size.t +++ b/testcases/t/252-floating-size.t @@ -26,76 +26,92 @@ workspace ws output fake-0 EOT ################################################################################ -# Check that setting floating windows size works +# Init variables used for all tests. ################################################################################ my $tmp = fresh_workspace; - open_floating_window; - my @content = @{get_ws($tmp)->{floating_nodes}}; is(@content, 1, 'one floating node on this ws'); - my $oldrect = $content[0]->{rect}; -cmd 'resize set 100 px 250 px'; +sub do_test { + my ($width, $height) = @_; -@content = @{get_ws($tmp)->{floating_nodes}}; -cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched'); -cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched'); -cmp_ok($content[0]->{rect}->{width}, '!=', $oldrect->{width}, 'width changed'); -cmp_ok($content[0]->{rect}->{height}, '!=', $oldrect->{width}, 'height changed'); -cmp_ok($content[0]->{rect}->{width}, '==', 100, 'width changed to 100 px'); -cmp_ok($content[0]->{rect}->{height}, '==', 250, 'height changed to 250 px'); + cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x unchanged'); + cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y unchanged'); + + @content = @{get_ws($tmp)->{floating_nodes}}; + if ($width) { + cmp_ok($content[0]->{rect}->{width}, '==', $width, "width changed to $width px"); + } else { + cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width unchanged'); + } + if ($height) { + cmp_ok($content[0]->{rect}->{height}, '==', $height, "height changed to $height px"); + } else { + cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height unchanged'); + } + $oldrect = $content[0]->{rect}; +} + +################################################################################ +# Check that setting floating windows size works +################################################################################ + +cmd 'resize set 100 px 250 px'; +do_test(100, 250); ################################################################################ # Same but with ppt instead of px ################################################################################ -kill_all_windows; -$tmp = 'ws'; -cmd "workspace $tmp"; -open_floating_window; - -@content = @{get_ws($tmp)->{floating_nodes}}; -is(@content, 1, 'one floating node on this ws'); - -$oldrect = $content[0]->{rect}; - cmd 'resize set 33 ppt 20 ppt'; -my $expected_width = int(0.33 * 1333); -my $expected_height = int(0.2 * 999); - -@content = @{get_ws($tmp)->{floating_nodes}}; -cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched'); -cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched'); -cmp_ok($content[0]->{rect}->{width}, '!=', $oldrect->{width}, 'width changed'); -cmp_ok($content[0]->{rect}->{height}, '!=', $oldrect->{width}, 'height changed'); -cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px"); -cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px"); +do_test(int(0.33 * 1333), int(0.2 * 999)); ################################################################################ # Mix ppt and px in a single resize set command ################################################################################ cmd 'resize set 44 ppt 111 px'; -$expected_width = int(0.44 * 1333); -$expected_height = 111; - -@content = @{get_ws($tmp)->{floating_nodes}}; -cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched'); -cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched'); -cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px"); -cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px"); +do_test(int(0.44 * 1333), 111); cmd 'resize set 222 px 100 ppt'; -$expected_width = 222; -$expected_height = 999; +do_test(222, 999); -@content = @{get_ws($tmp)->{floating_nodes}}; -cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched'); -cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y untouched'); -cmp_ok($content[0]->{rect}->{width}, '==', $expected_width, "width changed to $expected_width px"); -cmp_ok($content[0]->{rect}->{height}, '==', $expected_height, "height changed to $expected_height px"); +################################################################################ +# Zero is interpreted as no change. +# See issue: #3276. +################################################################################ + +cmd 'resize set 0 px 333 px'; +do_test(0, 333); + +cmd 'resize set 333 px 0 ppt'; +do_test(333, 0); + +cmd 'resize set 0 px 0 ppt'; +do_test(0, 0); + +cmd 'resize set 100 ppt 0 px'; +do_test(1333, 0); + +################################################################################ +# Use 'width' and 'height' keywords. +# See issue: #3275. +################################################################################ + +cmd 'resize set width 200 px'; +do_test(200, 0); + +cmd 'resize set height 200 px'; +do_test(0, 200); + +cmd 'resize set width 300 px height 300 px'; +do_test(300, 300); + +# ppt + keyword used only for height +cmd 'resize set 100 ppt height 100 px'; +do_test(1333, 100); done_testing; diff --git a/testcases/t/541-resize-set-tiling.t b/testcases/t/541-resize-set-tiling.t index 82267baf..fcf3267a 100644 --- a/testcases/t/541-resize-set-tiling.t +++ b/testcases/t/541-resize-set-tiling.t @@ -39,6 +39,14 @@ my ($nodes, $focus) = get_ws_content($tmp); cmp_float($nodes->[0]->{percent}, 0.25, 'left window got only 25%'); cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%'); +# Same but use the 'width' keyword. +cmd 'resize set width 80 ppt'; + +($nodes, $focus) = get_ws_content($tmp); + +cmp_float($nodes->[0]->{percent}, 0.20, 'left window got 20%'); +cmp_float($nodes->[1]->{percent}, 0.80, 'right window got 80%'); + ############################################################ # resize vertically ############################################################ @@ -61,6 +69,13 @@ my ($nodes, $focus) = get_ws_content($tmp); cmp_float($nodes->[0]->{percent}, 0.25, 'top window got only 25%'); cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%'); +# Same but use the 'height' keyword. +cmd 'resize set height 80 ppt'; + +($nodes, $focus) = get_ws_content($tmp); + +cmp_float($nodes->[0]->{percent}, 0.20, 'top window got 20%'); +cmp_float($nodes->[1]->{percent}, 0.80, 'bottom window got 80%'); ############################################################ # resize horizontally and vertically