Support "resize set W H"

This commit is contained in:
rr- 2015-09-05 08:31:45 +02:00
parent ee2983c791
commit 23d16e1332
8 changed files with 178 additions and 1 deletions

View File

@ -2007,6 +2007,7 @@ If you want to resize containers/windows using your keyboard, you can use the
*Syntax*: *Syntax*:
------------------------------------------------------- -------------------------------------------------------
resize grow|shrink <direction> [<px> px [or <ppt> ppt]] resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
resize set <width> [px] <height> [px]
------------------------------------------------------- -------------------------------------------------------
Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be
@ -2015,7 +2016,8 @@ 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). default is 10 percentage points). Note that +resize set+ will only work for
floating containers.
I recommend using the resize command inside a so called +mode+: I recommend using the resize command inside a so called +mode+:
@ -2048,6 +2050,11 @@ mode "resize" {
bindsym $mod+r mode "resize" bindsym $mod+r mode "resize"
---------------------------------------------------------------------- ----------------------------------------------------------------------
*Example 2 - setting urxvt size to 640x480:*
------------------------------------------------
for_window [class="urxvt"] resize set 640 480
------------------------------------------------
=== Jumping to specific windows === Jumping to specific windows
Often when in a multi-monitor environment, you want to quickly jump to a Often when in a multi-monitor environment, you want to quickly jump to a

View File

@ -60,6 +60,12 @@ void cmd_move_con_to_workspace_name(I3_CMD, char *name);
*/ */
void cmd_move_con_to_workspace_number(I3_CMD, char *which); void cmd_move_con_to_workspace_number(I3_CMD, char *which);
/**
* Implementation of 'resize set <px> [px] <px> [px]'.
*
*/
void cmd_size(I3_CMD, char *cwidth, char *cheight);
/** /**
* Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'. * Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'.
* *

View File

@ -188,6 +188,15 @@ drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event,
*/ */
void floating_reposition(Con *con, Rect newrect); void floating_reposition(Con *con, Rect newrect);
/**
* Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
* actual size with regard to size constraints taken from user settings.
* Additionally, the dimensions may be upscaled until they're divisible by the
* window's size hints.
*
*/
void floating_resize(Con *floating_con, int x, int y);
/** /**
* Fixes the coordinates of the floating window whenever the window gets * Fixes the coordinates of the floating window whenever the window gets
* reassigned to a different output (or when the outputs rect changes). * reassigned to a different output (or when the outputs rect changes).

View File

@ -211,6 +211,8 @@ state UNMARK:
state RESIZE: state RESIZE:
way = 'grow', 'shrink' way = 'grow', 'shrink'
-> RESIZE_DIRECTION -> RESIZE_DIRECTION
set = 'set'
-> RESIZE_SET
state RESIZE_DIRECTION: state RESIZE_DIRECTION:
direction = 'up', 'down', 'left', 'right', 'width', 'height' direction = 'up', 'down', 'left', 'right', 'width', 'height'
@ -238,6 +240,20 @@ state RESIZE_TILING_FINAL:
'ppt', end 'ppt', end
-> call cmd_resize($way, $direction, $resize_px, $resize_ppt) -> call cmd_resize($way, $direction, $resize_px, $resize_ppt)
state RESIZE_SET:
width = word
-> RESIZE_WIDTH
state RESIZE_WIDTH:
'px'
->
height = word
-> RESIZE_HEIGHT
state RESIZE_HEIGHT:
'px', end
-> call cmd_size($width, $height)
# rename workspace <name> to <name> # rename workspace <name> to <name>
# rename workspace to <name> # rename workspace to <name>
state RENAME: state RENAME:

View File

@ -823,6 +823,37 @@ void cmd_resize(I3_CMD, char *way, char *direction, char *resize_px, char *resiz
ysuccess(true); ysuccess(true);
} }
/*
* Implementation of 'resize set <px> [px] <px> [px]'.
*
*/
void cmd_size(I3_CMD, char *cwidth, char *cheight) {
DLOG("resizing to %sx%s px\n", cwidth, cheight);
// TODO: We could either handle this in the parser itself as a separate token (and make the stack typed) or we need a better way to convert a string to a number with error checking
int x = atoi(cwidth);
int y = atoi(cheight);
if (x <= 0 || y <= 0) {
ELOG("Resize failed: dimensions cannot be negative (was %sx%s)\n", cwidth, cheight);
return;
}
HANDLE_EMPTY_MATCH;
owindow *current;
TAILQ_FOREACH(current, &owindows, owindows) {
Con *floating_con;
if ((floating_con = con_inside_floating(current->con))) {
floating_resize(floating_con, x, y);
} else {
ELOG("Resize failed: %p not a floating container\n", current->con);
}
}
cmd_output->needs_tree_render = true;
// XXX: default reply for now, make this a better reply
ysuccess(true);
}
/* /*
* Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'. * Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'.
* *

View File

@ -825,6 +825,37 @@ void floating_reposition(Con *con, Rect newrect) {
tree_render(); tree_render();
} }
/*
* Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
* actual size with regard to size constraints taken from user settings.
* Additionally, the dimensions may be upscaled until they're divisible by the
* window's size hints.
*
*/
void floating_resize(Con *floating_con, int x, int y) {
DLOG("floating resize to %dx%d px\n", x, y);
Rect *rect = &floating_con->rect;
Con *focused_con = con_descend_focused(floating_con);
if (focused_con->window == NULL) {
DLOG("No window is focused. Not resizing.\n");
return;
}
int wi = focused_con->window->width_increment;
int hi = focused_con->window->height_increment;
rect->width = x;
rect->height = y;
if (wi)
rect->width += (wi - 1 - rect->width) % wi;
if (hi)
rect->height += (hi - 1 - rect->height) % hi;
floating_check_size(floating_con);
/* If this is a scratchpad window, don't auto center it from now on. */
if (floating_con->scratchpad_state == SCRATCHPAD_FRESH)
floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
}
/* /*
* Fixes the coordinates of the floating window whenever the window gets * Fixes the coordinates of the floating window whenever the window gets
* reassigned to a different output (or when the outputs rect changes). * reassigned to a different output (or when the outputs rect changes).

View File

@ -186,4 +186,36 @@ is($rect->{y}, $old_y, 'window did not move when trying to resize');
exit_gracefully($pid); exit_gracefully($pid);
################################################################################
# 7: check floating_maximum_size with cmd_size
################################################################################
my $config = <<EOT;
# i3 config file (v4)
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# Test with different dimensions than the i3 default.
floating_minimum_size 80 x 70
floating_maximum_size 100 x 90
EOT
$pid = launch_with_config($config);
my $window = open_floating_window(rect => [ 0, 0, 90, 80 ]);
cmd 'border none';
cmd 'resize set 101 91';
sync_with_i3;
my $rect = $window->rect;
is($rect->{width}, 100, 'width did not exceed maximum width');
is($rect->{height}, 90, 'height did not exceed maximum height');
cmd 'resize set 79 69';
sync_with_i3;
$rect = $window->rect;
is($rect->{width}, 80, 'width did not exceed minimum width');
is($rect->{height}, 70, 'height did not exceed minimum height');
exit_gracefully($pid);
done_testing; done_testing;

View File

@ -0,0 +1,45 @@
#!perl
# vim:ts=4:sw=4:expandtab
#
# Please read the following documents before working on tests:
# • http://build.i3wm.org/docs/testsuite.html
# (or docs/testsuite)
#
# • http://build.i3wm.org/docs/lib-i3test.html
# (alternatively: perldoc ./testcases/lib/i3test.pm)
#
# • http://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)
#
# Test behavior of "resize <width> <height>" command.
# Ticket: #1727
# Bug still in: 4.10.2-1-gc0dbc5d
use i3test;
################################################################################
# Check that setting floating windows size works
################################################################################
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';
@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');
done_testing;