@@ -728,15 +728,23 @@ static void subsurface_get_root_coords(struct sway_view_child *child,
728
728
* root_sx = - child -> view -> geometry .x ;
729
729
* root_sy = - child -> view -> geometry .y ;
730
730
731
- while (surface && wlr_surface_is_subsurface (surface )) {
732
- struct wlr_subsurface * subsurface =
733
- wlr_subsurface_from_wlr_surface (surface );
734
- if (subsurface == NULL ) {
735
- break ;
731
+ if (child -> parent && child -> parent -> impl &&
732
+ child -> parent -> impl -> get_root_coords ) {
733
+ int sx , sy ;
734
+ child -> parent -> impl -> get_root_coords (child -> parent , & sx , & sy );
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
788
subsurface -> destroy .notify = subsurface_handle_destroy ;
781
789
782
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
813
view_child_damage (& subsurface -> child , true);
784
814
}
785
815
@@ -806,7 +836,7 @@ static void view_child_handle_surface_new_subsurface(
806
836
struct sway_view_child * child =
807
837
wl_container_of (listener , child , surface_new_subsurface );
808
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
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
884
child -> impl = impl ;
855
885
child -> view = view ;
856
886
child -> surface = surface ;
887
+ wl_list_init (& child -> children );
857
888
858
889
wl_signal_add (& surface -> events .commit , & child -> surface_commit );
859
890
child -> surface_commit .notify = view_child_handle_surface_commit ;
@@ -882,6 +913,17 @@ void view_child_destroy(struct sway_view_child *child) {
882
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
927
wl_list_remove (& child -> surface_commit .link );
886
928
wl_list_remove (& child -> surface_destroy .link );
887
929
wl_list_remove (& child -> view_unmap .link );
0 commit comments