aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/container.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-02 23:30:26 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-08-02 23:36:36 +1000
commit8392eae40f17e550338b8b7058d8e9c1a6ad4f78 (patch)
treeffefcdd261970549f8b83adae8d93b6c3b9ebbbb /sway/tree/container.c
parentMerge pull request #2366 from RedSoxFan/nagbar (diff)
downloadsway-8392eae40f17e550338b8b7058d8e9c1a6ad4f78.tar.gz
sway-8392eae40f17e550338b8b7058d8e9c1a6ad4f78.tar.zst
sway-8392eae40f17e550338b8b7058d8e9c1a6ad4f78.zip
Revert "Revert "Fix popups""
This reverts commit 9aa258d33a9baa42895214da7e82f4568fcb8f76. Reverting the revert, so that popups can be fixed.
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r--sway/tree/container.c134
1 files changed, 96 insertions, 38 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index b6ff4d30..b980c5e9 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -569,10 +569,15 @@ static struct sway_container *container_at_view(struct sway_container *swayc,
569 *sx = _sx; 569 *sx = _sx;
570 *sy = _sy; 570 *sy = _sy;
571 *surface = _surface; 571 *surface = _surface;
572 return swayc;
572 } 573 }
573 return swayc; 574 return NULL;
574} 575}
575 576
577static struct sway_container *tiling_container_at(
578 struct sway_container *con, double lx, double ly,
579 struct wlr_surface **surface, double *sx, double *sy);
580
576/** 581/**
577 * container_at for a container with layout L_TABBED. 582 * container_at for a container with layout L_TABBED.
578 */ 583 */
@@ -599,7 +604,7 @@ static struct sway_container *container_at_tabbed(struct sway_container *parent,
599 // Surfaces 604 // Surfaces
600 struct sway_container *current = seat_get_active_child(seat, parent); 605 struct sway_container *current = seat_get_active_child(seat, parent);
601 606
602 return container_at(current, lx, ly, surface, sx, sy); 607 return tiling_container_at(current, lx, ly, surface, sx, sy);
603} 608}
604 609
605/** 610/**
@@ -624,7 +629,7 @@ static struct sway_container *container_at_stacked(
624 // Surfaces 629 // Surfaces
625 struct sway_container *current = seat_get_active_child(seat, parent); 630 struct sway_container *current = seat_get_active_child(seat, parent);
626 631
627 return container_at(current, lx, ly, surface, sx, sy); 632 return tiling_container_at(current, lx, ly, surface, sx, sy);
628} 633}
629 634
630/** 635/**
@@ -642,45 +647,13 @@ static struct sway_container *container_at_linear(struct sway_container *parent,
642 .height = child->height, 647 .height = child->height,
643 }; 648 };
644 if (wlr_box_contains_point(&box, lx, ly)) { 649 if (wlr_box_contains_point(&box, lx, ly)) {
645 return container_at(child, lx, ly, surface, sx, sy); 650 return tiling_container_at(child, lx, ly, surface, sx, sy);
646 } 651 }
647 } 652 }
648 return NULL; 653 return NULL;
649} 654}
650 655
651struct sway_container *container_at(struct sway_container *parent, 656static struct sway_container *floating_container_at(double lx, double ly,
652 double lx, double ly,
653 struct wlr_surface **surface, double *sx, double *sy) {
654 if (!sway_assert(parent->type >= C_WORKSPACE,
655 "Expected workspace or deeper")) {
656 return NULL;
657 }
658 if (parent->type == C_VIEW) {
659 return container_at_view(parent, lx, ly, surface, sx, sy);
660 }
661 if (!parent->children->length) {
662 return NULL;
663 }
664
665 switch (parent->layout) {
666 case L_HORIZ:
667 case L_VERT:
668 return container_at_linear(parent, lx, ly, surface, sx, sy);
669 case L_TABBED:
670 return container_at_tabbed(parent, lx, ly, surface, sx, sy);
671 case L_STACKED:
672 return container_at_stacked(parent, lx, ly, surface, sx, sy);
673 case L_FLOATING:
674 sway_assert(false, "Didn't expect to see floating here");
675 return NULL;
676 case L_NONE:
677 return NULL;
678 }
679
680 return NULL;
681}
682
683struct sway_container *floating_container_at(double lx, double ly,
684 struct wlr_surface **surface, double *sx, double *sy) { 657 struct wlr_surface **surface, double *sx, double *sy) {
685 for (int i = 0; i < root_container.children->length; ++i) { 658 for (int i = 0; i < root_container.children->length; ++i) {
686 struct sway_container *output = root_container.children->items[i]; 659 struct sway_container *output = root_container.children->items[i];
@@ -702,7 +675,8 @@ struct sway_container *floating_container_at(double lx, double ly,
702 .height = floater->height, 675 .height = floater->height,
703 }; 676 };
704 if (wlr_box_contains_point(&box, lx, ly)) { 677 if (wlr_box_contains_point(&box, lx, ly)) {
705 return container_at(floater, lx, ly, surface, sx, sy); 678 return tiling_container_at(floater, lx, ly,
679 surface, sx, sy);
706 } 680 }
707 } 681 }
708 } 682 }
@@ -710,6 +684,90 @@ struct sway_container *floating_container_at(double lx, double ly,
710 return NULL; 684 return NULL;
711} 685}
712 686
687static struct sway_container *tiling_container_at(
688 struct sway_container *con, double lx, double ly,
689 struct wlr_surface **surface, double *sx, double *sy) {
690 if (con->type == C_VIEW) {
691 return container_at_view(con, lx, ly, surface, sx, sy);
692 }
693 if (!con->children->length) {
694 return NULL;
695 }
696
697 switch (con->layout) {
698 case L_HORIZ:
699 case L_VERT:
700 return container_at_linear(con, lx, ly, surface, sx, sy);
701 case L_TABBED:
702 return container_at_tabbed(con, lx, ly, surface, sx, sy);
703 case L_STACKED:
704 return container_at_stacked(con, lx, ly, surface, sx, sy);
705 case L_FLOATING:
706 sway_assert(false, "Didn't expect to see floating here");
707 return NULL;
708 case L_NONE:
709 return NULL;
710 }
711 return NULL;
712}
713
714static bool surface_is_popup(struct wlr_surface *surface) {
715 if (wlr_surface_is_xdg_surface(surface)) {
716 struct wlr_xdg_surface *xdg_surface =
717 wlr_xdg_surface_from_wlr_surface(surface);
718 while (xdg_surface) {
719 if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
720 return true;
721 }
722 xdg_surface = xdg_surface->toplevel->parent;
723 }
724 return false;
725 }
726
727 if (wlr_surface_is_xdg_surface_v6(surface)) {
728 struct wlr_xdg_surface_v6 *xdg_surface_v6 =
729 wlr_xdg_surface_v6_from_wlr_surface(surface);
730 while (xdg_surface_v6) {
731 if (xdg_surface_v6->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) {
732 return true;
733 }
734 xdg_surface_v6 = xdg_surface_v6->toplevel->parent;
735 }
736 return false;
737 }
738
739 return false;
740}
741
742struct sway_container *container_at(struct sway_container *workspace,
743 double lx, double ly,
744 struct wlr_surface **surface, double *sx, double *sy) {
745 if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) {
746 return NULL;
747 }
748 struct sway_container *c;
749 // Focused view's popups
750 struct sway_seat *seat = input_manager_current_seat(input_manager);
751 struct sway_container *focus =
752 seat_get_focus_inactive(seat, &root_container);
753 if (focus && focus->type == C_VIEW) {
754 container_at_view(focus, lx, ly, surface, sx, sy);
755 if (*surface && surface_is_popup(*surface)) {
756 return focus;
757 }
758 *surface = NULL;
759 }
760 // Floating
761 if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
762 return c;
763 }
764 // Tiling
765 if ((c = tiling_container_at(workspace, lx, ly, surface, sx, sy))) {
766 return c;
767 }
768 return NULL;
769}
770
713void container_for_each_descendant_dfs(struct sway_container *container, 771void container_for_each_descendant_dfs(struct sway_container *container,
714 void (*f)(struct sway_container *container, void *data), 772 void (*f)(struct sway_container *container, void *data),
715 void *data) { 773 void *data) {