From b17e7b82c602b946594006bb3019f47bd8262f14 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Wed, 18 Oct 2017 02:04:42 +0300 Subject: [PATCH] Add support to resize floating container in percentage resize set is modified to accept both 'px' and 'ppt' height and width. Fixes #2816. --- docs/userguide | 2 +- include/commands.h | 2 +- parser-specs/commands.spec | 8 +++-- src/commands.c | 15 ++++++--- testcases/t/252-floating-size.t | 58 ++++++++++++++++++++++++++++++++- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/docs/userguide b/docs/userguide index 54ac9c8d..4fec6cda 100644 --- a/docs/userguide +++ b/docs/userguide @@ -2302,7 +2302,7 @@ If you want to resize containers/windows using your keyboard, you can use the *Syntax*: ------------------------------------------------------- resize grow|shrink [ px [or ppt]] -resize set [px] [px] +resize set [px | ppt] [px | ppt] ------------------------------------------------------- Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be diff --git a/include/commands.h b/include/commands.h index 9780f788..85d5fe78 100644 --- a/include/commands.h +++ b/include/commands.h @@ -66,7 +66,7 @@ void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_ * Implementation of 'resize set [px] [px]'. * */ -void cmd_resize_set(I3_CMD, long cwidth, long cheight); +void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height); /** * Implementation of 'resize grow|shrink [ px] [or ppt]'. diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index a5873328..0289fa1a 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -258,14 +258,16 @@ state RESIZE_SET: -> RESIZE_WIDTH state RESIZE_WIDTH: - 'px' + mode_width = 'px', 'ppt' -> height = number -> RESIZE_HEIGHT state RESIZE_HEIGHT: - 'px', end - -> call cmd_resize_set(&width, &height) + mode_height = 'px', 'ppt' + -> + end + -> call cmd_resize_set(&width, $mode_width, &height, $mode_height) # rename workspace to # rename workspace to diff --git a/src/commands.c b/src/commands.c index d7cdf219..e68fcd80 100644 --- a/src/commands.c +++ b/src/commands.c @@ -676,13 +676,13 @@ void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px, } /* - * Implementation of 'resize set [px] [px]'. + * Implementation of 'resize set [px | ppt] [px | ppt]'. * */ -void cmd_resize_set(I3_CMD, long cwidth, long cheight) { - DLOG("resizing to %ldx%ld px\n", cwidth, cheight); +void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) { + DLOG("resizing to %ld %s x %ld %s\n", cwidth, mode_width, cheight, mode_height); if (cwidth <= 0 || cheight <= 0) { - ELOG("Resize failed: dimensions cannot be negative (was %ldx%ld)\n", cwidth, cheight); + ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height); return; } @@ -692,6 +692,13 @@ void cmd_resize_set(I3_CMD, long cwidth, long cheight) { TAILQ_FOREACH(current, &owindows, owindows) { Con *floating_con; if ((floating_con = con_inside_floating(current->con))) { + Con *output = con_get_output(floating_con); + if (mode_width && strcmp(mode_width, "ppt") == 0) { + cwidth = output->rect.width * ((double)cwidth / 100.0); + } + if (mode_height && strcmp(mode_height, "ppt") == 0) { + cheight = output->rect.height * ((double)cheight / 100.0); + } floating_resize(floating_con, cwidth, cheight); } else { ELOG("Resize failed: %p not a floating container\n", current->con); diff --git a/testcases/t/252-floating-size.t b/testcases/t/252-floating-size.t index 8d8d4120..ac0c48d0 100644 --- a/testcases/t/252-floating-size.t +++ b/testcases/t/252-floating-size.t @@ -17,7 +17,13 @@ # Test behavior of "resize " command. # Ticket: #1727 # Bug still in: 4.10.2-1-gc0dbc5d -use i3test; +use i3test i3_config => <{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'); +################################################################################ +# 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"); + +################################################################################ +# Mix ppt and px in a single resize set command +################################################################################ + +cmd 'resize set 44 ppt 111 px'; +my $expected_width = int(0.44 * 1333); +my $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"); + +cmd 'resize set 222 px 100 ppt'; +my $expected_width = 222; +my $expected_height = 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"); + done_testing; -- 2.39.2