resize command updates (#713)

This commit is contained in:
Zandr Martin 2016-07-03 12:11:21 -05:00
parent aced6daa19
commit d5e4fff345
Failed to generate hash of commit
6 changed files with 229 additions and 52 deletions

View file

@ -21,6 +21,10 @@ swayc_t *get_focused_container(swayc_t *parent);
swayc_t *get_focused_view(swayc_t *parent); swayc_t *get_focused_view(swayc_t *parent);
swayc_t *get_focused_float(swayc_t *ws); swayc_t *get_focused_float(swayc_t *ws);
// a special-case function to get the floating view, regardless
// of whether it's tiled or floating
swayc_t *get_focused_view_include_floating(swayc_t *parent);
bool set_focused_container(swayc_t *container); bool set_focused_container(swayc_t *container);
bool set_focused_container_for(swayc_t *ancestor, swayc_t *container); bool set_focused_container_for(swayc_t *ancestor, swayc_t *container);

View file

@ -2,7 +2,13 @@
#define _SWAY_RESIZE_H #define _SWAY_RESIZE_H
#include <stdbool.h> #include <stdbool.h>
bool set_size_tiled(int amount, bool use_width); enum resize_dim_types {
bool resize_tiled(int amount, bool use_width); RESIZE_DIM_PX,
RESIZE_DIM_PPT,
RESIZE_DIM_DEFAULT,
};
bool set_size(int dimension, bool use_width);
bool resize(int dimension, bool use_width, enum resize_dim_types dim_type);
#endif #endif

View file

@ -2010,31 +2010,41 @@ static struct cmd_results *cmd_resize(int argc, char **argv) {
return error; return error;
} }
int amount = (int)strtol(argv[argc - 1], NULL, 10); int dim_arg = argc - 1;
enum resize_dim_types dim_type = RESIZE_DIM_DEFAULT;
if (strcasecmp(argv[dim_arg], "ppt") == 0) {
dim_type = RESIZE_DIM_PPT;
dim_arg--;
} else if (strcasecmp(argv[dim_arg], "px") == 0) {
dim_type = RESIZE_DIM_PX;
dim_arg--;
}
int amount = (int)strtol(argv[dim_arg], NULL, 10);
if (errno == ERANGE || amount == 0) { if (errno == ERANGE || amount == 0) {
errno = 0; errno = 0;
return cmd_results_new(CMD_INVALID, "resize", "Number is out of range."); amount = 10; // this is the default resize dimension used by i3 for both px and ppt
sway_log(L_DEBUG, "Tried to get resize dimension out of '%s' but failed; setting dimension to default %d",
argv[dim_arg], amount);
} }
bool use_width = false;
if (strcasecmp(argv[0], "shrink") == 0 || strcmp(argv[0], "grow") == 0) { if (strcasecmp(argv[1], "width") == 0) {
if (strcasecmp(argv[0], "shrink") == 0) { use_width = true;
amount *= -1; } else if (strcasecmp(argv[1], "height") != 0) {
}
if (strcasecmp(argv[1], "width") == 0) {
resize_tiled(amount, true);
} else if (strcmp(argv[1], "height") == 0) {
resize_tiled(amount, false);
} else {
return cmd_results_new(CMD_INVALID, "resize",
"Expected 'resize <shrink|grow> <width|height> <amount>'");
}
} else {
return cmd_results_new(CMD_INVALID, "resize", return cmd_results_new(CMD_INVALID, "resize",
"Expected 'resize <shrink|grow> <width|height> <amount>'"); "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
} }
if (strcasecmp(argv[0], "shrink") == 0) {
amount *= -1;
} else if (strcasecmp(argv[0], "grow") != 0) {
return cmd_results_new(CMD_INVALID, "resize",
"Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
}
resize(amount, use_width, dim_type);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }
@ -2044,26 +2054,59 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
return error; return error;
} }
int cmd_num = 0; if (strcasecmp(argv[0], "width") == 0 || strcasecmp(argv[0], "height") == 0) {
int amount; // handle `reset set width 100 px height 100 px` syntax, also allows
// specifying only one dimension for a `resize set`
int cmd_num = 0;
int dim;
while (cmd_num < argc) { while ((cmd_num + 1) < argc) {
amount = (int)strtol(argv[cmd_num + 1], NULL, 10); dim = (int)strtol(argv[cmd_num + 1], NULL, 10);
if (errno == ERANGE || amount == 0) { if (errno == ERANGE || dim == 0) {
errno = 0;
return cmd_results_new(CMD_INVALID, "resize set",
"Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
}
if (strcasecmp(argv[cmd_num], "width") == 0) {
set_size(dim, true);
} else if (strcasecmp(argv[cmd_num], "height") == 0) {
set_size(dim, false);
} else {
return cmd_results_new(CMD_INVALID, "resize set",
"Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
}
cmd_num += 2;
if (cmd_num < argc && strcasecmp(argv[cmd_num], "px") == 0) {
// if this was `resize set width 400 px height 300 px`, disregard the `px` arg
cmd_num++;
}
}
} else {
// handle `reset set 100 px 100 px` syntax
int width = (int)strtol(argv[0], NULL, 10);
if (errno == ERANGE || width == 0) {
errno = 0; errno = 0;
return cmd_results_new(CMD_INVALID, "resize set", "Number is out of range."); return cmd_results_new(CMD_INVALID, "resize set",
"Expected 'resize set <width> [px] <height> [px]'");
} }
if (strcasecmp(argv[cmd_num], "width") == 0) { int height_arg = 1;
set_size_tiled(amount, true); if (strcasecmp(argv[1], "px") == 0) {
} else if (strcasecmp(argv[cmd_num], "height") == 0) { height_arg = 2;
set_size_tiled(amount, false);
} else {
return cmd_results_new(CMD_INVALID, "resize",
"Expected 'resize set <width|height> <amount> [<width|height> <amount>]'");
} }
cmd_num += 2; int height = (int)strtol(argv[height_arg], NULL, 10);
if (errno == ERANGE || height == 0) {
errno = 0;
return cmd_results_new(CMD_INVALID, "resize set",
"Expected 'resize set <width> [px] <height> [px]'");
}
set_size(width, true);
set_size(height, false);
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -243,3 +243,22 @@ swayc_t *get_focused_float(swayc_t *ws) {
} }
return NULL; return NULL;
} }
swayc_t *get_focused_view_include_floating(swayc_t *parent) {
swayc_t *c = parent;
swayc_t *f = NULL;
while (c && c->type != C_VIEW) {
if (c->type == C_WORKSPACE && c->focused == NULL) {
return ((f = get_focused_float(c))) ? f : c;
}
c = c->focused;
}
if (c == NULL) {
c = swayc_active_workspace_for(parent);
}
return c;
}

View file

@ -7,20 +7,52 @@
#include "handlers.h" #include "handlers.h"
#include "resize.h" #include "resize.h"
bool set_size_tiled(int amount, bool use_width) { static bool set_size_floating(int new_dimension, bool use_width) {
int desired; swayc_t *view = get_focused_float(swayc_active_workspace());
swayc_t *focused = get_focused_view(swayc_active_workspace()); if (view) {
if (use_width) {
int current_width = view->width;
view->desired_width = new_dimension;
floating_view_sane_size(view);
if (use_width) { int new_x = view->x + (int)(((view->desired_width - current_width) / 2) * -1);
desired = amount - focused->width; view->width = view->desired_width;
} else { view->x = new_x;
desired = amount - focused->height;
update_geometry(view);
} else {
int current_height = view->height;
view->desired_height = new_dimension;
floating_view_sane_size(view);
int new_y = view->y + (int)(((view->desired_height - current_height) / 2) * -1);
view->height = view->desired_height;
view->y = new_y;
update_geometry(view);
}
return true;
} }
return resize_tiled(desired, use_width); return false;
} }
bool resize_tiled(int amount, bool use_width) { static bool resize_floating(int amount, bool use_width) {
swayc_t *view = get_focused_float(swayc_active_workspace());
if (view) {
if (use_width) {
return set_size_floating(view->width + amount, true);
} else {
return set_size_floating(view->height + amount, false);
}
}
return false;
}
static bool resize_tiled(int amount, bool use_width) {
swayc_t *parent = get_focused_view(swayc_active_workspace()); swayc_t *parent = get_focused_view(swayc_active_workspace());
swayc_t *focused = parent; swayc_t *focused = parent;
swayc_t *sibling; swayc_t *sibling;
@ -242,3 +274,65 @@ bool resize_tiled(int amount, bool use_width) {
} }
return true; return true;
} }
static bool set_size_tiled(int amount, bool use_width) {
int desired;
swayc_t *focused = get_focused_view(swayc_active_workspace());
if (use_width) {
desired = amount - focused->width;
} else {
desired = amount - focused->height;
}
return resize_tiled(desired, use_width);
}
bool set_size(int dimension, bool use_width) {
swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());
if (focused) {
if (focused->is_floating) {
return set_size_floating(dimension, use_width);
} else {
return set_size_tiled(dimension, use_width);
}
}
return false;
}
bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) {
swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());
// translate "10 ppt" (10%) to appropriate # of pixels in case we need it
float ppt_dim = (float)dimension / 100;
if (use_width) {
ppt_dim = focused->width * ppt_dim;
} else {
ppt_dim = focused->height * ppt_dim;
}
if (focused) {
if (focused->is_floating) {
// floating view resize dimensions should default to px, so only
// use ppt if specified
if (dim_type == RESIZE_DIM_PPT) {
dimension = (int)ppt_dim;
}
return resize_floating(dimension, use_width);
} else {
// tiled view resize dimensions should default to ppt, so only use
// px if specified
if (dim_type != RESIZE_DIM_PX) {
dimension = (int)ppt_dim;
}
return resize_tiled(dimension, use_width);
}
}
return false;
}

View file

@ -94,13 +94,24 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**(
**reload**:: **reload**::
Reloads the sway config file without restarting sway. Reloads the sway config file without restarting sway.
**resize** <shrink|grow> <width|height> <amount>:: **resize** <shrink|grow> <width|height> [<amount>] [px|ppt]::
Resizes the currently focused container or view by _amount_. _amount_ can be Resizes the currently focused container or view by _amount_. _amount_ is
specified as "n px" or "n ppt" or "n px or n ppt". optional: the default value is 10 (either px or ppt depending on the view
type). The [px|ppt] parameter is optional. _px_ specifies that _amount_ refers
to pixels; _ppt_ specifies that _amount_ refers to percentage points of the
current dimension. Floating views use px dimensions by default (but can use
ppt if specified); tiled views use ppt dimensions by default (but can use px
if specified).
**resize** <width|height> <amount>:: **resize set** <width> [px] <height> [px]::
Sets the _width_ or _height_ of the currently focused container to _amount_. Sets the width and height of the currently focused container to _width_ pixels
_amount_ can be specified as "n px" or "n ppt" or "n px or n ppt". and _height_ pixels. The [px] parameters are optional and have no effect. This
command only accepts pixel dimensions.
**resize set** <width|height> <amount> [px] [<width|height> <amount> [px]]::
Sets the _width_ and/or _height_ of the currently focused container to
_amount_. The [px] parameters are optional and have no effect. This command
only accepts pixel dimensions.
**split** <vertical|v|horizontal|h|toggle|t>:: **split** <vertical|v|horizontal|h|toggle|t>::
Splits the current container, vertically or horizontally. If toggled then the Splits the current container, vertically or horizontally. If toggled then the
@ -200,7 +211,7 @@ The default colors are:
**floating_maximum_size** <width> x <height>:: **floating_maximum_size** <width> x <height>::
Specifies the maximum dimensions of floating windows. Specifies the maximum dimensions of floating windows.
Uses the container dimensions as default. Uses the container dimensions as default.
-1 x -1 will remove any restriction on dimentions. -1 x -1 will remove any restriction on dimensions.
0 x 0 has the same behavior as not setting any value. 0 x 0 has the same behavior as not setting any value.
If in conflict this option has precedence over floating_minimum_size. If in conflict this option has precedence over floating_minimum_size.
@ -214,7 +225,7 @@ The default colors are:
windows, and right click to resize them. Unlike i3, this modifier may also be windows, and right click to resize them. Unlike i3, this modifier may also be
used to resize and move windows that are tiled. With the _inverse_ mode used to resize and move windows that are tiled. With the _inverse_ mode
enabled, left click is used for resizing and right click for dragging. The enabled, left click is used for resizing and right click for dragging. The
mode paramenter is optional and defaults to _normal_ if it isn't defined. mode parameter is optional and defaults to _normal_ if it isn't defined.
**floating_scroll** <up|down|left|right> [command]:: **floating_scroll** <up|down|left|right> [command]::
Sets a command to be executed when the mouse wheel is scrolled in the Sets a command to be executed when the mouse wheel is scrolled in the
@ -263,7 +274,7 @@ The default colors are:
than one child container. than one child container.
**mode** <mode_name>:: **mode** <mode_name>::
Switches to the given mode_name. the default mode is simply _default_. To Switches to the given mode_name. The default mode is simply _default_. To
create a new mode in config append _{_ to this command, the following lines create a new mode in config append _{_ to this command, the following lines
will be keybinds for that mode, and _}_ on its own line to close the block. will be keybinds for that mode, and _}_ on its own line to close the block.