Implement 'resize set <width> ppt <height> ppt' command for tiling windows (#3036)
This commit is contained in:
parent
1a04608796
commit
7b59da8a4f
|
@ -2320,8 +2320,11 @@ space from all the other containers. The optional pixel argument specifies by
|
||||||
how many pixels a *floating container* should be grown or shrunk (the default
|
how many pixels a *floating container* should be grown or shrunk (the default
|
||||||
is 10 pixels). The ppt argument means percentage points and specifies by how
|
is 10 pixels). The ppt argument means percentage points and specifies by how
|
||||||
many percentage points a *tiling container* should be grown or shrunk (the
|
many percentage points a *tiling container* should be grown or shrunk (the
|
||||||
default is 10 percentage points). Note that +resize set+ will only work for
|
default is 10 percentage points).
|
||||||
floating containers.
|
|
||||||
|
Notes about +resize set+: a value of 0 for <width> or <height> means "do
|
||||||
|
not resize in this direction", and resizing a tiling container by +px+ is not
|
||||||
|
implemented.
|
||||||
|
|
||||||
It is recommended to define bindings for resizing in a dedicated binding mode.
|
It is recommended to define bindings for resizing in a dedicated binding mode.
|
||||||
See <<binding_modes>> and the example in the i3
|
See <<binding_modes>> and the example in the i3
|
||||||
|
|
|
@ -63,7 +63,7 @@ void cmd_move_con_to_workspace_name(I3_CMD, const char *name, const char *no_aut
|
||||||
void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_auto_back_and_forth);
|
void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_auto_back_and_forth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of 'resize set <px> [px] <px> [px]'.
|
* Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height);
|
void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height);
|
||||||
|
|
|
@ -659,7 +659,7 @@ void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px,
|
||||||
*/
|
*/
|
||||||
void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) {
|
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);
|
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);
|
ELOG("Resize failed: dimensions cannot be negative (was %ld %s x %ld %s)\n", cwidth, mode_width, cheight, mode_height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -667,25 +667,84 @@ void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, c
|
||||||
HANDLE_EMPTY_MATCH;
|
HANDLE_EMPTY_MATCH;
|
||||||
|
|
||||||
owindow *current;
|
owindow *current;
|
||||||
|
bool success = true;
|
||||||
TAILQ_FOREACH(current, &owindows, owindows) {
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
Con *floating_con;
|
Con *floating_con;
|
||||||
if ((floating_con = con_inside_floating(current->con))) {
|
if ((floating_con = con_inside_floating(current->con))) {
|
||||||
Con *output = con_get_output(floating_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);
|
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);
|
cheight = output->rect.height * ((double)cheight / 100.0);
|
||||||
}
|
}
|
||||||
floating_resize(floating_con, cwidth, cheight);
|
floating_resize(floating_con, cwidth, cheight);
|
||||||
} else {
|
} 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;
|
cmd_output->needs_tree_render = true;
|
||||||
// XXX: default reply for now, make this a better reply
|
ysuccess(success);
|
||||||
ysuccess(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
#!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;
|
Loading…
Reference in New Issue