*/
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) {
+ if (cwidth < 0 || cheight < 0) {
ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height);
return;
}
HANDLE_EMPTY_MATCH;
owindow *current;
+ bool success = true;
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) {
+ if (cwidth == 0) {
+ cwidth = output->rect.width;
+ } else if (mode_width && strcmp(mode_width, "ppt") == 0) {
cwidth = output->rect.width * ((double)cwidth / 100.0);
}
- if (mode_height && strcmp(mode_height, "ppt") == 0) {
+ if (cheight == 0) {
+ cheight = output->rect.height;
+ } else 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);
+ if (current->con->window && current->con->window->dock) {
+ DLOG("This is a dock window. Not resizing (con = %p)\n)", current->con);
+ continue;
+ }
+
+ if (cwidth > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
+ /* get the appropriate current container (skip stacked/tabbed cons) */
+ Con *target = current->con;
+ Con *dummy;
+ resize_find_tiling_participants(&target, &dummy, D_LEFT, true);
+
+ /* Calculate new size for the target container */
+ double current_percent = target->percent;
+ char *action_string;
+ long adjustment;
+
+ if (current_percent > cwidth) {
+ action_string = "shrink";
+ adjustment = (int)(current_percent * 100) - cwidth;
+ } else {
+ action_string = "grow";
+ adjustment = cwidth - (int)(current_percent * 100);
+ }
+
+ /* perform resizing and report failure if not possible */
+ if (!cmd_resize_tiling_width_height(current_match, cmd_output,
+ target, action_string, "width", adjustment)) {
+ success = false;
+ }
+ }
+
+ if (cheight > 0 && mode_width && strcmp(mode_width, "ppt") == 0) {
+ /* get the appropriate current container (skip stacked/tabbed cons) */
+ Con *target = current->con;
+ Con *dummy;
+ resize_find_tiling_participants(&target, &dummy, D_DOWN, true);
+
+ /* Calculate new size for the target container */
+ double current_percent = target->percent;
+ char *action_string;
+ long adjustment;
+
+ if (current_percent > cheight) {
+ action_string = "shrink";
+ adjustment = (int)(current_percent * 100) - cheight;
+ } else {
+ action_string = "grow";
+ adjustment = cheight - (int)(current_percent * 100);
+ }
+
+ /* perform resizing and report failure if not possible */
+ if (!cmd_resize_tiling_width_height(current_match, cmd_output,
+ target, action_string, "height", adjustment)) {
+ success = false;
+ }
+ }
}
}
cmd_output->needs_tree_render = true;
- // XXX: default reply for now, make this a better reply
- ysuccess(true);
+ ysuccess(success);
}
/*
--- /dev/null
+#!perl
+# vim:ts=4:sw=4:expandtab
+#
+# Please read the following documents before working on tests:
+# • https://build.i3wm.org/docs/testsuite.html
+# (or docs/testsuite)
+#
+# • https://build.i3wm.org/docs/lib-i3test.html
+# (alternatively: perldoc ./testcases/lib/i3test.pm)
+#
+# • https://build.i3wm.org/docs/ipc.html
+# (or docs/ipc)
+#
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
+# (unless you are already familiar with Perl)
+#
+# Tests resizing tiling containers
+use i3test;
+
+############################################################
+# resize horizontally
+############################################################
+
+my $tmp = fresh_workspace;
+
+cmd 'split h';
+
+my $left = open_window;
+my $right = open_window;
+
+diag("left = " . $left->id . ", right = " . $right->id);
+
+is($x->input_focus, $right->id, 'Right window focused');
+
+cmd 'resize set 75 ppt 0 ppt';
+
+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%');
+
+############################################################
+# resize vertically
+############################################################
+
+my $tmp = fresh_workspace;
+
+cmd 'split v';
+
+my $top = open_window;
+my $bottom = open_window;
+
+diag("top = " . $top->id . ", bottom = " . $bottom->id);
+
+is($x->input_focus, $bottom->id, 'Bottom window focused');
+
+cmd 'resize set 0 ppt 75 ppt';
+
+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%');
+
+
+############################################################
+# resize horizontally and vertically
+############################################################
+
+my $tmp = fresh_workspace;
+
+cmd 'split h';
+my $left = open_window;
+my $top_right = open_window;
+cmd 'split v';
+my $bottom_right = open_window;
+
+diag("left = " . $left->id . ", top-right = " . $top_right->id . ", bottom-right = " . $bottom_right->id);
+
+is($x->input_focus, $bottom_right->id, 'Bottom-right window focused');
+
+cmd 'resize set 75 ppt 75 ppt';
+
+my ($nodes, $focus) = get_ws_content($tmp);
+
+cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
+cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
+cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.25, 'top-right window got 25%');
+cmp_float($nodes->[1]->{nodes}->[1]->{percent}, 0.75, 'bottom-right window got 75%');
+
+
+############################################################
+# resize from inside a tabbed container
+############################################################
+
+my $tmp = fresh_workspace;
+
+cmd 'split h';
+
+my $left = open_window;
+my $right1 = open_window;
+
+cmd 'split h';
+cmd 'layout tabbed';
+
+my $right2 = open_window;
+
+diag("left = " . $left->id . ", right1 = " . $right1->id . ", right2 = " . $right2->id);
+
+is($x->input_focus, $right2->id, '2nd right window focused');
+
+cmd 'resize set 75 ppt 0 ppt';
+
+my ($nodes, $focus) = get_ws_content($tmp);
+
+cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
+cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
+
+
+############################################################
+# resize from inside a stacked container
+############################################################
+
+my $tmp = fresh_workspace;
+
+cmd 'split h';
+
+my $left = open_window;
+my $right1 = open_window;
+
+cmd 'split h';
+cmd 'layout stacked';
+
+my $right2 = open_window;
+
+diag("left = " . $left->id . ", right1 = " . $right1->id . ", right2 = " . $right2->id);
+
+is($x->input_focus, $right2->id, '2nd right window focused');
+
+cmd 'resize set 75 ppt 0 ppt';
+
+my ($nodes, $focus) = get_ws_content($tmp);
+
+cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
+cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
+
+
+done_testing;