aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kenny Levinsen <kl@kl.wtf>2019-05-29 16:08:48 +0200
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-06-03 08:30:28 -0400
commitb06d2eb1eec8547e7c3087c4e42a66251d6c4689 (patch)
tree5abb4d4ac423790906caed48c9680b88949e087e
parentcommon/ipc-client: remove ipc recv timeout log (diff)
downloadsway-b06d2eb1eec8547e7c3087c4e42a66251d6c4689.tar.gz
sway-b06d2eb1eec8547e7c3087c4e42a66251d6c4689.tar.zst
sway-b06d2eb1eec8547e7c3087c4e42a66251d6c4689.zip
Use parent get_root_coords in subsurfaces
Subsurfaces need access to the parent get_root_coords impl for positioning in popups. To do this, we store a reference to the parent view_child where applicable. Fixes #4191.
-rw-r--r--include/sway/tree/view.h3
-rw-r--r--sway/tree/view.c60
2 files changed, 54 insertions, 9 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index bdd8960c..4ce487fc 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -192,8 +192,11 @@ struct sway_view_child_impl {
192 */ 192 */
193struct sway_view_child { 193struct sway_view_child {
194 const struct sway_view_child_impl *impl; 194 const struct sway_view_child_impl *impl;
195 struct wl_list link;
195 196
196 struct sway_view *view; 197 struct sway_view *view;
198 struct sway_view_child *parent;
199 struct wl_list children; // sway_view_child::link
197 struct wlr_surface *surface; 200 struct wlr_surface *surface;
198 bool mapped; 201 bool mapped;
199 202
diff --git a/sway/tree/view.c b/sway/tree/view.c
index e8f5a299..4fd3a65a 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -728,15 +728,23 @@ static void subsurface_get_root_coords(struct sway_view_child *child,
728 *root_sx = -child->view->geometry.x; 728 *root_sx = -child->view->geometry.x;
729 *root_sy = -child->view->geometry.y; 729 *root_sy = -child->view->geometry.y;
730 730
731 while (surface && wlr_surface_is_subsurface(surface)) { 731 if (child->parent && child->parent->impl &&
732 struct wlr_subsurface *subsurface = 732 child->parent->impl->get_root_coords) {
733 wlr_subsurface_from_wlr_surface(surface); 733 int sx, sy;
734 if (subsurface == NULL) { 734 child->parent->impl->get_root_coords(child->parent, &sx, &sy);
735 break; 735 *root_sx += sx;
736 *root_sy += sy;
737 } else {
738 while (surface && wlr_surface_is_subsurface(surface)) {
739 struct wlr_subsurface *subsurface =
740 wlr_subsurface_from_wlr_surface(surface);
741 if (subsurface == NULL) {
742 break;
743 }
744 *root_sx += subsurface->current.x;
745 *root_sy += subsurface->current.y;
746 surface = subsurface->parent;
736 } 747 }
737 *root_sx += subsurface->current.x;
738 *root_sy += subsurface->current.y;
739 surface = subsurface->parent;
740 } 748 }
741} 749}
742 750
@@ -780,6 +788,28 @@ static void view_subsurface_create(struct sway_view *view,
780 subsurface->destroy.notify = subsurface_handle_destroy; 788 subsurface->destroy.notify = subsurface_handle_destroy;
781 789
782 subsurface->child.mapped = true; 790 subsurface->child.mapped = true;
791
792 view_child_damage(&subsurface->child, true);
793}
794
795static void view_child_subsurface_create(struct sway_view_child *child,
796 struct wlr_subsurface *wlr_subsurface) {
797 struct sway_subsurface *subsurface =
798 calloc(1, sizeof(struct sway_subsurface));
799 if (subsurface == NULL) {
800 sway_log(SWAY_ERROR, "Allocation failed");
801 return;
802 }
803 subsurface->child.parent = child;
804 wl_list_insert(&child->children, &subsurface->child.link);
805 view_child_init(&subsurface->child, &subsurface_impl, child->view,
806 wlr_subsurface->surface);
807
808 wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
809 subsurface->destroy.notify = subsurface_handle_destroy;
810
811 subsurface->child.mapped = true;
812
783 view_child_damage(&subsurface->child, true); 813 view_child_damage(&subsurface->child, true);
784} 814}
785 815
@@ -806,7 +836,7 @@ static void view_child_handle_surface_new_subsurface(
806 struct sway_view_child *child = 836 struct sway_view_child *child =
807 wl_container_of(listener, child, surface_new_subsurface); 837 wl_container_of(listener, child, surface_new_subsurface);
808 struct wlr_subsurface *subsurface = data; 838 struct wlr_subsurface *subsurface = data;
809 view_subsurface_create(child->view, subsurface); 839 view_child_subsurface_create(child, subsurface);
810} 840}
811 841
812static void view_child_handle_surface_destroy(struct wl_listener *listener, 842static void view_child_handle_surface_destroy(struct wl_listener *listener,
@@ -854,6 +884,7 @@ void view_child_init(struct sway_view_child *child,
854 child->impl = impl; 884 child->impl = impl;
855 child->view = view; 885 child->view = view;
856 child->surface = surface; 886 child->surface = surface;
887 wl_list_init(&child->children);
857 888
858 wl_signal_add(&surface->events.commit, &child->surface_commit); 889 wl_signal_add(&surface->events.commit, &child->surface_commit);
859 child->surface_commit.notify = view_child_handle_surface_commit; 890 child->surface_commit.notify = view_child_handle_surface_commit;
@@ -882,6 +913,17 @@ void view_child_destroy(struct sway_view_child *child) {
882 view_child_damage(child, true); 913 view_child_damage(child, true);
883 } 914 }
884 915
916 if (child->parent != NULL) {
917 wl_list_remove(&child->link);
918 child->parent = NULL;
919 }
920
921 struct sway_view_child *subchild, *tmpchild;
922 wl_list_for_each_safe(subchild, tmpchild, &child->children, link) {
923 wl_list_remove(&subchild->link);
924 subchild->parent = NULL;
925 }
926
885 wl_list_remove(&child->surface_commit.link); 927 wl_list_remove(&child->surface_commit.link);
886 wl_list_remove(&child->surface_destroy.link); 928 wl_list_remove(&child->surface_destroy.link);
887 wl_list_remove(&child->view_unmap.link); 929 wl_list_remove(&child->view_unmap.link);