summaryrefslogtreecommitdiffstats
path: root/sway/tree
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-31 18:41:30 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-31 18:41:30 +1000
commitde86d65627e96cffe77f4abf11c4a0b982326ff9 (patch)
tree1a3a914fdf561884b1bb0425d51d15684b629b3a /sway/tree
parentMerge pull request #2390 from emersion/fix-fullscreen-segfault (diff)
downloadsway-de86d65627e96cffe77f4abf11c4a0b982326ff9.tar.gz
sway-de86d65627e96cffe77f4abf11c4a0b982326ff9.tar.zst
sway-de86d65627e96cffe77f4abf11c4a0b982326ff9.zip
Fix popups
Fixes the render and container_at order for popups. Fixes #2210 For rendering: * render_view_surfaces has been renamed to render_view_toplevels * render_view_toplevels now uses output_surface_for_each_surface (which is now public), as that function uses wlr_surface_for_each_surface which doesn't descend into popups * Views now have a for_each_popup iterator, which is used by the renderer to render the focused view's popups * When rendering a popup, toplevels (xdg subsurfaces) of that popup are also rendered For sending frame done, the logic has been updated to match the rendering logic: * send_frame_done_container no longer descends into popups * for_each_popup is used to send frame done to the focused view's popups and their child toplevels For container_at: * floating_container_at is now static, which means it had to be moved higher in the file. * container_at now considers popups for the focused view before checking containers. * tiling_container_at has been introduced, so that it doesn't call container_at recursively (it would check popups recursively if it did)
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/container.c134
-rw-r--r--sway/tree/view.c10
2 files changed, 106 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
569static 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
643struct sway_container *container_at(struct sway_container *parent, 648static 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
675struct 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
679static 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
706static 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
734struct 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
705void container_for_each_descendant_dfs(struct sway_container *container, 763void 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) {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 8f54cc11..c1207821 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -332,6 +332,16 @@ void view_for_each_surface(struct sway_view *view,
332 } 332 }
333} 333}
334 334
335void view_for_each_popup(struct sway_view *view,
336 wlr_surface_iterator_func_t iterator, void *user_data) {
337 if (!view->surface) {
338 return;
339 }
340 if (view->impl->for_each_popup) {
341 view->impl->for_each_popup(view, iterator, user_data);
342 }
343}
344
335static void view_subsurface_create(struct sway_view *view, 345static void view_subsurface_create(struct sway_view *view,
336 struct wlr_subsurface *subsurface); 346 struct wlr_subsurface *subsurface);
337 347