aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/resize.c
diff options
context:
space:
mode:
authorLibravatar Nils Schulte <git@nilsschulte.de>2020-07-16 10:23:24 +0200
committerLibravatar Simon Ser <contact@emersion.fr>2020-07-21 10:07:01 +0200
commit6898d1963f7a7f6dcc0bff5d4c484818f38cdacf (patch)
treed8fd7ba5347f23e24cfa470727b2b6bd5b693342 /sway/commands/resize.c
parentsway.5: add missing underscore (diff)
downloadsway-6898d1963f7a7f6dcc0bff5d4c484818f38cdacf.tar.gz
sway-6898d1963f7a7f6dcc0bff5d4c484818f38cdacf.tar.zst
sway-6898d1963f7a7f6dcc0bff5d4c484818f38cdacf.zip
moved and renamed movement-unit parsing to common
Diffstat (limited to 'sway/commands/resize.c')
-rw-r--r--sway/commands/resize.c144
1 files changed, 48 insertions, 96 deletions
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index 7ff4ef7b..4038e331 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -11,59 +11,11 @@
11#include "sway/tree/view.h" 11#include "sway/tree/view.h"
12#include "sway/tree/workspace.h" 12#include "sway/tree/workspace.h"
13#include "log.h" 13#include "log.h"
14#include "util.h"
14 15
15#define AXIS_HORIZONTAL (WLR_EDGE_LEFT | WLR_EDGE_RIGHT) 16#define AXIS_HORIZONTAL (WLR_EDGE_LEFT | WLR_EDGE_RIGHT)
16#define AXIS_VERTICAL (WLR_EDGE_TOP | WLR_EDGE_BOTTOM) 17#define AXIS_VERTICAL (WLR_EDGE_TOP | WLR_EDGE_BOTTOM)
17 18
18enum resize_unit {
19 RESIZE_UNIT_PX,
20 RESIZE_UNIT_PPT,
21 RESIZE_UNIT_DEFAULT,
22 RESIZE_UNIT_INVALID,
23};
24
25struct resize_amount {
26 int amount;
27 enum resize_unit unit;
28};
29
30static enum resize_unit parse_resize_unit(const char *unit) {
31 if (strcasecmp(unit, "px") == 0) {
32 return RESIZE_UNIT_PX;
33 }
34 if (strcasecmp(unit, "ppt") == 0) {
35 return RESIZE_UNIT_PPT;
36 }
37 if (strcasecmp(unit, "default") == 0) {
38 return RESIZE_UNIT_DEFAULT;
39 }
40 return RESIZE_UNIT_INVALID;
41}
42
43// Parse arguments such as "10", "10px" or "10 px".
44// Returns the number of arguments consumed.
45static int parse_resize_amount(int argc, char **argv,
46 struct resize_amount *amount) {
47 char *err;
48 amount->amount = (int)strtol(argv[0], &err, 10);
49 if (*err) {
50 // e.g. 10px
51 amount->unit = parse_resize_unit(err);
52 return 1;
53 }
54 if (argc == 1) {
55 amount->unit = RESIZE_UNIT_DEFAULT;
56 return 1;
57 }
58 // Try the second argument
59 amount->unit = parse_resize_unit(argv[1]);
60 if (amount->unit == RESIZE_UNIT_INVALID) {
61 amount->unit = RESIZE_UNIT_DEFAULT;
62 return 1;
63 }
64 return 2;
65}
66
67static uint32_t parse_resize_axis(const char *axis) { 19static uint32_t parse_resize_axis(const char *axis) {
68 if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) { 20 if (strcasecmp(axis, "width") == 0 || strcasecmp(axis, "horizontal") == 0) {
69 return AXIS_HORIZONTAL; 21 return AXIS_HORIZONTAL;
@@ -237,7 +189,7 @@ void container_resize_tiled(struct sway_container *con,
237 * Implement `resize <grow|shrink>` for a floating container. 189 * Implement `resize <grow|shrink>` for a floating container.
238 */ 190 */
239static struct cmd_results *resize_adjust_floating(uint32_t axis, 191static struct cmd_results *resize_adjust_floating(uint32_t axis,
240 struct resize_amount *amount) { 192 struct movement_amount *amount) {
241 struct sway_container *con = config->handler_context.container; 193 struct sway_container *con = config->handler_context.container;
242 int grow_width = 0, grow_height = 0; 194 int grow_width = 0, grow_height = 0;
243 195
@@ -294,13 +246,13 @@ static struct cmd_results *resize_adjust_floating(uint32_t axis,
294 * Implement `resize <grow|shrink>` for a tiled container. 246 * Implement `resize <grow|shrink>` for a tiled container.
295 */ 247 */
296static struct cmd_results *resize_adjust_tiled(uint32_t axis, 248static struct cmd_results *resize_adjust_tiled(uint32_t axis,
297 struct resize_amount *amount) { 249 struct movement_amount *amount) {
298 struct sway_container *current = config->handler_context.container; 250 struct sway_container *current = config->handler_context.container;
299 251
300 if (amount->unit == RESIZE_UNIT_DEFAULT) { 252 if (amount->unit == MOVEMENT_UNIT_DEFAULT) {
301 amount->unit = RESIZE_UNIT_PPT; 253 amount->unit = MOVEMENT_UNIT_PPT;
302 } 254 }
303 if (amount->unit == RESIZE_UNIT_PPT) { 255 if (amount->unit == MOVEMENT_UNIT_PPT) {
304 float pct = amount->amount / 100.0f; 256 float pct = amount->amount / 100.0f;
305 257
306 if (is_horizontal(axis)) { 258 if (is_horizontal(axis)) {
@@ -324,10 +276,10 @@ static struct cmd_results *resize_adjust_tiled(uint32_t axis,
324 * Implement `resize set` for a tiled container. 276 * Implement `resize set` for a tiled container.
325 */ 277 */
326static struct cmd_results *resize_set_tiled(struct sway_container *con, 278static struct cmd_results *resize_set_tiled(struct sway_container *con,
327 struct resize_amount *width, struct resize_amount *height) { 279 struct movement_amount *width, struct movement_amount *height) {
328 if (width->amount) { 280 if (width->amount) {
329 if (width->unit == RESIZE_UNIT_PPT || 281 if (width->unit == MOVEMENT_UNIT_PPT ||
330 width->unit == RESIZE_UNIT_DEFAULT) { 282 width->unit == MOVEMENT_UNIT_DEFAULT) {
331 // Convert to px 283 // Convert to px
332 struct sway_container *parent = con->parent; 284 struct sway_container *parent = con->parent;
333 while (parent && parent->layout != L_HORIZ) { 285 while (parent && parent->layout != L_HORIZ) {
@@ -338,17 +290,17 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
338 } else { 290 } else {
339 width->amount = con->workspace->width * width->amount / 100; 291 width->amount = con->workspace->width * width->amount / 100;
340 } 292 }
341 width->unit = RESIZE_UNIT_PX; 293 width->unit = MOVEMENT_UNIT_PX;
342 } 294 }
343 if (width->unit == RESIZE_UNIT_PX) { 295 if (width->unit == MOVEMENT_UNIT_PX) {
344 container_resize_tiled(con, AXIS_HORIZONTAL, 296 container_resize_tiled(con, AXIS_HORIZONTAL,
345 width->amount - con->width); 297 width->amount - con->width);
346 } 298 }
347 } 299 }
348 300
349 if (height->amount) { 301 if (height->amount) {
350 if (height->unit == RESIZE_UNIT_PPT || 302 if (height->unit == MOVEMENT_UNIT_PPT ||
351 height->unit == RESIZE_UNIT_DEFAULT) { 303 height->unit == MOVEMENT_UNIT_DEFAULT) {
352 // Convert to px 304 // Convert to px
353 struct sway_container *parent = con->parent; 305 struct sway_container *parent = con->parent;
354 while (parent && parent->layout != L_VERT) { 306 while (parent && parent->layout != L_VERT) {
@@ -359,9 +311,9 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
359 } else { 311 } else {
360 height->amount = con->workspace->height * height->amount / 100; 312 height->amount = con->workspace->height * height->amount / 100;
361 } 313 }
362 height->unit = RESIZE_UNIT_PX; 314 height->unit = MOVEMENT_UNIT_PX;
363 } 315 }
364 if (height->unit == RESIZE_UNIT_PX) { 316 if (height->unit == MOVEMENT_UNIT_PX) {
365 container_resize_tiled(con, AXIS_VERTICAL, 317 container_resize_tiled(con, AXIS_VERTICAL,
366 height->amount - con->height); 318 height->amount - con->height);
367 } 319 }
@@ -374,30 +326,30 @@ static struct cmd_results *resize_set_tiled(struct sway_container *con,
374 * Implement `resize set` for a floating container. 326 * Implement `resize set` for a floating container.
375 */ 327 */
376static struct cmd_results *resize_set_floating(struct sway_container *con, 328static struct cmd_results *resize_set_floating(struct sway_container *con,
377 struct resize_amount *width, struct resize_amount *height) { 329 struct movement_amount *width, struct movement_amount *height) {
378 int min_width, max_width, min_height, max_height, grow_width = 0, grow_height = 0; 330 int min_width, max_width, min_height, max_height, grow_width = 0, grow_height = 0;
379 floating_calculate_constraints(&min_width, &max_width, 331 floating_calculate_constraints(&min_width, &max_width,
380 &min_height, &max_height); 332 &min_height, &max_height);
381 333
382 if (width->amount) { 334 if (width->amount) {
383 switch (width->unit) { 335 switch (width->unit) {
384 case RESIZE_UNIT_PPT: 336 case MOVEMENT_UNIT_PPT:
385 if (container_is_scratchpad_hidden(con)) { 337 if (container_is_scratchpad_hidden(con)) {
386 return cmd_results_new(CMD_FAILURE, 338 return cmd_results_new(CMD_FAILURE,
387 "Cannot resize a hidden scratchpad container by ppt"); 339 "Cannot resize a hidden scratchpad container by ppt");
388 } 340 }
389 // Convert to px 341 // Convert to px
390 width->amount = con->workspace->width * width->amount / 100; 342 width->amount = con->workspace->width * width->amount / 100;
391 width->unit = RESIZE_UNIT_PX; 343 width->unit = MOVEMENT_UNIT_PX;
392 // Falls through 344 // Falls through
393 case RESIZE_UNIT_PX: 345 case MOVEMENT_UNIT_PX:
394 case RESIZE_UNIT_DEFAULT: 346 case MOVEMENT_UNIT_DEFAULT:
395 width->amount = fmax(min_width, fmin(width->amount, max_width)); 347 width->amount = fmax(min_width, fmin(width->amount, max_width));
396 grow_width = width->amount - con->width; 348 grow_width = width->amount - con->width;
397 con->x -= grow_width / 2; 349 con->x -= grow_width / 2;
398 con->width = width->amount; 350 con->width = width->amount;
399 break; 351 break;
400 case RESIZE_UNIT_INVALID: 352 case MOVEMENT_UNIT_INVALID:
401 sway_assert(false, "invalid width unit"); 353 sway_assert(false, "invalid width unit");
402 break; 354 break;
403 } 355 }
@@ -405,23 +357,23 @@ static struct cmd_results *resize_set_floating(struct sway_container *con,
405 357
406 if (height->amount) { 358 if (height->amount) {
407 switch (height->unit) { 359 switch (height->unit) {
408 case RESIZE_UNIT_PPT: 360 case MOVEMENT_UNIT_PPT:
409 if (container_is_scratchpad_hidden(con)) { 361 if (container_is_scratchpad_hidden(con)) {
410 return cmd_results_new(CMD_FAILURE, 362 return cmd_results_new(CMD_FAILURE,
411 "Cannot resize a hidden scratchpad container by ppt"); 363 "Cannot resize a hidden scratchpad container by ppt");
412 } 364 }
413 // Convert to px 365 // Convert to px
414 height->amount = con->workspace->height * height->amount / 100; 366 height->amount = con->workspace->height * height->amount / 100;
415 height->unit = RESIZE_UNIT_PX; 367 height->unit = MOVEMENT_UNIT_PX;
416 // Falls through 368 // Falls through
417 case RESIZE_UNIT_PX: 369 case MOVEMENT_UNIT_PX:
418 case RESIZE_UNIT_DEFAULT: 370 case MOVEMENT_UNIT_DEFAULT:
419 height->amount = fmax(min_height, fmin(height->amount, max_height)); 371 height->amount = fmax(min_height, fmin(height->amount, max_height));
420 grow_height = height->amount - con->height; 372 grow_height = height->amount - con->height;
421 con->y -= grow_height / 2; 373 con->y -= grow_height / 2;
422 con->height = height->amount; 374 con->height = height->amount;
423 break; 375 break;
424 case RESIZE_UNIT_INVALID: 376 case MOVEMENT_UNIT_INVALID:
425 sway_assert(false, "invalid height unit"); 377 sway_assert(false, "invalid height unit");
426 break; 378 break;
427 } 379 }
@@ -454,30 +406,30 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
454 "'resize set [width] <width> [px|ppt] [height] <height> [px|ppt]'"; 406 "'resize set [width] <width> [px|ppt] [height] <height> [px|ppt]'";
455 407
456 // Width 408 // Width
457 struct resize_amount width = {0}; 409 struct movement_amount width = {0};
458 if (argc >= 2 && !strcmp(argv[0], "width") && strcmp(argv[1], "height")) { 410 if (argc >= 2 && !strcmp(argv[0], "width") && strcmp(argv[1], "height")) {
459 argc--; argv++; 411 argc--; argv++;
460 } 412 }
461 if (strcmp(argv[0], "height")) { 413 if (strcmp(argv[0], "height")) {
462 int num_consumed_args = parse_resize_amount(argc, argv, &width); 414 int num_consumed_args = parse_movement_amount(argc, argv, &width);
463 argc -= num_consumed_args; 415 argc -= num_consumed_args;
464 argv += num_consumed_args; 416 argv += num_consumed_args;
465 if (width.unit == RESIZE_UNIT_INVALID) { 417 if (width.unit == MOVEMENT_UNIT_INVALID) {
466 return cmd_results_new(CMD_INVALID, usage); 418 return cmd_results_new(CMD_INVALID, usage);
467 } 419 }
468 } 420 }
469 421
470 // Height 422 // Height
471 struct resize_amount height = {0}; 423 struct movement_amount height = {0};
472 if (argc) { 424 if (argc) {
473 if (argc >= 2 && !strcmp(argv[0], "height")) { 425 if (argc >= 2 && !strcmp(argv[0], "height")) {
474 argc--; argv++; 426 argc--; argv++;
475 } 427 }
476 int num_consumed_args = parse_resize_amount(argc, argv, &height); 428 int num_consumed_args = parse_movement_amount(argc, argv, &height);
477 if (argc > num_consumed_args) { 429 if (argc > num_consumed_args) {
478 return cmd_results_new(CMD_INVALID, usage); 430 return cmd_results_new(CMD_INVALID, usage);
479 } 431 }
480 if (width.unit == RESIZE_UNIT_INVALID) { 432 if (width.unit == MOVEMENT_UNIT_INVALID) {
481 return cmd_results_new(CMD_INVALID, usage); 433 return cmd_results_new(CMD_INVALID, usage);
482 } 434 }
483 } 435 }
@@ -515,17 +467,17 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
515 --argc; ++argv; 467 --argc; ++argv;
516 468
517 // First amount 469 // First amount
518 struct resize_amount first_amount; 470 struct movement_amount first_amount;
519 if (argc) { 471 if (argc) {
520 int num_consumed_args = parse_resize_amount(argc, argv, &first_amount); 472 int num_consumed_args = parse_movement_amount(argc, argv, &first_amount);
521 argc -= num_consumed_args; 473 argc -= num_consumed_args;
522 argv += num_consumed_args; 474 argv += num_consumed_args;
523 if (first_amount.unit == RESIZE_UNIT_INVALID) { 475 if (first_amount.unit == MOVEMENT_UNIT_INVALID) {
524 return cmd_results_new(CMD_INVALID, usage); 476 return cmd_results_new(CMD_INVALID, usage);
525 } 477 }
526 } else { 478 } else {
527 first_amount.amount = 10; 479 first_amount.amount = 10;
528 first_amount.unit = RESIZE_UNIT_DEFAULT; 480 first_amount.unit = MOVEMENT_UNIT_DEFAULT;
529 } 481 }
530 482
531 // "or" 483 // "or"
@@ -537,18 +489,18 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
537 } 489 }
538 490
539 // Second amount 491 // Second amount
540 struct resize_amount second_amount; 492 struct movement_amount second_amount;
541 if (argc) { 493 if (argc) {
542 int num_consumed_args = parse_resize_amount(argc, argv, &second_amount); 494 int num_consumed_args = parse_movement_amount(argc, argv, &second_amount);
543 if (argc > num_consumed_args) { 495 if (argc > num_consumed_args) {
544 return cmd_results_new(CMD_INVALID, usage); 496 return cmd_results_new(CMD_INVALID, usage);
545 } 497 }
546 if (second_amount.unit == RESIZE_UNIT_INVALID) { 498 if (second_amount.unit == MOVEMENT_UNIT_INVALID) {
547 return cmd_results_new(CMD_INVALID, usage); 499 return cmd_results_new(CMD_INVALID, usage);
548 } 500 }
549 } else { 501 } else {
550 second_amount.amount = 0; 502 second_amount.amount = 0;
551 second_amount.unit = RESIZE_UNIT_INVALID; 503 second_amount.unit = MOVEMENT_UNIT_INVALID;
552 } 504 }
553 505
554 first_amount.amount *= multiplier; 506 first_amount.amount *= multiplier;
@@ -558,13 +510,13 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
558 if (container_is_floating(con)) { 510 if (container_is_floating(con)) {
559 // Floating containers can only resize in px. Choose an amount which 511 // Floating containers can only resize in px. Choose an amount which
560 // uses px, with fallback to an amount that specified no unit. 512 // uses px, with fallback to an amount that specified no unit.
561 if (first_amount.unit == RESIZE_UNIT_PX) { 513 if (first_amount.unit == MOVEMENT_UNIT_PX) {
562 return resize_adjust_floating(axis, &first_amount); 514 return resize_adjust_floating(axis, &first_amount);
563 } else if (second_amount.unit == RESIZE_UNIT_PX) { 515 } else if (second_amount.unit == MOVEMENT_UNIT_PX) {
564 return resize_adjust_floating(axis, &second_amount); 516 return resize_adjust_floating(axis, &second_amount);
565 } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { 517 } else if (first_amount.unit == MOVEMENT_UNIT_DEFAULT) {
566 return resize_adjust_floating(axis, &first_amount); 518 return resize_adjust_floating(axis, &first_amount);
567 } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { 519 } else if (second_amount.unit == MOVEMENT_UNIT_DEFAULT) {
568 return resize_adjust_floating(axis, &second_amount); 520 return resize_adjust_floating(axis, &second_amount);
569 } else { 521 } else {
570 return cmd_results_new(CMD_INVALID, 522 return cmd_results_new(CMD_INVALID,
@@ -573,13 +525,13 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
573 } 525 }
574 526
575 // For tiling, prefer ppt -> default -> px 527 // For tiling, prefer ppt -> default -> px
576 if (first_amount.unit == RESIZE_UNIT_PPT) { 528 if (first_amount.unit == MOVEMENT_UNIT_PPT) {
577 return resize_adjust_tiled(axis, &first_amount); 529 return resize_adjust_tiled(axis, &first_amount);
578 } else if (second_amount.unit == RESIZE_UNIT_PPT) { 530 } else if (second_amount.unit == MOVEMENT_UNIT_PPT) {
579 return resize_adjust_tiled(axis, &second_amount); 531 return resize_adjust_tiled(axis, &second_amount);
580 } else if (first_amount.unit == RESIZE_UNIT_DEFAULT) { 532 } else if (first_amount.unit == MOVEMENT_UNIT_DEFAULT) {
581 return resize_adjust_tiled(axis, &first_amount); 533 return resize_adjust_tiled(axis, &first_amount);
582 } else if (second_amount.unit == RESIZE_UNIT_DEFAULT) { 534 } else if (second_amount.unit == MOVEMENT_UNIT_DEFAULT) {
583 return resize_adjust_tiled(axis, &second_amount); 535 return resize_adjust_tiled(axis, &second_amount);
584 } else { 536 } else {
585 return resize_adjust_tiled(axis, &first_amount); 537 return resize_adjust_tiled(axis, &first_amount);