diff options
author | Drew DeVault <sir@cmpwn.com> | 2015-08-22 09:03:43 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2015-08-22 09:03:43 -0400 |
commit | ade634bb04027a6ea5f053330e044638f135c147 (patch) | |
tree | b446198afb8d5ea2d9e32e5953c9e1d4cf445485 | |
parent | Merge pull request #117 from Luminarys/master (diff) | |
parent | Added in bspwm like view swapping (diff) | |
download | sway-ade634bb04027a6ea5f053330e044638f135c147.tar.gz sway-ade634bb04027a6ea5f053330e044638f135c147.tar.zst sway-ade634bb04027a6ea5f053330e044638f135c147.zip |
Merge pull request #118 from Luminarys/master
Refactored resizing functions into resize.c
-rw-r--r-- | include/handlers.h | 1 | ||||
-rw-r--r-- | include/layout.h | 3 | ||||
-rw-r--r-- | include/resize.h | 8 | ||||
-rw-r--r-- | sway/commands.c | 225 | ||||
-rw-r--r-- | sway/handlers.c | 297 | ||||
-rw-r--r-- | sway/layout.c | 2 | ||||
-rw-r--r-- | sway/resize.c | 491 |
7 files changed, 556 insertions, 471 deletions
diff --git a/include/handlers.h b/include/handlers.h index c25c3309..4c71f953 100644 --- a/include/handlers.h +++ b/include/handlers.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <wlc/wlc.h> | 5 | #include <wlc/wlc.h> |
6 | 6 | ||
7 | extern struct wlc_interface interface; | 7 | extern struct wlc_interface interface; |
8 | extern struct wlc_origin mouse_origin; | ||
8 | extern uint32_t keys_pressed[32]; | 9 | extern uint32_t keys_pressed[32]; |
9 | 10 | ||
10 | // set focus to current pointer location and return focused container | 11 | // set focus to current pointer location and return focused container |
diff --git a/include/layout.h b/include/layout.h index 7b8829ed..f8aebe0a 100644 --- a/include/layout.h +++ b/include/layout.h | |||
@@ -8,6 +8,9 @@ | |||
8 | 8 | ||
9 | extern swayc_t root_container; | 9 | extern swayc_t root_container; |
10 | 10 | ||
11 | extern int min_sane_w; | ||
12 | extern int min_sane_h; | ||
13 | |||
11 | void init_layout(void); | 14 | void init_layout(void); |
12 | 15 | ||
13 | void add_child(swayc_t *parent, swayc_t *child); | 16 | void add_child(swayc_t *parent, swayc_t *child); |
diff --git a/include/resize.h b/include/resize.h new file mode 100644 index 00000000..4ace1815 --- /dev/null +++ b/include/resize.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _SWAY_RESIZE_H | ||
2 | #define _SWAY_RESIZE_H | ||
3 | |||
4 | bool mouse_resize_tiled(struct wlc_origin prev_pos); | ||
5 | bool resize_floating(struct wlc_origin prev_pos); | ||
6 | bool resize_tiled(int amount, bool use_width); | ||
7 | |||
8 | #endif | ||
diff --git a/sway/commands.c b/sway/commands.c index 36299c8d..62794111 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "container.h" | 16 | #include "container.h" |
17 | #include "handlers.h" | 17 | #include "handlers.h" |
18 | #include "sway.h" | 18 | #include "sway.h" |
19 | #include "resize.h" | ||
19 | 20 | ||
20 | struct modifier_key { | 21 | struct modifier_key { |
21 | char *name; | 22 | char *name; |
@@ -448,240 +449,26 @@ static bool cmd_resize(struct sway_config *config, int argc, char **argv) { | |||
448 | return false; | 449 | return false; |
449 | } | 450 | } |
450 | char *end; | 451 | char *end; |
451 | int min_sane_w = 100; | ||
452 | int min_sane_h = 60; | ||
453 | int amount = (int)strtol(argv[2], &end, 10); | 452 | int amount = (int)strtol(argv[2], &end, 10); |
454 | if (errno == ERANGE || amount == 0) { | 453 | if (errno == ERANGE || amount == 0) { |
455 | errno = 0; | 454 | errno = 0; |
456 | return false; | 455 | return false; |
457 | } | 456 | } |
457 | |||
458 | if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) { | 458 | if (strcmp(argv[0], "shrink") != 0 && strcmp(argv[0], "grow") != 0) { |
459 | return false; | 459 | return false; |
460 | } | 460 | } |
461 | |||
461 | if (strcmp(argv[0], "shrink") == 0) { | 462 | if (strcmp(argv[0], "shrink") == 0) { |
462 | amount *= -1; | 463 | amount *= -1; |
463 | } | 464 | } |
464 | 465 | ||
465 | swayc_t *parent = get_focused_view(swayc_active_workspace()); | ||
466 | swayc_t *focused = parent; | ||
467 | swayc_t *sibling; | ||
468 | if (!parent) { | ||
469 | return true; | ||
470 | } | ||
471 | // Find the closest parent container which has siblings of the proper layout. | ||
472 | // Then apply the resize to all of them. | ||
473 | int i; | ||
474 | if (strcmp(argv[1], "width") == 0) { | 466 | if (strcmp(argv[1], "width") == 0) { |
475 | int lnumber = 0; | 467 | return resize_tiled(amount, true); |
476 | int rnumber = 0; | ||
477 | while (parent->parent) { | ||
478 | if (parent->parent->layout == L_HORIZ) { | ||
479 | for (i = 0; i < parent->parent->children->length; i++) { | ||
480 | sibling = parent->parent->children->items[i]; | ||
481 | if (sibling->x != focused->x) { | ||
482 | if (sibling->x < parent->x) { | ||
483 | lnumber++; | ||
484 | } else if (sibling->x > parent->x) { | ||
485 | rnumber++; | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | if (rnumber || lnumber) { | ||
490 | break; | ||
491 | } | ||
492 | } | ||
493 | parent = parent->parent; | ||
494 | } | ||
495 | if (parent == &root_container) { | ||
496 | return true; | ||
497 | } | ||
498 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber); | ||
499 | //TODO: Ensure rounding is done in such a way that there are NO pixel leaks | ||
500 | bool valid = true; | ||
501 | for (i = 0; i < parent->parent->children->length; i++) { | ||
502 | sibling = parent->parent->children->items[i]; | ||
503 | if (sibling->x != focused->x) { | ||
504 | if (sibling->x < parent->x) { | ||
505 | double pixels = -1 * amount; | ||
506 | pixels /= lnumber; | ||
507 | if (rnumber) { | ||
508 | if ((sibling->width + pixels/2) < min_sane_w) { | ||
509 | valid = false; | ||
510 | break; | ||
511 | } | ||
512 | } else { | ||
513 | if ((sibling->width + pixels) < min_sane_w) { | ||
514 | valid = false; | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | } else if (sibling->x > parent->x) { | ||
519 | double pixels = -1 * amount; | ||
520 | pixels /= rnumber; | ||
521 | if (lnumber) { | ||
522 | if ((sibling->width + pixels/2) < min_sane_w) { | ||
523 | valid = false; | ||
524 | break; | ||
525 | } | ||
526 | } else { | ||
527 | if ((sibling->width + pixels) < min_sane_w) { | ||
528 | valid = false; | ||
529 | break; | ||
530 | } | ||
531 | } | ||
532 | } | ||
533 | } else { | ||
534 | double pixels = amount; | ||
535 | if (parent->width + pixels < min_sane_w) { | ||
536 | valid = false; | ||
537 | break; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | if (valid) { | ||
542 | for (i = 0; i < parent->parent->children->length; i++) { | ||
543 | sibling = parent->parent->children->items[i]; | ||
544 | if (sibling->x != focused->x) { | ||
545 | if (sibling->x < parent->x) { | ||
546 | double pixels = -1 * amount; | ||
547 | pixels /= lnumber; | ||
548 | if (rnumber) { | ||
549 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT); | ||
550 | } else { | ||
551 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT); | ||
552 | } | ||
553 | } else if (sibling->x > parent->x) { | ||
554 | double pixels = -1 * amount; | ||
555 | pixels /= rnumber; | ||
556 | if (lnumber) { | ||
557 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT); | ||
558 | } else { | ||
559 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT); | ||
560 | } | ||
561 | } | ||
562 | } else { | ||
563 | if (rnumber != 0 && lnumber != 0) { | ||
564 | double pixels = amount; | ||
565 | pixels /= 2; | ||
566 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT); | ||
567 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT); | ||
568 | } else if (rnumber) { | ||
569 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT); | ||
570 | } else if (lnumber) { | ||
571 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT); | ||
572 | } | ||
573 | } | ||
574 | } | ||
575 | // Recursive resize does not handle positions, let arrange_windows | ||
576 | // take care of that. | ||
577 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
578 | } | ||
579 | return true; | ||
580 | } else if (strcmp(argv[1], "height") == 0) { | 468 | } else if (strcmp(argv[1], "height") == 0) { |
581 | int tnumber = 0; | 469 | return resize_tiled(amount, false); |
582 | int bnumber = 0; | ||
583 | while (parent->parent) { | ||
584 | if (parent->parent->layout == L_VERT) { | ||
585 | for (i = 0; i < parent->parent->children->length; i++) { | ||
586 | sibling = parent->parent->children->items[i]; | ||
587 | if (sibling->y != focused->y) { | ||
588 | if (sibling->y < parent->y) { | ||
589 | bnumber++; | ||
590 | } else if (sibling->y > parent->y) { | ||
591 | tnumber++; | ||
592 | } | ||
593 | } | ||
594 | } | ||
595 | if (bnumber || tnumber) { | ||
596 | break; | ||
597 | } | ||
598 | } | ||
599 | parent = parent->parent; | ||
600 | } | ||
601 | if (parent == &root_container) { | ||
602 | return true; | ||
603 | } | ||
604 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber); | ||
605 | //TODO: Ensure rounding is done in such a way that there are NO pixel leaks | ||
606 | bool valid = true; | ||
607 | for (i = 0; i < parent->parent->children->length; i++) { | ||
608 | sibling = parent->parent->children->items[i]; | ||
609 | if (sibling->y != focused->y) { | ||
610 | if (sibling->y < parent->y) { | ||
611 | double pixels = -1 * amount; | ||
612 | pixels /= bnumber; | ||
613 | if (tnumber) { | ||
614 | if ((sibling->height + pixels/2) < min_sane_h) { | ||
615 | valid = false; | ||
616 | break; | ||
617 | } | ||
618 | } else { | ||
619 | if ((sibling->height + pixels) < min_sane_h) { | ||
620 | valid = false; | ||
621 | break; | ||
622 | } | ||
623 | } | ||
624 | } else if (sibling->y > parent->y) { | ||
625 | double pixels = -1 * amount; | ||
626 | pixels /= tnumber; | ||
627 | if (bnumber) { | ||
628 | if ((sibling->height + pixels/2) < min_sane_h) { | ||
629 | valid = false; | ||
630 | break; | ||
631 | } | ||
632 | } else { | ||
633 | if ((sibling->height + pixels) < min_sane_h) { | ||
634 | valid = false; | ||
635 | break; | ||
636 | } | ||
637 | } | ||
638 | } | ||
639 | } else { | ||
640 | double pixels = amount; | ||
641 | if (parent->height + pixels < min_sane_h) { | ||
642 | valid = false; | ||
643 | break; | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | if (valid) { | ||
648 | for (i = 0; i < parent->parent->children->length; i++) { | ||
649 | sibling = parent->parent->children->items[i]; | ||
650 | if (sibling->y != focused->y) { | ||
651 | if (sibling->y < parent->y) { | ||
652 | double pixels = -1 * amount; | ||
653 | pixels /= bnumber; | ||
654 | if (tnumber) { | ||
655 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM); | ||
656 | } else { | ||
657 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM); | ||
658 | } | ||
659 | } else if (sibling->x > parent->x) { | ||
660 | double pixels = -1 * amount; | ||
661 | pixels /= tnumber; | ||
662 | if (bnumber) { | ||
663 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP); | ||
664 | } else { | ||
665 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP); | ||
666 | } | ||
667 | } | ||
668 | } else { | ||
669 | if (bnumber != 0 && tnumber != 0) { | ||
670 | double pixels = amount/2; | ||
671 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP); | ||
672 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM); | ||
673 | } else if (tnumber) { | ||
674 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP); | ||
675 | } else if (bnumber) { | ||
676 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM); | ||
677 | } | ||
678 | } | ||
679 | } | ||
680 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
681 | } | ||
682 | return true; | ||
683 | } | 470 | } |
684 | return true; | 471 | return false; |
685 | } | 472 | } |
686 | 473 | ||
687 | static bool cmd_set(struct sway_config *config, int argc, char **argv) { | 474 | static bool cmd_set(struct sway_config *config, int argc, char **argv) { |
diff --git a/sway/handlers.c b/sway/handlers.c index d8f9e987..cb42196f 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -15,8 +15,9 @@ | |||
15 | #include "container.h" | 15 | #include "container.h" |
16 | #include "focus.h" | 16 | #include "focus.h" |
17 | #include "input_state.h" | 17 | #include "input_state.h" |
18 | #include "resize.h" | ||
18 | 19 | ||
19 | static struct wlc_origin mouse_origin; | 20 | struct wlc_origin mouse_origin; |
20 | 21 | ||
21 | static bool pointer_test(swayc_t *view, void *_origin) { | 22 | static bool pointer_test(swayc_t *view, void *_origin) { |
22 | const struct wlc_origin *origin = _origin; | 23 | const struct wlc_origin *origin = _origin; |
@@ -338,261 +339,65 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
338 | mouse_origin = *origin; | 339 | mouse_origin = *origin; |
339 | bool changed_floating = false; | 340 | bool changed_floating = false; |
340 | bool changed_tiling = false; | 341 | bool changed_tiling = false; |
341 | int min_sane_w = 100; | ||
342 | int min_sane_h = 60; | ||
343 | if (!swayc_active_workspace()) { | 342 | if (!swayc_active_workspace()) { |
344 | return false; | 343 | return false; |
345 | } | 344 | } |
346 | // Do checks to determine if proper keys are being held | 345 | // Do checks to determine if proper keys are being held |
347 | swayc_t *view = container_under_pointer(); | 346 | swayc_t *view = container_under_pointer(); |
348 | uint32_t edge = 0; | ||
349 | if (pointer_state.floating.drag && view) { | 347 | if (pointer_state.floating.drag && view) { |
350 | if (view->is_floating) { | 348 | if (view->is_floating) { |
351 | int dx = mouse_origin.x - prev_pos.x; | 349 | int dx = mouse_origin.x - prev_pos.x; |
352 | int dy = mouse_origin.y - prev_pos.y; | 350 | int dy = mouse_origin.y - prev_pos.y; |
353 | view->x += dx; | 351 | view->x += dx; |
354 | view->y += dy; | 352 | view->y += dy; |
355 | changed_floating = true; | 353 | struct wlc_geometry geometry = { |
356 | } | 354 | .origin = { |
357 | } else if (pointer_state.floating.resize && view) { | 355 | .x = view->x, |
358 | if (view->is_floating) { | 356 | .y = view->y |
359 | int dx = mouse_origin.x - prev_pos.x; | 357 | }, |
360 | int dy = mouse_origin.y - prev_pos.y; | 358 | .size = { |
361 | 359 | .w = view->width, | |
362 | // Move and resize the view based on the dx/dy and mouse position | 360 | .h = view->height |
363 | int midway_x = view->x + view->width/2; | ||
364 | int midway_y = view->y + view->height/2; | ||
365 | if (dx < 0) { | ||
366 | if (!pointer_state.lock.right) { | ||
367 | if (view->width > min_sane_w) { | ||
368 | changed_floating = true; | ||
369 | view->width += dx; | ||
370 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
371 | } | ||
372 | } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { | ||
373 | changed_floating = true; | ||
374 | view->x += dx; | ||
375 | view->width -= dx; | ||
376 | edge += WLC_RESIZE_EDGE_LEFT; | ||
377 | } | 361 | } |
378 | } else if (dx > 0) { | 362 | }; |
379 | if (mouse_origin.x > midway_x && !pointer_state.lock.right) { | 363 | wlc_view_set_geometry(view->handle, 0, &geometry); |
380 | changed_floating = true; | 364 | changed_floating = true; |
381 | view->width += dx; | 365 | } else { |
382 | edge += WLC_RESIZE_EDGE_RIGHT; | 366 | swayc_t *init_view = pointer_state.tiling.init_view; |
383 | } else if (!pointer_state.lock.left) { | 367 | if (view != init_view && view->type == C_VIEW) { |
384 | if (view->width > min_sane_w) { | 368 | changed_tiling = true; |
385 | changed_floating = true; | 369 | int i, j; |
386 | view->x += dx; | 370 | for (i = 0; i < view->parent->children->length; i++) { |
387 | view->width -= dx; | 371 | if (view->parent->children->items[i] == view) { |
388 | edge += WLC_RESIZE_EDGE_LEFT; | 372 | for (j = 0; j < init_view->parent->children->length; j++) { |
389 | } | 373 | if (init_view->parent->children->items[j] == init_view) { |
390 | } | 374 | double temp_w = view->width; |
391 | } | 375 | double temp_h = view->height; |
392 | 376 | view->width = init_view->width; | |
393 | if (dy < 0) { | 377 | view->height = init_view->height; |
394 | if (!pointer_state.lock.bottom) { | 378 | init_view->width = temp_w; |
395 | if (view->height > min_sane_h) { | 379 | init_view->height = temp_h; |
396 | changed_floating = true; | 380 | |
397 | view->height += dy; | 381 | init_view->parent->children->items[j] = view; |
398 | edge += WLC_RESIZE_EDGE_BOTTOM; | 382 | view->parent->children->items[i] = init_view; |
399 | } | 383 | |
400 | } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { | 384 | swayc_t *temp = view->parent; |
401 | changed_floating = true; | 385 | view->parent = init_view->parent; |
402 | view->y += dy; | 386 | init_view->parent = temp; |
403 | view->height -= dy; | 387 | |
404 | edge += WLC_RESIZE_EDGE_TOP; | 388 | arrange_windows(&root_container, -1, -1); |
405 | } | 389 | break; |
406 | } else if (dy > 0) { | ||
407 | if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { | ||
408 | changed_floating = true; | ||
409 | view->height += dy; | ||
410 | edge += WLC_RESIZE_EDGE_BOTTOM; | ||
411 | } else if (!pointer_state.lock.top) { | ||
412 | if (view->height > min_sane_h) { | ||
413 | changed_floating = true; | ||
414 | view->y += dy; | ||
415 | view->height -= dy; | ||
416 | edge += WLC_RESIZE_EDGE_TOP; | ||
417 | } | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | } else if (pointer_state.tiling.resize && view) { | ||
422 | bool valid = true; | ||
423 | double dx = mouse_origin.x - prev_pos.x; | ||
424 | double dy = mouse_origin.y - prev_pos.y; | ||
425 | if (view != pointer_state.tiling.init_view) { | ||
426 | changed_tiling = true; | ||
427 | valid = false; | ||
428 | if (view->type != C_WORKSPACE) { | ||
429 | if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) { | ||
430 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
431 | pointer_state.lock.temp_left = true; | ||
432 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) { | ||
433 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
434 | pointer_state.lock.temp_right = true; | ||
435 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) { | ||
436 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
437 | pointer_state.lock.temp_up = true; | ||
438 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) { | ||
439 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
440 | pointer_state.lock.temp_down = true; | ||
441 | } | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) { | ||
446 | changed_tiling = true; | ||
447 | valid = false; | ||
448 | } else if (dx > 0 && pointer_state.lock.temp_left) { | ||
449 | pointer_state.lock.temp_left = false; | ||
450 | pointer_state.tiling.lock_pos.x = 0; | ||
451 | } | ||
452 | |||
453 | if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) { | ||
454 | changed_tiling = true; | ||
455 | valid = false; | ||
456 | } else if (dx < 0 && pointer_state.lock.temp_right) { | ||
457 | pointer_state.lock.temp_right = false; | ||
458 | pointer_state.tiling.lock_pos.x = 0; | ||
459 | } | ||
460 | |||
461 | if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) { | ||
462 | changed_tiling = true; | ||
463 | valid = false; | ||
464 | } else if (dy > 0 && pointer_state.lock.temp_up) { | ||
465 | pointer_state.lock.temp_up = false; | ||
466 | pointer_state.tiling.lock_pos.y = 0; | ||
467 | } | ||
468 | |||
469 | if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) { | ||
470 | changed_tiling = true; | ||
471 | valid = false; | ||
472 | } else if (dy < 0 && pointer_state.lock.temp_down) { | ||
473 | pointer_state.lock.temp_down = false; | ||
474 | pointer_state.tiling.lock_pos.y = 0; | ||
475 | } | ||
476 | |||
477 | if (!view->is_floating && valid) { | ||
478 | // Handle layout resizes -- Find the biggest parent container then apply resizes to that | ||
479 | // and its bordering siblings | ||
480 | swayc_t *parent = view; | ||
481 | if (!pointer_state.lock.bottom) { | ||
482 | while (parent->type != C_WORKSPACE) { | ||
483 | // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better | ||
484 | // way of doing this. | ||
485 | if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) { | ||
486 | parent = parent->parent; | ||
487 | } else { | ||
488 | break; | ||
489 | } | ||
490 | } | ||
491 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
492 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN); | ||
493 | if (sibling) { | ||
494 | if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) { | ||
495 | recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
496 | recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
497 | changed_tiling = true; | ||
498 | } else { | ||
499 | if (parent->height < min_sane_h) { | ||
500 | //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
501 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
502 | pointer_state.lock.temp_up = true; | ||
503 | } else if (sibling->height < min_sane_h) { | ||
504 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
505 | pointer_state.lock.temp_down = true; | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | } | ||
510 | } else if (!pointer_state.lock.top) { | ||
511 | while (parent->type != C_WORKSPACE) { | ||
512 | if (fabs(parent->parent->y - view->y) <= 1) { | ||
513 | parent = parent->parent; | ||
514 | } else { | ||
515 | break; | ||
516 | } | ||
517 | } | ||
518 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
519 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP); | ||
520 | if (sibling) { | ||
521 | if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) { | ||
522 | recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
523 | recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
524 | changed_tiling = true; | ||
525 | } else { | ||
526 | if (parent->height < min_sane_h) { | ||
527 | //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
528 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
529 | pointer_state.lock.temp_down = true; | ||
530 | } else if (sibling->height < min_sane_h) { | ||
531 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
532 | pointer_state.lock.temp_up = true; | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | |||
539 | parent = view; | ||
540 | if (!pointer_state.lock.right) { | ||
541 | while (parent->type != C_WORKSPACE) { | ||
542 | if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) { | ||
543 | parent = parent->parent; | ||
544 | } else { | ||
545 | sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width); | ||
546 | break; | ||
547 | } | ||
548 | } | ||
549 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
550 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT); | ||
551 | if (sibling) { | ||
552 | if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) { | ||
553 | recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT); | ||
554 | recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
555 | changed_tiling = true; | ||
556 | } else { | ||
557 | if (parent->width < min_sane_w) { | ||
558 | pointer_state.lock.temp_left = true; | ||
559 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
560 | } else if (sibling->width < min_sane_w) { | ||
561 | pointer_state.lock.temp_right = true; | ||
562 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
563 | } | 390 | } |
564 | } | 391 | } |
565 | } | ||
566 | } | ||
567 | } else if (!pointer_state.lock.left) { | ||
568 | while (parent->type != C_WORKSPACE) { | ||
569 | if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) { | ||
570 | parent = parent->parent; | ||
571 | } else { | ||
572 | break; | 392 | break; |
573 | } | 393 | } |
574 | } | 394 | } |
575 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
576 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT); | ||
577 | if (sibling) { | ||
578 | if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) { | ||
579 | recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
580 | recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT); | ||
581 | changed_tiling = true; | ||
582 | } else { | ||
583 | if (parent->width < min_sane_w) { | ||
584 | pointer_state.lock.temp_right = true; | ||
585 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
586 | } else if (sibling->width < min_sane_w) { | ||
587 | pointer_state.lock.temp_left = true; | ||
588 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
589 | } | ||
590 | } | ||
591 | } | ||
592 | } | ||
593 | } | 395 | } |
594 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
595 | } | 396 | } |
397 | } else if (pointer_state.floating.resize && view) { | ||
398 | changed_floating = resize_floating(prev_pos); | ||
399 | } else if (pointer_state.tiling.resize && view) { | ||
400 | changed_tiling = mouse_resize_tiled(prev_pos); | ||
596 | } | 401 | } |
597 | if (config->focus_follows_mouse && prev_handle != handle) { | 402 | if (config->focus_follows_mouse && prev_handle != handle) { |
598 | // Dont change focus if fullscreen | 403 | // Dont change focus if fullscreen |
@@ -604,21 +409,7 @@ static bool handle_pointer_motion(wlc_handle handle, uint32_t time, const struct | |||
604 | } | 409 | } |
605 | prev_handle = handle; | 410 | prev_handle = handle; |
606 | prev_pos = mouse_origin; | 411 | prev_pos = mouse_origin; |
607 | if (changed_floating) { | 412 | if (changed_tiling || changed_floating) { |
608 | struct wlc_geometry geometry = { | ||
609 | .origin = { | ||
610 | .x = view->x, | ||
611 | .y = view->y | ||
612 | }, | ||
613 | .size = { | ||
614 | .w = view->width, | ||
615 | .h = view->height | ||
616 | } | ||
617 | }; | ||
618 | wlc_view_set_geometry(view->handle, edge, &geometry); | ||
619 | return true; | ||
620 | } | ||
621 | if (changed_tiling) { | ||
622 | return true; | 413 | return true; |
623 | } | 414 | } |
624 | return false; | 415 | return false; |
@@ -670,6 +461,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
670 | return (pointer_state.floating.drag || pointer_state.floating.resize); | 461 | return (pointer_state.floating.drag || pointer_state.floating.resize); |
671 | } else { | 462 | } else { |
672 | if (modifiers->mods & config->floating_mod) { | 463 | if (modifiers->mods & config->floating_mod) { |
464 | pointer_state.floating.drag = pointer_state.l_held; | ||
673 | pointer_state.tiling.resize = pointer_state.r_held; | 465 | pointer_state.tiling.resize = pointer_state.r_held; |
674 | pointer_state.tiling.init_view = pointer; | 466 | pointer_state.tiling.init_view = pointer; |
675 | // Dont want pointer sent when resizing | 467 | // Dont want pointer sent when resizing |
@@ -682,6 +474,7 @@ static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct w | |||
682 | if (button == M_LEFT_CLICK) { | 474 | if (button == M_LEFT_CLICK) { |
683 | pointer_state.l_held = false; | 475 | pointer_state.l_held = false; |
684 | pointer_state.floating.drag = false; | 476 | pointer_state.floating.drag = false; |
477 | pointer_state.tiling.init_view = NULL; | ||
685 | } | 478 | } |
686 | if (button == M_RIGHT_CLICK) { | 479 | if (button == M_RIGHT_CLICK) { |
687 | pointer_state.r_held = false; | 480 | pointer_state.r_held = false; |
diff --git a/sway/layout.c b/sway/layout.c index 70d9eb21..18ecb1e7 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include "focus.h" | 10 | #include "focus.h" |
11 | 11 | ||
12 | swayc_t root_container; | 12 | swayc_t root_container; |
13 | int min_sane_h = 60; | ||
14 | int min_sane_w = 100; | ||
13 | 15 | ||
14 | void init_layout(void) { | 16 | void init_layout(void) { |
15 | root_container.type = C_ROOT; | 17 | root_container.type = C_ROOT; |
diff --git a/sway/resize.c b/sway/resize.c new file mode 100644 index 00000000..a08ef4a1 --- /dev/null +++ b/sway/resize.c | |||
@@ -0,0 +1,491 @@ | |||
1 | #include <wlc/wlc.h> | ||
2 | #include <math.h> | ||
3 | #include "layout.h" | ||
4 | #include "focus.h" | ||
5 | #include "log.h" | ||
6 | #include "input_state.h" | ||
7 | #include "handlers.h" | ||
8 | |||
9 | bool mouse_resize_tiled(struct wlc_origin prev_pos) { | ||
10 | swayc_t *view = container_under_pointer(); | ||
11 | bool valid = true; | ||
12 | bool changed_tiling = false; | ||
13 | double dx = mouse_origin.x - prev_pos.x; | ||
14 | double dy = mouse_origin.y - prev_pos.y; | ||
15 | if (view != pointer_state.tiling.init_view) { | ||
16 | changed_tiling = true; | ||
17 | valid = false; | ||
18 | if (view->type != C_WORKSPACE) { | ||
19 | if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_LEFT) == view) { | ||
20 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
21 | pointer_state.lock.temp_left = true; | ||
22 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_RIGHT) == view) { | ||
23 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
24 | pointer_state.lock.temp_right = true; | ||
25 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_UP) == view) { | ||
26 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
27 | pointer_state.lock.temp_up = true; | ||
28 | } else if (get_swayc_in_direction(pointer_state.tiling.init_view, MOVE_DOWN) == view) { | ||
29 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
30 | pointer_state.lock.temp_down = true; | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | |||
35 | if ((dx < 0 || mouse_origin.x < pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_left) { | ||
36 | changed_tiling = true; | ||
37 | valid = false; | ||
38 | } else if (dx > 0 && pointer_state.lock.temp_left) { | ||
39 | pointer_state.lock.temp_left = false; | ||
40 | pointer_state.tiling.lock_pos.x = 0; | ||
41 | } | ||
42 | |||
43 | if ((dx > 0 || mouse_origin.x > pointer_state.tiling.lock_pos.x) && pointer_state.lock.temp_right) { | ||
44 | changed_tiling = true; | ||
45 | valid = false; | ||
46 | } else if (dx < 0 && pointer_state.lock.temp_right) { | ||
47 | pointer_state.lock.temp_right = false; | ||
48 | pointer_state.tiling.lock_pos.x = 0; | ||
49 | } | ||
50 | |||
51 | if ((dy < 0 || mouse_origin.y < pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_up) { | ||
52 | changed_tiling = true; | ||
53 | valid = false; | ||
54 | } else if (dy > 0 && pointer_state.lock.temp_up) { | ||
55 | pointer_state.lock.temp_up = false; | ||
56 | pointer_state.tiling.lock_pos.y = 0; | ||
57 | } | ||
58 | |||
59 | if ((dy > 0 || mouse_origin.y > pointer_state.tiling.lock_pos.y) && pointer_state.lock.temp_down) { | ||
60 | changed_tiling = true; | ||
61 | valid = false; | ||
62 | } else if (dy < 0 && pointer_state.lock.temp_down) { | ||
63 | pointer_state.lock.temp_down = false; | ||
64 | pointer_state.tiling.lock_pos.y = 0; | ||
65 | } | ||
66 | |||
67 | if (!view->is_floating && valid) { | ||
68 | // Handle layout resizes -- Find the biggest parent container then apply resizes to that | ||
69 | // and its bordering siblings | ||
70 | swayc_t *parent = view; | ||
71 | if (!pointer_state.lock.bottom) { | ||
72 | while (parent->type != C_WORKSPACE) { | ||
73 | // TODO: Absolute value is a bad hack here to compensate for rounding. Find a better | ||
74 | // way of doing this. | ||
75 | if (fabs(parent->parent->y + parent->parent->height - (view->y + view->height)) <= 1) { | ||
76 | parent = parent->parent; | ||
77 | } else { | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
82 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_DOWN); | ||
83 | if (sibling) { | ||
84 | if ((parent->height > min_sane_h || dy > 0) && (sibling->height > min_sane_h || dy < 0)) { | ||
85 | recursive_resize(parent, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
86 | recursive_resize(sibling, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
87 | changed_tiling = true; | ||
88 | } else { | ||
89 | if (parent->height < min_sane_h) { | ||
90 | //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
91 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
92 | pointer_state.lock.temp_up = true; | ||
93 | } else if (sibling->height < min_sane_h) { | ||
94 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
95 | pointer_state.lock.temp_down = true; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | } else if (!pointer_state.lock.top) { | ||
101 | while (parent->type != C_WORKSPACE) { | ||
102 | if (fabs(parent->parent->y - view->y) <= 1) { | ||
103 | parent = parent->parent; | ||
104 | } else { | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | if (parent->parent->children->length > 1 && parent->parent->layout == L_VERT) { | ||
109 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_UP); | ||
110 | if (sibling) { | ||
111 | if ((parent->height > min_sane_h || dy < 0) && (sibling->height > min_sane_h || dy > 0)) { | ||
112 | recursive_resize(parent, -1 * dy, WLC_RESIZE_EDGE_TOP); | ||
113 | recursive_resize(sibling, dy, WLC_RESIZE_EDGE_BOTTOM); | ||
114 | changed_tiling = true; | ||
115 | } else { | ||
116 | if (parent->height < min_sane_h) { | ||
117 | //pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + pointer_state.tiling.init_view->height - 20; | ||
118 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
119 | pointer_state.lock.temp_down = true; | ||
120 | } else if (sibling->height < min_sane_h) { | ||
121 | pointer_state.tiling.lock_pos.y = pointer_state.tiling.init_view->y + 20; | ||
122 | pointer_state.lock.temp_up = true; | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | parent = view; | ||
130 | if (!pointer_state.lock.right) { | ||
131 | while (parent->type != C_WORKSPACE) { | ||
132 | if (fabs(parent->parent->x + parent->parent->width - (view->x + view->width)) <= 1) { | ||
133 | parent = parent->parent; | ||
134 | } else { | ||
135 | sway_log(L_DEBUG, "view: %f vs parent: %f", view->x + view->width, parent->parent->x + parent->parent->width); | ||
136 | break; | ||
137 | } | ||
138 | } | ||
139 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
140 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_RIGHT); | ||
141 | if (sibling) { | ||
142 | if ((parent->width > min_sane_w || dx > 0) && (sibling->width > min_sane_w || dx < 0)) { | ||
143 | recursive_resize(parent, dx, WLC_RESIZE_EDGE_RIGHT); | ||
144 | recursive_resize(sibling, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
145 | changed_tiling = true; | ||
146 | } else { | ||
147 | if (parent->width < min_sane_w) { | ||
148 | pointer_state.lock.temp_left = true; | ||
149 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
150 | } else if (sibling->width < min_sane_w) { | ||
151 | pointer_state.lock.temp_right = true; | ||
152 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + pointer_state.tiling.init_view->width - 20; | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | } else if (!pointer_state.lock.left) { | ||
158 | while (parent->type != C_WORKSPACE) { | ||
159 | if (fabs(parent->parent->x - view->x) <= 1 && parent->parent) { | ||
160 | parent = parent->parent; | ||
161 | } else { | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | if (parent->parent->children->length > 1 && parent->parent->layout == L_HORIZ) { | ||
166 | swayc_t *sibling = get_swayc_in_direction(parent, MOVE_LEFT); | ||
167 | if (sibling) { | ||
168 | if ((parent->width > min_sane_w || dx < 0) && (sibling->width > min_sane_w || dx > 0)) { | ||
169 | recursive_resize(parent, -1 * dx, WLC_RESIZE_EDGE_LEFT); | ||
170 | recursive_resize(sibling, dx, WLC_RESIZE_EDGE_RIGHT); | ||
171 | changed_tiling = true; | ||
172 | } else { | ||
173 | if (parent->width < min_sane_w) { | ||
174 | pointer_state.lock.temp_right = true; | ||
175 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
176 | } else if (sibling->width < min_sane_w) { | ||
177 | pointer_state.lock.temp_left = true; | ||
178 | pointer_state.tiling.lock_pos.x = pointer_state.tiling.init_view->x + 20; | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
185 | } | ||
186 | return changed_tiling; | ||
187 | } | ||
188 | |||
189 | bool resize_floating(struct wlc_origin prev_pos) { | ||
190 | bool changed = false; | ||
191 | swayc_t *view = container_under_pointer(); | ||
192 | uint32_t edge = 0; | ||
193 | int dx = mouse_origin.x - prev_pos.x; | ||
194 | int dy = mouse_origin.y - prev_pos.y; | ||
195 | |||
196 | // Move and resize the view based on the dx/dy and mouse position | ||
197 | int midway_x = view->x + view->width/2; | ||
198 | int midway_y = view->y + view->height/2; | ||
199 | if (dx < 0) { | ||
200 | if (!pointer_state.lock.right) { | ||
201 | if (view->width > min_sane_w) { | ||
202 | changed = true; | ||
203 | view->width += dx; | ||
204 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
205 | } | ||
206 | } else if (mouse_origin.x < midway_x && !pointer_state.lock.left) { | ||
207 | changed = true; | ||
208 | view->x += dx; | ||
209 | view->width -= dx; | ||
210 | edge += WLC_RESIZE_EDGE_LEFT; | ||
211 | } | ||
212 | } else if (dx > 0) { | ||
213 | if (mouse_origin.x > midway_x && !pointer_state.lock.right) { | ||
214 | changed = true; | ||
215 | view->width += dx; | ||
216 | edge += WLC_RESIZE_EDGE_RIGHT; | ||
217 | } else if (!pointer_state.lock.left) { | ||
218 | if (view->width > min_sane_w) { | ||
219 | changed = true; | ||
220 | view->x += dx; | ||
221 | view->width -= dx; | ||
222 | edge += WLC_RESIZE_EDGE_LEFT; | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | |||
227 | if (dy < 0) { | ||
228 | if (!pointer_state.lock.bottom) { | ||
229 | if (view->height > min_sane_h) { | ||
230 | changed = true; | ||
231 | view->height += dy; | ||
232 | edge += WLC_RESIZE_EDGE_BOTTOM; | ||
233 | } | ||
234 | } else if (mouse_origin.y < midway_y && !pointer_state.lock.top) { | ||
235 | changed = true; | ||
236 | view->y += dy; | ||
237 | view->height -= dy; | ||
238 | edge += WLC_RESIZE_EDGE_TOP; | ||
239 | } | ||
240 | } else if (dy > 0) { | ||
241 | if (mouse_origin.y > midway_y && !pointer_state.lock.bottom) { | ||
242 | changed = true; | ||
243 | view->height += dy; | ||
244 | edge += WLC_RESIZE_EDGE_BOTTOM; | ||
245 | } else if (!pointer_state.lock.top) { | ||
246 | if (view->height > min_sane_h) { | ||
247 | changed = true; | ||
248 | view->y += dy; | ||
249 | view->height -= dy; | ||
250 | edge += WLC_RESIZE_EDGE_TOP; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | if (changed) { | ||
255 | struct wlc_geometry geometry = { | ||
256 | .origin = { | ||
257 | .x = view->x, | ||
258 | .y = view->y | ||
259 | }, | ||
260 | .size = { | ||
261 | .w = view->width, | ||
262 | .h = view->height | ||
263 | } | ||
264 | }; | ||
265 | wlc_view_set_geometry(view->handle, edge, &geometry); | ||
266 | } | ||
267 | return changed; | ||
268 | } | ||
269 | |||
270 | bool resize_tiled(int amount, bool use_width) { | ||
271 | swayc_t *parent = get_focused_view(swayc_active_workspace()); | ||
272 | swayc_t *focused = parent; | ||
273 | swayc_t *sibling; | ||
274 | if (!parent) { | ||
275 | return true; | ||
276 | } | ||
277 | // Find the closest parent container which has siblings of the proper layout. | ||
278 | // Then apply the resize to all of them. | ||
279 | int i; | ||
280 | if (use_width) { | ||
281 | int lnumber = 0; | ||
282 | int rnumber = 0; | ||
283 | while (parent->parent) { | ||
284 | if (parent->parent->layout == L_HORIZ) { | ||
285 | for (i = 0; i < parent->parent->children->length; i++) { | ||
286 | sibling = parent->parent->children->items[i]; | ||
287 | if (sibling->x != focused->x) { | ||
288 | if (sibling->x < parent->x) { | ||
289 | lnumber++; | ||
290 | } else if (sibling->x > parent->x) { | ||
291 | rnumber++; | ||
292 | } | ||
293 | } | ||
294 | } | ||
295 | if (rnumber || lnumber) { | ||
296 | break; | ||
297 | } | ||
298 | } | ||
299 | parent = parent->parent; | ||
300 | } | ||
301 | if (parent == &root_container) { | ||
302 | return true; | ||
303 | } | ||
304 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, lnumber, rnumber); | ||
305 | //TODO: Ensure rounding is done in such a way that there are NO pixel leaks | ||
306 | bool valid = true; | ||
307 | for (i = 0; i < parent->parent->children->length; i++) { | ||
308 | sibling = parent->parent->children->items[i]; | ||
309 | if (sibling->x != focused->x) { | ||
310 | if (sibling->x < parent->x) { | ||
311 | double pixels = -1 * amount; | ||
312 | pixels /= lnumber; | ||
313 | if (rnumber) { | ||
314 | if ((sibling->width + pixels/2) < min_sane_w) { | ||
315 | valid = false; | ||
316 | break; | ||
317 | } | ||
318 | } else { | ||
319 | if ((sibling->width + pixels) < min_sane_w) { | ||
320 | valid = false; | ||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | } else if (sibling->x > parent->x) { | ||
325 | double pixels = -1 * amount; | ||
326 | pixels /= rnumber; | ||
327 | if (lnumber) { | ||
328 | if ((sibling->width + pixels/2) < min_sane_w) { | ||
329 | valid = false; | ||
330 | break; | ||
331 | } | ||
332 | } else { | ||
333 | if ((sibling->width + pixels) < min_sane_w) { | ||
334 | valid = false; | ||
335 | break; | ||
336 | } | ||
337 | } | ||
338 | } | ||
339 | } else { | ||
340 | double pixels = amount; | ||
341 | if (parent->width + pixels < min_sane_w) { | ||
342 | valid = false; | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | if (valid) { | ||
348 | for (i = 0; i < parent->parent->children->length; i++) { | ||
349 | sibling = parent->parent->children->items[i]; | ||
350 | if (sibling->x != focused->x) { | ||
351 | if (sibling->x < parent->x) { | ||
352 | double pixels = -1 * amount; | ||
353 | pixels /= lnumber; | ||
354 | if (rnumber) { | ||
355 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_RIGHT); | ||
356 | } else { | ||
357 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_RIGHT); | ||
358 | } | ||
359 | } else if (sibling->x > parent->x) { | ||
360 | double pixels = -1 * amount; | ||
361 | pixels /= rnumber; | ||
362 | if (lnumber) { | ||
363 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_LEFT); | ||
364 | } else { | ||
365 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_LEFT); | ||
366 | } | ||
367 | } | ||
368 | } else { | ||
369 | if (rnumber != 0 && lnumber != 0) { | ||
370 | double pixels = amount; | ||
371 | pixels /= 2; | ||
372 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_LEFT); | ||
373 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_RIGHT); | ||
374 | } else if (rnumber) { | ||
375 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_RIGHT); | ||
376 | } else if (lnumber) { | ||
377 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_LEFT); | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | // Recursive resize does not handle positions, let arrange_windows | ||
382 | // take care of that. | ||
383 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
384 | } | ||
385 | return true; | ||
386 | } else { | ||
387 | int tnumber = 0; | ||
388 | int bnumber = 0; | ||
389 | while (parent->parent) { | ||
390 | if (parent->parent->layout == L_VERT) { | ||
391 | for (i = 0; i < parent->parent->children->length; i++) { | ||
392 | sibling = parent->parent->children->items[i]; | ||
393 | if (sibling->y != focused->y) { | ||
394 | if (sibling->y < parent->y) { | ||
395 | bnumber++; | ||
396 | } else if (sibling->y > parent->y) { | ||
397 | tnumber++; | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | if (bnumber || tnumber) { | ||
402 | break; | ||
403 | } | ||
404 | } | ||
405 | parent = parent->parent; | ||
406 | } | ||
407 | if (parent == &root_container) { | ||
408 | return true; | ||
409 | } | ||
410 | sway_log(L_DEBUG, "Found the proper parent: %p. It has %d b conts, and %d t conts", parent->parent, bnumber, tnumber); | ||
411 | //TODO: Ensure rounding is done in such a way that there are NO pixel leaks | ||
412 | bool valid = true; | ||
413 | for (i = 0; i < parent->parent->children->length; i++) { | ||
414 | sibling = parent->parent->children->items[i]; | ||
415 | if (sibling->y != focused->y) { | ||
416 | if (sibling->y < parent->y) { | ||
417 | double pixels = -1 * amount; | ||
418 | pixels /= bnumber; | ||
419 | if (tnumber) { | ||
420 | if ((sibling->height + pixels/2) < min_sane_h) { | ||
421 | valid = false; | ||
422 | break; | ||
423 | } | ||
424 | } else { | ||
425 | if ((sibling->height + pixels) < min_sane_h) { | ||
426 | valid = false; | ||
427 | break; | ||
428 | } | ||
429 | } | ||
430 | } else if (sibling->y > parent->y) { | ||
431 | double pixels = -1 * amount; | ||
432 | pixels /= tnumber; | ||
433 | if (bnumber) { | ||
434 | if ((sibling->height + pixels/2) < min_sane_h) { | ||
435 | valid = false; | ||
436 | break; | ||
437 | } | ||
438 | } else { | ||
439 | if ((sibling->height + pixels) < min_sane_h) { | ||
440 | valid = false; | ||
441 | break; | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | } else { | ||
446 | double pixels = amount; | ||
447 | if (parent->height + pixels < min_sane_h) { | ||
448 | valid = false; | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | if (valid) { | ||
454 | for (i = 0; i < parent->parent->children->length; i++) { | ||
455 | sibling = parent->parent->children->items[i]; | ||
456 | if (sibling->y != focused->y) { | ||
457 | if (sibling->y < parent->y) { | ||
458 | double pixels = -1 * amount; | ||
459 | pixels /= bnumber; | ||
460 | if (tnumber) { | ||
461 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_BOTTOM); | ||
462 | } else { | ||
463 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_BOTTOM); | ||
464 | } | ||
465 | } else if (sibling->x > parent->x) { | ||
466 | double pixels = -1 * amount; | ||
467 | pixels /= tnumber; | ||
468 | if (bnumber) { | ||
469 | recursive_resize(sibling, pixels/2, WLC_RESIZE_EDGE_TOP); | ||
470 | } else { | ||
471 | recursive_resize(sibling, pixels, WLC_RESIZE_EDGE_TOP); | ||
472 | } | ||
473 | } | ||
474 | } else { | ||
475 | if (bnumber != 0 && tnumber != 0) { | ||
476 | double pixels = amount/2; | ||
477 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_TOP); | ||
478 | recursive_resize(parent, pixels, WLC_RESIZE_EDGE_BOTTOM); | ||
479 | } else if (tnumber) { | ||
480 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_TOP); | ||
481 | } else if (bnumber) { | ||
482 | recursive_resize(parent, amount, WLC_RESIZE_EDGE_BOTTOM); | ||
483 | } | ||
484 | } | ||
485 | } | ||
486 | arrange_windows(swayc_active_workspace(), -1, -1); | ||
487 | } | ||
488 | return true; | ||
489 | } | ||
490 | return true; | ||
491 | } | ||