diff options
Diffstat (limited to 'sway/commands/resize.c')
-rw-r--r-- | sway/commands/resize.c | 144 |
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 | ||
18 | enum resize_unit { | ||
19 | RESIZE_UNIT_PX, | ||
20 | RESIZE_UNIT_PPT, | ||
21 | RESIZE_UNIT_DEFAULT, | ||
22 | RESIZE_UNIT_INVALID, | ||
23 | }; | ||
24 | |||
25 | struct resize_amount { | ||
26 | int amount; | ||
27 | enum resize_unit unit; | ||
28 | }; | ||
29 | |||
30 | static 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. | ||
45 | static 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 | |||
67 | static uint32_t parse_resize_axis(const char *axis) { | 19 | static 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 | */ |
239 | static struct cmd_results *resize_adjust_floating(uint32_t axis, | 191 | static 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 | */ |
296 | static struct cmd_results *resize_adjust_tiled(uint32_t axis, | 248 | static 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 | */ |
326 | static struct cmd_results *resize_set_tiled(struct sway_container *con, | 278 | static 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 | */ |
376 | static struct cmd_results *resize_set_floating(struct sway_container *con, | 328 | static 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); |