diff options
-rw-r--r-- | sway/commands/resize.c | 406 |
1 files changed, 351 insertions, 55 deletions
diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 5efbd8b0..2cf811d8 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <limits.h> | ||
2 | #include <math.h> | 3 | #include <math.h> |
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
4 | #include <stdlib.h> | 5 | #include <stdlib.h> |
@@ -7,6 +8,7 @@ | |||
7 | #include <wlr/util/log.h> | 8 | #include <wlr/util/log.h> |
8 | #include "sway/commands.h" | 9 | #include "sway/commands.h" |
9 | #include "sway/tree/arrange.h" | 10 | #include "sway/tree/arrange.h" |
11 | #include "sway/tree/view.h" | ||
10 | #include "log.h" | 12 | #include "log.h" |
11 | 13 | ||
12 | static const int MIN_SANE_W = 100, MIN_SANE_H = 60; | 14 | static const int MIN_SANE_W = 100, MIN_SANE_H = 60; |
@@ -21,9 +23,18 @@ enum resize_unit { | |||
21 | enum resize_axis { | 23 | enum resize_axis { |
22 | RESIZE_AXIS_HORIZONTAL, | 24 | RESIZE_AXIS_HORIZONTAL, |
23 | RESIZE_AXIS_VERTICAL, | 25 | RESIZE_AXIS_VERTICAL, |
26 | RESIZE_AXIS_UP, | ||
27 | RESIZE_AXIS_DOWN, | ||
28 | RESIZE_AXIS_LEFT, | ||
29 | RESIZE_AXIS_RIGHT, | ||
24 | RESIZE_AXIS_INVALID, | 30 | RESIZE_AXIS_INVALID, |
25 | }; | 31 | }; |
26 | 32 | ||
33 | struct resize_amount { | ||
34 | int amount; | ||
35 | enum resize_unit unit; | ||
36 | }; | ||
37 | |||
27 | static enum resize_unit parse_resize_unit(const char *unit) { | 38 | static enum resize_unit parse_resize_unit(const char *unit) { |
28 | if (strcasecmp(unit, "px") == 0) { | 39 | if (strcasecmp(unit, "px") == 0) { |
29 | return RESIZE_UNIT_PX; | 40 | return RESIZE_UNIT_PX; |
@@ -37,6 +48,69 @@ static enum resize_unit parse_resize_unit(const char *unit) { | |||
37 | return RESIZE_UNIT_INVALID; | 48 | return RESIZE_UNIT_INVALID; |
38 | } | 49 | } |
39 | 50 | ||
51 | // Parse arguments such as "10", "10px" or "10 px". | ||
52 | // Returns the number of arguments consumed. | ||
53 | static int parse_resize_amount(int argc, char **argv, | ||
54 | struct resize_amount *amount) { | ||
55 | char *err; | ||
56 | amount->amount = (int)strtol(argv[0], &err, 10); | ||
57 | if (*err) { | ||
58 | // e.g. 10px | ||
59 | amount->unit = parse_resize_unit(err); | ||
60 | return 1; | ||
61 | } | ||
62 | if (argc == 1) { | ||
63 | amount->unit = RESIZE_UNIT_DEFAULT; | ||
64 | return 1; | ||
65 | } | ||
66 | // Try the second argument | ||
67 | amount->unit = parse_resize_unit(argv[1]); | ||
68 | if (amount->unit == RESIZE_UNIT_INVALID) { | ||
69 | amount->unit = RESIZE_UNIT_DEFAULT; | ||
70 | return 1; | ||
71 | } | ||
72 | return 2; | ||
73 | } | ||
74 | |||
75 | static void calculate_constraints(int *min_width, int *max_width, | ||
76 | int *min_height, int *max_height) { | ||
77 | struct sway_container *con = config->handler_context.current_container; | ||
78 | |||
79 | if (config->floating_minimum_width == -1) { // no minimum | ||
80 | *min_width = 0; | ||
81 | } else if (config->floating_minimum_width == 0) { // automatic | ||
82 | *min_width = 75; | ||
83 | } else { | ||
84 | *min_width = config->floating_minimum_width; | ||
85 | } | ||
86 | |||
87 | if (config->floating_minimum_height == -1) { // no minimum | ||
88 | *min_height = 0; | ||
89 | } else if (config->floating_minimum_height == 0) { // automatic | ||
90 | *min_height = 50; | ||
91 | } else { | ||
92 | *min_height = config->floating_minimum_height; | ||
93 | } | ||
94 | |||
95 | if (config->floating_maximum_width == -1) { // no maximum | ||
96 | *max_width = INT_MAX; | ||
97 | } else if (config->floating_maximum_width == 0) { // automatic | ||
98 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | ||
99 | *max_width = ws->width; | ||
100 | } else { | ||
101 | *max_width = config->floating_maximum_width; | ||
102 | } | ||
103 | |||
104 | if (config->floating_maximum_height == -1) { // no maximum | ||
105 | *max_height = INT_MAX; | ||
106 | } else if (config->floating_maximum_height == 0) { // automatic | ||
107 | struct sway_container *ws = container_parent(con, C_WORKSPACE); | ||
108 | *max_height = ws->height; | ||
109 | } else { | ||
110 | *max_height = config->floating_maximum_height; | ||
111 | } | ||
112 | } | ||
113 | |||
40 | static enum resize_axis parse_resize_axis(const char *axis) { | 114 | static enum resize_axis parse_resize_axis(const char *axis) { |
41 | if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { | 115 | if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { |
42 | return RESIZE_AXIS_HORIZONTAL; | 116 | return RESIZE_AXIS_HORIZONTAL; |
@@ -44,6 +118,18 @@ static enum resize_axis parse_resize_axis(const char *axis) { | |||
44 | if (strcasecmp(axis, "height") == 0 || strcasecmp(axis, "vertical") == 0) { | 118 | if (strcasecmp(axis, "height") == 0 || strcasecmp(axis, "vertical") == 0) { |
45 | return RESIZE_AXIS_VERTICAL; | 119 | return RESIZE_AXIS_VERTICAL; |
46 | } | 120 | } |
121 | if (strcasecmp(axis, "up") == 0) { | ||
122 | return RESIZE_AXIS_UP; | ||
123 | } | ||
124 | if (strcasecmp(axis, "down") == 0) { | ||
125 | return RESIZE_AXIS_DOWN; | ||
126 | } | ||
127 | if (strcasecmp(axis, "left") == 0) { | ||
128 | return RESIZE_AXIS_LEFT; | ||
129 | } | ||
130 | if (strcasecmp(axis, "right") == 0) { | ||
131 | return RESIZE_AXIS_RIGHT; | ||
132 | } | ||
47 | return RESIZE_AXIS_INVALID; | 133 | return RESIZE_AXIS_INVALID; |
48 | } | 134 | } |
49 | 135 | ||
@@ -185,102 +271,312 @@ static void resize_tiled(int amount, enum resize_axis axis) { | |||
185 | arrange_and_commit(parent->parent); | 271 | arrange_and_commit(parent->parent); |
186 | } | 272 | } |
187 | 273 | ||
188 | static void resize(int amount, enum resize_axis axis, enum resize_unit unit) { | 274 | /** |
189 | struct sway_container *current = config->handler_context.current_container; | 275 | * Implement `resize <grow|shrink>` for a floating container. |
190 | if (unit == RESIZE_UNIT_DEFAULT) { | 276 | */ |
191 | // Default for tiling; TODO floating should be px | 277 | static struct cmd_results *resize_adjust_floating(enum resize_axis axis, |
192 | unit = RESIZE_UNIT_PPT; | 278 | struct resize_amount *amount) { |
279 | struct sway_container *con = config->handler_context.current_container; | ||
280 | int grow_width = 0, grow_height = 0; | ||
281 | switch (axis) { | ||
282 | case RESIZE_AXIS_HORIZONTAL: | ||
283 | case RESIZE_AXIS_LEFT: | ||
284 | case RESIZE_AXIS_RIGHT: | ||
285 | grow_width = amount->amount; | ||
286 | break; | ||
287 | case RESIZE_AXIS_VERTICAL: | ||
288 | case RESIZE_AXIS_UP: | ||
289 | case RESIZE_AXIS_DOWN: | ||
290 | grow_height = amount->amount; | ||
291 | break; | ||
292 | case RESIZE_AXIS_INVALID: | ||
293 | return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction"); | ||
294 | } | ||
295 | // Make sure we're not adjusting beyond floating min/max size | ||
296 | int min_width, max_width, min_height, max_height; | ||
297 | calculate_constraints(&min_width, &max_width, &min_height, &max_height); | ||
298 | if (con->width + grow_width < min_width) { | ||
299 | grow_width = min_width - con->width; | ||
300 | } else if (con->width + grow_width > max_width) { | ||
301 | grow_width = max_width - con->width; | ||
193 | } | 302 | } |
303 | if (con->height + grow_height < min_height) { | ||
304 | grow_height = min_height - con->height; | ||
305 | } else if (con->height + grow_height > max_height) { | ||
306 | grow_height = max_height - con->height; | ||
307 | } | ||
308 | int grow_x = 0, grow_y = 0; | ||
309 | switch (axis) { | ||
310 | case RESIZE_AXIS_HORIZONTAL: | ||
311 | grow_x = -grow_width / 2; | ||
312 | break; | ||
313 | case RESIZE_AXIS_VERTICAL: | ||
314 | grow_y = -grow_height / 2; | ||
315 | break; | ||
316 | case RESIZE_AXIS_UP: | ||
317 | grow_y = -grow_height; | ||
318 | break; | ||
319 | case RESIZE_AXIS_LEFT: | ||
320 | grow_x = -grow_width; | ||
321 | break; | ||
322 | case RESIZE_AXIS_DOWN: | ||
323 | case RESIZE_AXIS_RIGHT: | ||
324 | break; | ||
325 | case RESIZE_AXIS_INVALID: | ||
326 | return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction"); | ||
327 | } | ||
328 | con->x += grow_x; | ||
329 | con->y += grow_y; | ||
330 | con->width += grow_width; | ||
331 | con->height += grow_height; | ||
332 | |||
333 | if (con->type == C_VIEW) { | ||
334 | struct sway_view *view = con->sway_view; | ||
335 | view->x += grow_x; | ||
336 | view->y += grow_y; | ||
337 | view->width += grow_width; | ||
338 | view->height += grow_height; | ||
339 | } | ||
340 | |||
341 | arrange_and_commit(con); | ||
342 | |||
343 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
344 | } | ||
194 | 345 | ||
195 | if (unit == RESIZE_UNIT_PPT) { | 346 | /** |
196 | float pct = amount / 100.0f; | 347 | * Implement `resize <grow|shrink>` for a tiled container. |
348 | */ | ||
349 | static struct cmd_results *resize_adjust_tiled(enum resize_axis axis, | ||
350 | struct resize_amount *amount) { | ||
351 | struct sway_container *current = config->handler_context.current_container; | ||
352 | |||
353 | if (amount->unit == RESIZE_UNIT_DEFAULT) { | ||
354 | amount->unit = RESIZE_UNIT_PPT; | ||
355 | } | ||
356 | if (amount->unit == RESIZE_UNIT_PPT) { | ||
357 | float pct = amount->amount / 100.0f; | ||
358 | // TODO: Make left/right/up/down resize in that direction? | ||
197 | switch (axis) { | 359 | switch (axis) { |
360 | case RESIZE_AXIS_LEFT: | ||
361 | case RESIZE_AXIS_RIGHT: | ||
198 | case RESIZE_AXIS_HORIZONTAL: | 362 | case RESIZE_AXIS_HORIZONTAL: |
199 | amount = (float)current->width * pct; | 363 | amount->amount = (float)current->width * pct; |
200 | break; | 364 | break; |
365 | case RESIZE_AXIS_UP: | ||
366 | case RESIZE_AXIS_DOWN: | ||
201 | case RESIZE_AXIS_VERTICAL: | 367 | case RESIZE_AXIS_VERTICAL: |
202 | amount = (float)current->height * pct; | 368 | amount->amount = (float)current->height * pct; |
203 | break; | 369 | break; |
204 | default: | 370 | case RESIZE_AXIS_INVALID: |
205 | sway_assert(0, "invalid resize axis"); | 371 | return cmd_results_new(CMD_INVALID, "resize", |
206 | return; | 372 | "Invalid resize axis/direction"); |
207 | } | 373 | } |
208 | } | 374 | } |
209 | 375 | ||
210 | return resize_tiled(amount, axis); | 376 | resize_tiled(amount->amount, axis); |
377 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
211 | } | 378 | } |
212 | 379 | ||
213 | struct cmd_results *cmd_resize(int argc, char **argv) { | 380 | /** |
214 | struct sway_container *current = config->handler_context.current_container; | 381 | * Implement `resize set` for a tiled container. |
215 | if (!current) { | 382 | */ |
216 | return cmd_results_new(CMD_INVALID, "resize", "Cannot resize nothing"); | 383 | static struct cmd_results *resize_set_tiled(struct sway_container *con, |
217 | } | 384 | struct resize_amount *width, struct resize_amount *height) { |
218 | if (current->type != C_VIEW && current->type != C_CONTAINER) { | 385 | return cmd_results_new(CMD_INVALID, "resize", |
219 | return cmd_results_new(CMD_INVALID, "resize", | 386 | "'resize set' is not implemented for tiled views"); |
220 | "Can only resize views/containers"); | 387 | } |
388 | |||
389 | /** | ||
390 | * Implement `resize set` for a floating container. | ||
391 | */ | ||
392 | static struct cmd_results *resize_set_floating(struct sway_container *con, | ||
393 | struct resize_amount *width, struct resize_amount *height) { | ||
394 | int min_width, max_width, min_height, max_height; | ||
395 | calculate_constraints(&min_width, &max_width, &min_height, &max_height); | ||
396 | width->amount = fmax(min_width, fmin(width->amount, max_width)); | ||
397 | height->amount = fmax(min_height, fmin(height->amount, max_height)); | ||
398 | int grow_width = width->amount - con->width; | ||
399 | int grow_height = height->amount - con->height; | ||
400 | con->x -= grow_width / 2; | ||
401 | con->y -= grow_height / 2; | ||
402 | con->width = width->amount; | ||
403 | con->height = height->amount; | ||
404 | |||
405 | if (con->type == C_VIEW) { | ||
406 | struct sway_view *view = con->sway_view; | ||
407 | view->x -= grow_width / 2; | ||
408 | view->y -= grow_height / 2; | ||
409 | view->width += grow_width; | ||
410 | view->height += grow_height; | ||
221 | } | 411 | } |
222 | 412 | ||
413 | arrange_and_commit(con); | ||
414 | |||
415 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
416 | } | ||
417 | |||
418 | /** | ||
419 | * resize set <args> | ||
420 | * | ||
421 | * args: <width> [px|ppt] <height> [px|ppt] | ||
422 | */ | ||
423 | static struct cmd_results *cmd_resize_set(int argc, char **argv) { | ||
223 | struct cmd_results *error; | 424 | struct cmd_results *error; |
224 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { | 425 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { |
225 | return error; | 426 | return error; |
226 | } | 427 | } |
227 | 428 | const char *usage = "Expected 'resize set <width> <height>'"; | |
228 | if (strcasecmp(argv[0], "set") == 0) { | 429 | |
229 | // TODO | 430 | // Width |
230 | //return cmd_resize_set(argc - 1, &argv[1]); | 431 | struct resize_amount width; |
231 | return cmd_results_new(CMD_INVALID, "resize", "resize set unimplemented"); | 432 | int num_consumed_args = parse_resize_amount(argc, argv, &width); |
433 | argc -= num_consumed_args; | ||
434 | argv += num_consumed_args; | ||
435 | if (width.unit == RESIZE_UNIT_INVALID) { | ||
436 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
437 | } | ||
438 | if (!argc) { | ||
439 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
232 | } | 440 | } |
233 | 441 | ||
234 | // TODO: resize grow|shrink left|right|up|down | 442 | // Height |
443 | struct resize_amount height; | ||
444 | num_consumed_args = parse_resize_amount(argc, argv, &height); | ||
445 | argc -= num_consumed_args; | ||
446 | argv += num_consumed_args; | ||
447 | if (height.unit == RESIZE_UNIT_INVALID) { | ||
448 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
449 | } | ||
235 | 450 | ||
236 | const char *usage = "Expected 'resize <shrink|grow> " | 451 | // If 0, don't resize that dimension |
237 | "<width|height> [<amount>] [px|ppt]'"; | 452 | struct sway_container *con = config->handler_context.current_container; |
453 | if (width.amount <= 0) { | ||
454 | width.amount = con->width; | ||
455 | } | ||
456 | if (height.amount <= 0) { | ||
457 | height.amount = con->height; | ||
458 | } | ||
238 | 459 | ||
239 | int multiplier = 0; | 460 | if (container_is_floating(con)) { |
240 | if (strcasecmp(*argv, "grow") == 0) { | 461 | return resize_set_floating(con, &width, &height); |
241 | multiplier = 1; | ||
242 | } else if (strcasecmp(*argv, "shrink") == 0) { | ||
243 | multiplier = -1; | ||
244 | } else { | ||
245 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
246 | } | 462 | } |
247 | --argc; ++argv; | 463 | return resize_set_tiled(con, &width, &height); |
464 | } | ||
248 | 465 | ||
466 | /** | ||
467 | * resize <grow|shrink> <args> | ||
468 | * | ||
469 | * args: <direction> | ||
470 | * args: <direction> <amount> <unit> | ||
471 | * args: <direction> <amount> <unit> or <amount> <other_unit> | ||
472 | */ | ||
473 | static struct cmd_results *cmd_resize_adjust(int argc, char **argv, | ||
474 | int multiplier) { | ||
475 | const char *usage = "Expected 'resize grow|shrink <direction> " | ||
476 | "[<amount> px|ppt [or <amount> px|ppt]]'"; | ||
249 | enum resize_axis axis = parse_resize_axis(*argv); | 477 | enum resize_axis axis = parse_resize_axis(*argv); |
250 | if (axis == RESIZE_AXIS_INVALID) { | 478 | if (axis == RESIZE_AXIS_INVALID) { |
251 | return cmd_results_new(CMD_INVALID, "resize", usage); | 479 | return cmd_results_new(CMD_INVALID, "resize", usage); |
252 | } | 480 | } |
253 | --argc; ++argv; | 481 | --argc; ++argv; |
254 | 482 | ||
255 | int amount = 10; // Default amount | 483 | // First amount |
256 | enum resize_unit unit = RESIZE_UNIT_DEFAULT; | 484 | struct resize_amount first_amount; |
257 | |||
258 | if (argc) { | 485 | if (argc) { |
259 | char *err; | 486 | int num_consumed_args = parse_resize_amount(argc, argv, &first_amount); |
260 | amount = (int)strtol(*argv, &err, 10); | 487 | argc -= num_consumed_args; |
261 | if (*err) { | 488 | argv += num_consumed_args; |
262 | // e.g. `resize grow width 10px` | 489 | if (first_amount.unit == RESIZE_UNIT_INVALID) { |
263 | unit = parse_resize_unit(err); | 490 | return cmd_results_new(CMD_INVALID, "resize", usage); |
264 | if (unit == RESIZE_UNIT_INVALID) { | ||
265 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
266 | } | ||
267 | } | 491 | } |
268 | --argc; ++argv; | 492 | } else { |
493 | first_amount.amount = 10; | ||
494 | first_amount.unit = RESIZE_UNIT_DEFAULT; | ||
269 | } | 495 | } |
270 | 496 | ||
497 | // "or" | ||
271 | if (argc) { | 498 | if (argc) { |
272 | unit = parse_resize_unit(*argv); | 499 | if (strcmp(*argv, "or") != 0) { |
273 | if (unit == RESIZE_UNIT_INVALID) { | ||
274 | return cmd_results_new(CMD_INVALID, "resize", usage); | 500 | return cmd_results_new(CMD_INVALID, "resize", usage); |
275 | } | 501 | } |
276 | --argc; ++argv; | 502 | --argc; ++argv; |
277 | } | 503 | } |
278 | 504 | ||
505 | // Second amount | ||
506 | struct resize_amount second_amount; | ||
279 | if (argc) { | 507 | if (argc) { |
280 | // Provied too many args, the bastard | 508 | int num_consumed_args = parse_resize_amount(argc, argv, &second_amount); |
281 | return cmd_results_new(CMD_INVALID, "resize", usage); | 509 | argc -= num_consumed_args; |
510 | argv += num_consumed_args; | ||
511 | if (second_amount.unit == RESIZE_UNIT_INVALID) { | ||
512 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
513 | } | ||
514 | } else { | ||
515 | second_amount.unit = RESIZE_UNIT_INVALID; | ||
282 | } | 516 | } |
283 | 517 | ||
284 | resize(amount * multiplier, axis, unit); | 518 | first_amount.amount *= multiplier; |
285 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 519 | second_amount.amount *= multiplier; |
520 | |||
521 | struct sway_container *con = config->handler_context.current_container; | ||
522 | if (container_is_floating(con)) { | ||
523 | // Floating containers can only resize in px. Choose an amount which | ||
524 | // uses px, with fallback to an amount that specified no unit. | ||
525 | if (first_amount.unit == RESIZE_UNIT_PX) { | ||
526 | return resize_adjust_floating(axis, &first_amount); | ||
527 | } else if (second_amount.unit == RESIZE_UNIT_PX) { | ||
528 | return resize_adjust_floating(axis, &second_amount); | ||
529 | } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
530 | return resize_adjust_floating(axis, &first_amount); | ||
531 | } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
532 | return resize_adjust_floating(axis, &second_amount); | ||
533 | } else { | ||
534 | return cmd_results_new(CMD_INVALID, "resize", | ||
535 | "Floating containers cannot use ppt measurements"); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | // For tiling, prefer ppt -> default -> px | ||
540 | if (first_amount.unit == RESIZE_UNIT_PPT) { | ||
541 | return resize_adjust_tiled(axis, &first_amount); | ||
542 | } else if (second_amount.unit == RESIZE_UNIT_PPT) { | ||
543 | return resize_adjust_tiled(axis, &second_amount); | ||
544 | } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
545 | return resize_adjust_tiled(axis, &first_amount); | ||
546 | } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { | ||
547 | return resize_adjust_tiled(axis, &second_amount); | ||
548 | } else { | ||
549 | return resize_adjust_tiled(axis, &first_amount); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | struct cmd_results *cmd_resize(int argc, char **argv) { | ||
554 | struct sway_container *current = config->handler_context.current_container; | ||
555 | if (!current) { | ||
556 | return cmd_results_new(CMD_INVALID, "resize", "Cannot resize nothing"); | ||
557 | } | ||
558 | if (current->type != C_VIEW && current->type != C_CONTAINER) { | ||
559 | return cmd_results_new(CMD_INVALID, "resize", | ||
560 | "Can only resize views/containers"); | ||
561 | } | ||
562 | |||
563 | struct cmd_results *error; | ||
564 | if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) { | ||
565 | return error; | ||
566 | } | ||
567 | |||
568 | if (strcasecmp(argv[0], "set") == 0) { | ||
569 | return cmd_resize_set(argc - 1, &argv[1]); | ||
570 | } | ||
571 | if (strcasecmp(argv[0], "grow") == 0) { | ||
572 | return cmd_resize_adjust(argc - 1, &argv[1], 1); | ||
573 | } | ||
574 | if (strcasecmp(argv[0], "shrink") == 0) { | ||
575 | return cmd_resize_adjust(argc - 1, &argv[1], -1); | ||
576 | } | ||
577 | |||
578 | const char *usage = "Expected 'resize <shrink|grow> " | ||
579 | "<width|height|up|down|left|right> [<amount>] [px|ppt]'"; | ||
580 | |||
581 | return cmd_results_new(CMD_INVALID, "resize", usage); | ||
286 | } | 582 | } |