Support "resize set W H"
This commit is contained in:
parent
ee2983c791
commit
23d16e1332
|
@ -2007,6 +2007,7 @@ If you want to resize containers/windows using your keyboard, you can use the
|
|||
*Syntax*:
|
||||
-------------------------------------------------------
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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+:
|
||||
|
||||
|
@ -2048,6 +2050,11 @@ 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
|
||||
|
||||
Often when in a multi-monitor environment, you want to quickly jump to a
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* 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]'.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* reassigned to a different output (or when the output’s rect changes).
|
||||
|
|
|
@ -211,6 +211,8 @@ state UNMARK:
|
|||
state RESIZE:
|
||||
way = 'grow', 'shrink'
|
||||
-> RESIZE_DIRECTION
|
||||
set = 'set'
|
||||
-> RESIZE_SET
|
||||
|
||||
state RESIZE_DIRECTION:
|
||||
direction = 'up', 'down', 'left', 'right', 'width', 'height'
|
||||
|
@ -238,6 +240,20 @@ state RESIZE_TILING_FINAL:
|
|||
'ppt', end
|
||||
-> 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 to <name>
|
||||
state RENAME:
|
||||
|
|
|
@ -823,6 +823,37 @@ void cmd_resize(I3_CMD, char *way, char *direction, char *resize_px, char *resiz
|
|||
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'.
|
||||
*
|
||||
|
|
|
@ -825,6 +825,37 @@ void floating_reposition(Con *con, Rect newrect) {
|
|||
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
|
||||
* reassigned to a different output (or when the output’s rect changes).
|
||||
|
|
|
@ -186,4 +186,36 @@ is($rect->{y}, $old_y, 'window did not move when trying to resize');
|
|||
|
||||
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;
|
||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue