aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/focus.h4
-rw-r--r--include/resize.h10
-rw-r--r--sway/commands.c115
-rw-r--r--sway/focus.c19
-rw-r--r--sway/resize.c112
-rw-r--r--sway/sway.5.txt31
6 files changed, 251 insertions, 40 deletions
diff --git a/include/focus.h b/include/focus.h
index 10d5182b..4abd6080 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 focused 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 55f46f79..2248e1c7 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -83,6 +83,7 @@ static sway_cmd cmd_orientation;
83static sway_cmd cmd_output; 83static sway_cmd cmd_output;
84static sway_cmd cmd_reload; 84static sway_cmd cmd_reload;
85static sway_cmd cmd_resize; 85static sway_cmd cmd_resize;
86static sway_cmd cmd_resize_set;
86static sway_cmd cmd_scratchpad; 87static sway_cmd cmd_scratchpad;
87static sway_cmd cmd_set; 88static sway_cmd cmd_set;
88static sway_cmd cmd_smart_gaps; 89static sway_cmd cmd_smart_gaps;
@@ -2000,36 +2001,112 @@ static struct cmd_results *cmd_resize(int argc, char **argv) {
2000 struct cmd_results *error = NULL; 2001 struct cmd_results *error = NULL;
2001 if (config->reading) return cmd_results_new(CMD_FAILURE, "resize", "Can't be used in config file."); 2002 if (config->reading) return cmd_results_new(CMD_FAILURE, "resize", "Can't be used in config file.");
2002 if (!config->active) return cmd_results_new(CMD_FAILURE, "resize", "Can only be used when sway is running."); 2003 if (!config->active) return cmd_results_new(CMD_FAILURE, "resize", "Can only be used when sway is running.");
2004
2005 if (strcasecmp(argv[0], "set") == 0) {
2006 return cmd_resize_set(argc - 1, &argv[1]);
2007 }
2008
2003 if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { 2009 if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) {
2004 return error; 2010 return error;
2005 } 2011 }
2006 2012
2007 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);
2008 if (errno == ERANGE || amount == 0) { 2025 if (errno == ERANGE || amount == 0) {
2009 errno = 0; 2026 errno = 0;
2010 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);
2011 } 2030 }
2012 2031
2013 if (strcmp(argv[0], "shrink") == 0 || strcmp(argv[0], "grow") == 0) { 2032 bool use_width = false;
2014 if (strcmp(argv[0], "shrink") == 0) { 2033 if (strcasecmp(argv[1], "width") == 0) {
2015 amount *= -1; 2034 use_width = true;
2016 } 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 }
2017 2039
2018 if (strcmp(argv[1], "width") == 0) { 2040 if (strcasecmp(argv[0], "shrink") == 0) {
2019 resize_tiled(amount, true); 2041 amount *= -1;
2020 } else if (strcmp(argv[1], "height") == 0) { 2042 } else if (strcasecmp(argv[0], "grow") != 0) {
2021 resize_tiled(amount, false); 2043 return cmd_results_new(CMD_INVALID, "resize",
2022 } else { 2044 "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
2023 return cmd_results_new(CMD_INVALID, "resize", 2045 }
2024 "Expected 'resize <shrink|grow> <width|height> <amount>' or 'resize <width|height> <amount>'"); 2046
2047 resize(amount, use_width, dim_type);
2048 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
2049}
2050
2051static struct cmd_results *cmd_resize_set(int argc, char **argv) {
2052 struct cmd_results *error = NULL;
2053 if ((error = checkarg(argc, "resize set", EXPECTED_AT_LEAST, 2))) {
2054 return error;
2055 }
2056
2057 if (strcasecmp(argv[0], "width") == 0 || strcasecmp(argv[0], "height") == 0) {
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;
2081
2082 if (cmd_num < argc && strcasecmp(argv[cmd_num], "px") == 0) {
2083 // if this was `resize set width 400 px height 300 px`, disregard the `px` arg
2084 cmd_num++;
2085 }
2025 } 2086 }
2026 } else if (strcmp(argv[0], "width") == 0) {
2027 set_size_tiled(amount, true);
2028 } else if (strcmp(argv[0], "height") == 0) {
2029 set_size_tiled(amount, false);
2030 } else { 2087 } else {
2031 return cmd_results_new(CMD_INVALID, "resize", 2088 // handle `reset set 100 px 100 px` syntax
2032 "Expected 'resize <shrink|grow> <width|height> <amount>' or 'resize <width|height> <amount>'"); 2089 int width = (int)strtol(argv[0], NULL, 10);
2090 if (errno == ERANGE || width == 0) {
2091 errno = 0;
2092 return cmd_results_new(CMD_INVALID, "resize set",
2093 "Expected 'resize set <width> [px] <height> [px]'");
2094 }
2095
2096 int height_arg = 1;
2097 if (strcasecmp(argv[1], "px") == 0) {
2098 height_arg = 2;
2099 }
2100
2101 int height = (int)strtol(argv[height_arg], NULL, 10);
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]'");
2106 }
2107
2108 set_size(width, true);
2109 set_size(height, false);
2033 } 2110 }
2034 2111
2035 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