summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-03 12:11:21 -0500
committerLibravatar Zandr Martin <zandrmartin@gmail.com>2016-07-03 12:11:21 -0500
commitd5e4fff34544deda97f9f7d26eb1cb391fcc86bf (patch)
treeb053d7c2e9cc7651991aea1254a6f1f5232aea7c
parentmatch i3 syntax for `resize set` (diff)
downloadsway-d5e4fff34544deda97f9f7d26eb1cb391fcc86bf.tar.gz
sway-d5e4fff34544deda97f9f7d26eb1cb391fcc86bf.tar.zst
sway-d5e4fff34544deda97f9f7d26eb1cb391fcc86bf.zip
resize command updates (#713)
-rw-r--r--include/focus.h4
-rw-r--r--include/resize.h10
-rw-r--r--sway/commands.c105
-rw-r--r--sway/focus.c19
-rw-r--r--sway/resize.c112
-rw-r--r--sway/sway.5.txt31
6 files changed, 229 insertions, 52 deletions
diff --git a/include/focus.h b/include/focus.h
index 10d5182b..9a8458fd 100644
--- a/include/focus.h
+++ b/include/focus.h
@@ -21,6 +21,10 @@ swayc_t *get_focused_container(swayc_t *parent);
21swayc_t *get_focused_view(swayc_t *parent); 21swayc_t *get_focused_view(swayc_t *parent);
22swayc_t *get_focused_float(swayc_t *ws); 22swayc_t *get_focused_float(swayc_t *ws);
23 23
24// a special-case function to get the floating view, regardless
25// of whether it's tiled or floating
26swayc_t *get_focused_view_include_floating(swayc_t *parent);
27
24bool set_focused_container(swayc_t *container); 28bool set_focused_container(swayc_t *container);
25bool set_focused_container_for(swayc_t *ancestor, swayc_t *container); 29bool set_focused_container_for(swayc_t *ancestor, swayc_t *container);
26 30
diff --git a/include/resize.h b/include/resize.h
index d49cc74a..0d382994 100644
--- a/include/resize.h
+++ b/include/resize.h
@@ -2,7 +2,13 @@
2#define _SWAY_RESIZE_H 2#define _SWAY_RESIZE_H
3#include <stdbool.h> 3#include <stdbool.h>
4 4
5bool set_size_tiled(int amount, bool use_width); 5enum resize_dim_types {
6bool resize_tiled(int amount, bool use_width); 6 RESIZE_DIM_PX,
7 RESIZE_DIM_PPT,
8 RESIZE_DIM_DEFAULT,
9};
10
11bool set_size(int dimension, bool use_width);
12bool resize(int dimension, bool use_width, enum resize_dim_types dim_type);
7 13
8#endif 14#endif
diff --git a/sway/commands.c b/sway/commands.c
index 625f8276..2248e1c7 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -2010,31 +2010,41 @@ static struct cmd_results *cmd_resize(int argc, char **argv) {
2010 return error; 2010 return error;
2011 } 2011 }
2012 2012
2013 int amount = (int)strtol(argv[argc - 1], NULL, 10); 2013 int dim_arg = argc - 1;
2014
2015 enum resize_dim_types dim_type = RESIZE_DIM_DEFAULT;
2016 if (strcasecmp(argv[dim_arg], "ppt") == 0) {
2017 dim_type = RESIZE_DIM_PPT;
2018 dim_arg--;
2019 } else if (strcasecmp(argv[dim_arg], "px") == 0) {
2020 dim_type = RESIZE_DIM_PX;
2021 dim_arg--;
2022 }
2023
2024 int amount = (int)strtol(argv[dim_arg], NULL, 10);
2014 if (errno == ERANGE || amount == 0) { 2025 if (errno == ERANGE || amount == 0) {
2015 errno = 0; 2026 errno = 0;
2016 return cmd_results_new(CMD_INVALID, "resize", "Number is out of range."); 2027 amount = 10; // this is the default resize dimension used by i3 for both px and ppt
2028 sway_log(L_DEBUG, "Tried to get resize dimension out of '%s' but failed; setting dimension to default %d",
2029 argv[dim_arg], amount);
2017 } 2030 }
2018 2031
2032 bool use_width = false;
2033 if (strcasecmp(argv[1], "width") == 0) {
2034 use_width = true;
2035 } else if (strcasecmp(argv[1], "height") != 0) {
2036 return cmd_results_new(CMD_INVALID, "resize",
2037 "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
2038 }
2019 2039
2020 if (strcasecmp(argv[0], "shrink") == 0 || strcmp(argv[0], "grow") == 0) { 2040 if (strcasecmp(argv[0], "shrink") == 0) {
2021 if (strcasecmp(argv[0], "shrink") == 0) { 2041 amount *= -1;
2022 amount *= -1; 2042 } else if (strcasecmp(argv[0], "grow") != 0) {
2023 }
2024
2025 if (strcasecmp(argv[1], "width") == 0) {
2026 resize_tiled(amount, true);
2027 } else if (strcmp(argv[1], "height") == 0) {
2028 resize_tiled(amount, false);
2029 } else {
2030 return cmd_results_new(CMD_INVALID, "resize",
2031 "Expected 'resize <shrink|grow> <width|height> <amount>'");
2032 }
2033 } else {
2034 return cmd_results_new(CMD_INVALID, "resize", 2043 return cmd_results_new(CMD_INVALID, "resize",
2035 "Expected 'resize <shrink|grow> <width|height> <amount>'"); 2044 "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
2036 } 2045 }
2037 2046
2047 resize(amount, use_width, dim_type);
2038 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 2048 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
2039} 2049}
2040 2050
@@ -2044,26 +2054,59 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
2044 return error; 2054 return error;
2045 } 2055 }
2046 2056
2047 int cmd_num = 0; 2057 if (strcasecmp(argv[0], "width") == 0 || strcasecmp(argv[0], "height") == 0) {
2048 int amount; 2058 // handle `reset set width 100 px height 100 px` syntax, also allows
2059 // specifying only one dimension for a `resize set`
2060 int cmd_num = 0;
2061 int dim;
2062
2063 while ((cmd_num + 1) < argc) {
2064 dim = (int)strtol(argv[cmd_num + 1], NULL, 10);
2065 if (errno == ERANGE || dim == 0) {
2066 errno = 0;
2067 return cmd_results_new(CMD_INVALID, "resize set",
2068 "Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
2069 }
2070
2071 if (strcasecmp(argv[cmd_num], "width") == 0) {
2072 set_size(dim, true);
2073 } else if (strcasecmp(argv[cmd_num], "height") == 0) {
2074 set_size(dim, false);
2075 } else {
2076 return cmd_results_new(CMD_INVALID, "resize set",
2077 "Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
2078 }
2079
2080 cmd_num += 2;
2049 2081
2050 while (cmd_num < argc) { 2082 if (cmd_num < argc && strcasecmp(argv[cmd_num], "px") == 0) {
2051 amount = (int)strtol(argv[cmd_num + 1], NULL, 10); 2083 // if this was `resize set width 400 px height 300 px`, disregard the `px` arg
2052 if (errno == ERANGE || amount == 0) { 2084 cmd_num++;
2085 }
2086 }
2087 } else {
2088 // handle `reset set 100 px 100 px` syntax
2089 int width = (int)strtol(argv[0], NULL, 10);
2090 if (errno == ERANGE || width == 0) {
2053 errno = 0; 2091 errno = 0;
2054 return cmd_results_new(CMD_INVALID, "resize set", "Number is out of range."); 2092 return cmd_results_new(CMD_INVALID, "resize set",
2093 "Expected 'resize set <width> [px] <height> [px]'");
2055 } 2094 }
2056 2095
2057 if (strcasecmp(argv[cmd_num], "width") == 0) { 2096 int height_arg = 1;
2058 set_size_tiled(amount, true); 2097 if (strcasecmp(argv[1], "px") == 0) {
2059 } else if (strcasecmp(argv[cmd_num], "height") == 0) { 2098 height_arg = 2;
2060 set_size_tiled(amount, false); 2099 }
2061 } else { 2100
2062 return cmd_results_new(CMD_INVALID, "resize", 2101 int height = (int)strtol(argv[height_arg], NULL, 10);
2063 "Expected 'resize set <width|height> <amount> [<width|height> <amount>]'"); 2102 if (errno == ERANGE || height == 0) {
2103 errno = 0;
2104 return cmd_results_new(CMD_INVALID, "resize set",
2105 "Expected 'resize set <width> [px] <height> [px]'");
2064 } 2106 }
2065 2107
2066 cmd_num += 2; 2108 set_size(width, true);
2109 set_size(height, false);
2067 } 2110 }
2068 2111
2069 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 2112 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/focus.c b/sway/focus.c
index 2219ab4a..1d21ac35 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -243,3 +243,22 @@ swayc_t *get_focused_float(swayc_t *ws) {
243 } 243 }
244 return NULL; 244 return NULL;
245} 245}
246
247swayc_t *get_focused_view_include_floating(swayc_t *parent) {
248 swayc_t *c = parent;
249 swayc_t *f = NULL;
250
251 while (c && c->type != C_VIEW) {
252 if (c->type == C_WORKSPACE && c->focused == NULL) {
253 return ((f = get_focused_float(c))) ? f : c;
254 }
255
256 c = c->focused;
257 }
258
259 if (c == NULL) {
260 c = swayc_active_workspace_for(parent);
261 }
262
263 return c;
264}
diff --git a/sway/resize.c b/sway/resize.c
index 9411cfd8..18bb86bb 100644
--- a/sway/resize.c
+++ b/sway/resize.c
@@ -7,20 +7,52 @@
7#include "handlers.h" 7#include "handlers.h"
8#include "resize.h" 8#include "resize.h"
9 9
10bool set_size_tiled(int amount, bool use_width) { 10static bool set_size_floating(int new_dimension, bool use_width) {
11 int desired; 11 swayc_t *view = get_focused_float(swayc_active_workspace());
12 swayc_t *focused = get_focused_view(swayc_active_workspace()); 12 if (view) {
13 if (use_width) {
14 int current_width = view->width;
15 view->desired_width = new_dimension;
16 floating_view_sane_size(view);
13 17
14 if (use_width) { 18 int new_x = view->x + (int)(((view->desired_width - current_width) / 2) * -1);
15 desired = amount - focused->width; 19 view->width = view->desired_width;
16 } else { 20 view->x = new_x;
17 desired = amount - focused->height; 21
22 update_geometry(view);
23 } else {
24 int current_height = view->height;
25 view->desired_height = new_dimension;
26 floating_view_sane_size(view);
27
28 int new_y = view->y + (int)(((view->desired_height - current_height) / 2) * -1);
29 view->height = view->desired_height;
30 view->y = new_y;
31
32 update_geometry(view);
33 }
34
35 return true;
18 } 36 }
19 37
20 return resize_tiled(desired, use_width); 38 return false;
21} 39}
22 40
23bool resize_tiled(int amount, bool use_width) { 41static bool resize_floating(int amount, bool use_width) {
42 swayc_t *view = get_focused_float(swayc_active_workspace());
43
44 if (view) {
45 if (use_width) {
46 return set_size_floating(view->width + amount, true);
47 } else {
48 return set_size_floating(view->height + amount, false);
49 }
50 }
51
52 return false;
53}
54
55static bool resize_tiled(int amount, bool use_width) {
24 swayc_t *parent = get_focused_view(swayc_active_workspace()); 56 swayc_t *parent = get_focused_view(swayc_active_workspace());
25 swayc_t *focused = parent; 57 swayc_t *focused = parent;
26 swayc_t *sibling; 58 swayc_t *sibling;
@@ -242,3 +274,65 @@ bool resize_tiled(int amount, bool use_width) {
242 } 274 }
243 return true; 275 return true;
244} 276}
277
278static bool set_size_tiled(int amount, bool use_width) {
279 int desired;
280 swayc_t *focused = get_focused_view(swayc_active_workspace());
281
282 if (use_width) {
283 desired = amount - focused->width;
284 } else {
285 desired = amount - focused->height;
286 }
287
288 return resize_tiled(desired, use_width);
289}
290
291bool set_size(int dimension, bool use_width) {
292 swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());
293
294 if (focused) {
295 if (focused->is_floating) {
296 return set_size_floating(dimension, use_width);
297 } else {
298 return set_size_tiled(dimension, use_width);
299 }
300 }
301
302 return false;
303}
304
305bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) {
306 swayc_t *focused = get_focused_view_include_floating(swayc_active_workspace());
307
308 // translate "10 ppt" (10%) to appropriate # of pixels in case we need it
309 float ppt_dim = (float)dimension / 100;
310
311 if (use_width) {
312 ppt_dim = focused->width * ppt_dim;
313 } else {
314 ppt_dim = focused->height * ppt_dim;
315 }
316
317 if (focused) {
318 if (focused->is_floating) {
319 // floating view resize dimensions should default to px, so only
320 // use ppt if specified
321 if (dim_type == RESIZE_DIM_PPT) {
322 dimension = (int)ppt_dim;
323 }
324
325 return resize_floating(dimension, use_width);
326 } else {
327 // tiled view resize dimensions should default to ppt, so only use
328 // px if specified
329 if (dim_type != RESIZE_DIM_PX) {
330 dimension = (int)ppt_dim;
331 }
332
333 return resize_tiled(dimension, use_width);
334 }
335 }
336
337 return false;
338}
diff --git a/sway/sway.5.txt b/sway/sway.5.txt
index 76d09edb..18b693f8 100644
--- a/sway/sway.5.txt
+++ b/sway/sway.5.txt
@@ -94,13 +94,24 @@ They are expected to be used with **bindsym** or at runtime through **swaymsg**(
94**reload**:: 94**reload**::
95 Reloads the sway config file without restarting sway. 95 Reloads the sway config file without restarting sway.
96 96
97**resize** <shrink|grow> <width|height> <amount>:: 97**resize** <shrink|grow> <width|height> [<amount>] [px|ppt]::
98 Resizes the currently focused container or view by _amount_. _amount_ can be 98 Resizes the currently focused container or view by _amount_. _amount_ is
99 specified as "n px" or "n ppt" or "n px or n ppt". 99 optional: the default value is 10 (either px or ppt depending on the view
100 100 type). The [px|ppt] parameter is optional. _px_ specifies that _amount_ refers
101**resize** <width|height> <amount>:: 101 to pixels; _ppt_ specifies that _amount_ refers to percentage points of the
102 Sets the _width_ or _height_ of the currently focused container to _amount_. 102 current dimension. Floating views use px dimensions by default (but can use
103 _amount_ can be specified as "n px" or "n ppt" or "n px or n ppt". 103 ppt if specified); tiled views use ppt dimensions by default (but can use px
104 if specified).
105
106**resize set** <width> [px] <height> [px]::
107 Sets the width and height of the currently focused container to _width_ pixels
108 and _height_ pixels. The [px] parameters are optional and have no effect. This
109 command only accepts pixel dimensions.
110
111**resize set** <width|height> <amount> [px] [<width|height> <amount> [px]]::
112 Sets the _width_ and/or _height_ of the currently focused container to
113 _amount_. The [px] parameters are optional and have no effect. This command
114 only accepts pixel dimensions.
104 115
105**split** <vertical|v|horizontal|h|toggle|t>:: 116**split** <vertical|v|horizontal|h|toggle|t>::
106 Splits the current container, vertically or horizontally. If toggled then the 117 Splits the current container, vertically or horizontally. If toggled then the
@@ -200,7 +211,7 @@ The default colors are:
200**floating_maximum_size** <width> x <height>:: 211**floating_maximum_size** <width> x <height>::
201 Specifies the maximum dimensions of floating windows. 212 Specifies the maximum dimensions of floating windows.
202 Uses the container dimensions as default. 213 Uses the container dimensions as default.
203 -1 x -1 will remove any restriction on dimentions. 214 -1 x -1 will remove any restriction on dimensions.
204 0 x 0 has the same behavior as not setting any value. 215 0 x 0 has the same behavior as not setting any value.
205 If in conflict this option has precedence over floating_minimum_size. 216 If in conflict this option has precedence over floating_minimum_size.
206 217
@@ -214,7 +225,7 @@ The default colors are:
214 windows, and right click to resize them. Unlike i3, this modifier may also be 225 windows, and right click to resize them. Unlike i3, this modifier may also be
215 used to resize and move windows that are tiled. With the _inverse_ mode 226 used to resize and move windows that are tiled. With the _inverse_ mode
216 enabled, left click is used for resizing and right click for dragging. The 227 enabled, left click is used for resizing and right click for dragging. The
217 mode paramenter is optional and defaults to _normal_ if it isn't defined. 228 mode parameter is optional and defaults to _normal_ if it isn't defined.
218 229
219**floating_scroll** <up|down|left|right> [command]:: 230**floating_scroll** <up|down|left|right> [command]::
220 Sets a command to be executed when the mouse wheel is scrolled in the 231 Sets a command to be executed when the mouse wheel is scrolled in the
@@ -263,7 +274,7 @@ The default colors are:
263 than one child container. 274 than one child container.
264 275
265**mode** <mode_name>:: 276**mode** <mode_name>::
266 Switches to the given mode_name. the default mode is simply _default_. To 277 Switches to the given mode_name. The default mode is simply _default_. To
267 create a new mode in config append _{_ to this command, the following lines 278 create a new mode in config append _{_ to this command, the following lines
268 will be keybinds for that mode, and _}_ on its own line to close the block. 279 will be keybinds for that mode, and _}_ on its own line to close the block.
269 280