diff options
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 134 |
1 files changed, 96 insertions, 38 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index 4e85021d..b5fefd17 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -561,10 +561,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc, | |||
561 | *sx = _sx; | 561 | *sx = _sx; |
562 | *sy = _sy; | 562 | *sy = _sy; |
563 | *surface = _surface; | 563 | *surface = _surface; |
564 | return swayc; | ||
564 | } | 565 | } |
565 | return swayc; | 566 | return NULL; |
566 | } | 567 | } |
567 | 568 | ||
569 | static struct sway_container *tiling_container_at( | ||
570 | struct sway_container *con, double lx, double ly, | ||
571 | struct wlr_surface **surface, double *sx, double *sy); | ||
572 | |||
568 | /** | 573 | /** |
569 | * container_at for a container with layout L_TABBED. | 574 | * container_at for a container with layout L_TABBED. |
570 | */ | 575 | */ |
@@ -591,7 +596,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent, | |||
591 | // Surfaces | 596 | // Surfaces |
592 | struct sway_container *current = seat_get_active_child(seat, parent); | 597 | struct sway_container *current = seat_get_active_child(seat, parent); |
593 | 598 | ||
594 | return container_at(current, lx, ly, surface, sx, sy); | 599 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
595 | } | 600 | } |
596 | 601 | ||
597 | /** | 602 | /** |
@@ -616,7 +621,7 @@ static struct sway_container *container_at_stacked( | |||
616 | // Surfaces | 621 | // Surfaces |
617 | struct sway_container *current = seat_get_active_child(seat, parent); | 622 | struct sway_container *current = seat_get_active_child(seat, parent); |
618 | 623 | ||
619 | return container_at(current, lx, ly, surface, sx, sy); | 624 | return tiling_container_at(current, lx, ly, surface, sx, sy); |
620 | } | 625 | } |
621 | 626 | ||
622 | /** | 627 | /** |
@@ -634,45 +639,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent, | |||
634 | .height = child->height, | 639 | .height = child->height, |
635 | }; | 640 | }; |
636 | if (wlr_box_contains_point(&box, lx, ly)) { | 641 | if (wlr_box_contains_point(&box, lx, ly)) { |
637 | return container_at(child, lx, ly, surface, sx, sy); | 642 | return tiling_container_at(child, lx, ly, surface, sx, sy); |
638 | } | 643 | } |
639 | } | 644 | } |
640 | return NULL; | 645 | return NULL; |
641 | } | 646 | } |
642 | 647 | ||
643 | struct sway_container *container_at(struct sway_container *parent, | 648 | static struct sway_container *floating_container_at(double lx, double ly, |
644 | double lx, double ly, | ||
645 | struct wlr_surface **surface, double *sx, double *sy) { | ||
646 | if (!sway_assert(parent->type >= C_WORKSPACE, | ||
647 | "Expected workspace or deeper")) { | ||
648 | return NULL; | ||
649 | } | ||
650 | if (parent->type == C_VIEW) { | ||
651 | return container_at_view(parent, lx, ly, surface, sx, sy); | ||
652 | } | ||
653 | if (!parent->children->length) { | ||
654 | return NULL; | ||
655 | } | ||
656 | |||
657 | switch (parent->layout) { | ||
658 | case L_HORIZ: | ||
659 | case L_VERT: | ||
660 | return container_at_linear(parent, lx, ly, surface, sx, sy); | ||
661 | case L_TABBED: | ||
662 | return container_at_tabbed(parent, lx, ly, surface, sx, sy); | ||
663 | case L_STACKED: | ||
664 | return container_at_stacked(parent, lx, ly, surface, sx, sy); | ||
665 | case L_FLOATING: | ||
666 | sway_assert(false, "Didn't expect to see floating here"); | ||
667 | return NULL; | ||
668 | case L_NONE: | ||
669 | return NULL; | ||
670 | } | ||
671 | |||
672 | return NULL; | ||
673 | } | ||
674 | |||
675 | struct sway_container *floating_container_at(double lx, double ly, | ||
676 | struct wlr_surface **surface, double *sx, double *sy) { | 649 | struct wlr_surface **surface, double *sx, double *sy) { |
677 | for (int i = 0; i < root_container.children->length; ++i) { | 650 | for (int i = 0; i < root_container.children->length; ++i) { |
678 | struct sway_container *output = root_container.children->items[i]; | 651 | struct sway_container *output = root_container.children->items[i]; |
@@ -694,7 +667,8 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
694 | .height = floater->height, | 667 | .height = floater->height, |
695 | }; | 668 | }; |
696 | if (wlr_box_contains_point(&box, lx, ly)) { | 669 | if (wlr_box_contains_point(&box, lx, ly)) { |
697 | return container_at(floater, lx, ly, surface, sx, sy); | 670 | return tiling_container_at(floater, lx, ly, |
671 | surface, sx, sy); | ||
698 | } | 672 | } |
699 | } | 673 | } |
700 | } | 674 | } |
@@ -702,6 +676,90 @@ struct sway_container *floating_container_at(double lx, double ly, | |||
702 | return NULL; | 676 | return NULL; |
703 | } | 677 | } |
704 | 678 | ||
679 | static struct sway_container *tiling_container_at( | ||
680 | struct sway_container *con, double lx, double ly, | ||
681 | struct wlr_surface **surface, double *sx, double *sy) { | ||
682 | if (con->type == C_VIEW) { | ||
683 | return container_at_view(con, lx, ly, surface, sx, sy); | ||
684 | } | ||
685 | if (!con->children->length) { | ||
686 | return NULL; | ||
687 | } | ||
688 | |||
689 | switch (con->layout) { | ||
690 | case L_HORIZ: | ||
691 | case L_VERT: | ||
692 | return container_at_linear(con, lx, ly, surface, sx, sy); | ||
693 | case L_TABBED: | ||
694 | return container_at_tabbed(con, lx, ly, surface, sx, sy); | ||
695 | case L_STACKED: | ||
696 | return container_at_stacked(con, lx, ly, surface, sx, sy); | ||
697 | case L_FLOATING: | ||
698 | sway_assert(false, "Didn't expect to see floating here"); | ||
699 | return NULL; | ||
700 | case L_NONE: | ||
701 | return NULL; | ||
702 | } | ||
703 | return NULL; | ||
704 | } | ||
705 | |||
706 | static bool surface_is_popup(struct wlr_surface *surface) { | ||
707 | if (wlr_surface_is_xdg_surface(surface)) { | ||
708 | struct wlr_xdg_surface *xdg_surface = | ||
709 | wlr_xdg_surface_from_wlr_surface(surface); | ||
710 | while (xdg_surface) { | ||
711 | if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
712 | return true; | ||
713 | } | ||
714 | xdg_surface = xdg_surface->toplevel->parent; | ||
715 | } | ||
716 | return false; | ||
717 | } | ||
718 | |||
719 | if (wlr_surface_is_xdg_surface_v6(surface)) { | ||
720 | struct wlr_xdg_surface_v6 *xdg_surface_v6 = | ||
721 | wlr_xdg_surface_v6_from_wlr_surface(surface); | ||
722 | while (xdg_surface_v6) { | ||
723 | if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||
724 | return true; | ||
725 | } | ||
726 | xdg_surface_v6 = xdg_surface_v6->toplevel->parent; | ||
727 | } | ||
728 | return false; | ||
729 | } | ||
730 | |||
731 | return false; | ||
732 | } | ||
733 | |||
734 | struct sway_container *container_at(struct sway_container *workspace, | ||
735 | double lx, double ly, | ||
736 | struct wlr_surface **surface, double *sx, double *sy) { | ||
737 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
738 | return NULL; | ||
739 | } | ||
740 | struct sway_container *c; | ||
741 | // Focused view's popups | ||
742 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
743 | struct sway_container *focus = | ||
744 | seat_get_focus_inactive(seat, &root_container); | ||
745 | if (focus && focus->type == C_VIEW) { | ||
746 | container_at_view(focus, lx, ly, surface, sx, sy); | ||
747 | if (*surface && surface_is_popup(*surface)) { | ||
748 | return focus; | ||
749 | } | ||
750 | *surface = NULL; | ||
751 | } | ||
752 | // Floating | ||
753 | if ((c = floating_container_at(lx, ly, surface, sx, sy))) { | ||
754 | return c; | ||
755 | } | ||
756 | // Tiling | ||
757 | if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) { | ||
758 | return c; | ||
759 | } | ||
760 | return NULL; | ||
761 | } | ||
762 | |||
705 | void container_for_each_descendant_dfs(struct sway_container *container, | 763 | void container_for_each_descendant_dfs(struct sway_container *container, |
706 | void (*f)(struct sway_container *container, void *data), | 764 | void (*f)(struct sway_container *container, void *data), |
707 | void *data) { | 765 | void *data) { |