diff options
Diffstat (limited to 'sway/tree/view.c')
-rw-r--r-- | sway/tree/view.c | 60 |
1 files changed, 51 insertions, 9 deletions
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); |