diff options
-rw-r--r-- | include/sway/tree/view.h | 3 | ||||
-rw-r--r-- | sway/tree/view.c | 60 |
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 | */ |
193 | struct sway_view_child { | 193 | struct 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 | |||
795 | static 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 | ||
812 | static void view_child_handle_surface_destroy(struct wl_listener *listener, | 842 | static 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); |