diff options
author | emersion <contact@emersion.fr> | 2018-11-28 14:08:20 +0100 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2018-11-28 14:08:20 +0100 |
commit | b98563d2d7fd2481188c60c0dafc036a9ca4dd15 (patch) | |
tree | 4ce855c622235ebd43781329bfe0f620db81b3e2 | |
parent | Merge pull request #3199 from emersion/handle-subsurface-destroy (diff) | |
download | sway-b98563d2d7fd2481188c60c0dafc036a9ca4dd15.tar.gz sway-b98563d2d7fd2481188c60c0dafc036a9ca4dd15.tar.zst sway-b98563d2d7fd2481188c60c0dafc036a9ca4dd15.zip |
Fix segfault when destroying unmapped child view
-rw-r--r-- | include/sway/tree/view.h | 1 | ||||
-rw-r--r-- | sway/tree/view.c | 12 |
2 files changed, 10 insertions, 3 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index d74f1bc9..5cc9777b 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h | |||
@@ -195,6 +195,7 @@ struct sway_view_child { | |||
195 | 195 | ||
196 | struct sway_view *view; | 196 | struct sway_view *view; |
197 | struct wlr_surface *surface; | 197 | struct wlr_surface *surface; |
198 | bool mapped; | ||
198 | 199 | ||
199 | struct wl_listener surface_commit; | 200 | struct wl_listener surface_commit; |
200 | struct wl_listener surface_new_subsurface; | 201 | struct wl_listener surface_new_subsurface; |
diff --git a/sway/tree/view.c b/sway/tree/view.c index 0edefc8e..4c46d0e9 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c | |||
@@ -711,8 +711,6 @@ static const struct sway_view_child_impl subsurface_impl = { | |||
711 | .destroy = subsurface_destroy, | 711 | .destroy = subsurface_destroy, |
712 | }; | 712 | }; |
713 | 713 | ||
714 | static void view_child_damage(struct sway_view_child *child, bool whole); | ||
715 | |||
716 | static void subsurface_handle_destroy(struct wl_listener *listener, | 714 | static void subsurface_handle_destroy(struct wl_listener *listener, |
717 | void *data) { | 715 | void *data) { |
718 | struct sway_subsurface *subsurface = | 716 | struct sway_subsurface *subsurface = |
@@ -721,6 +719,8 @@ static void subsurface_handle_destroy(struct wl_listener *listener, | |||
721 | view_child_destroy(child); | 719 | view_child_destroy(child); |
722 | } | 720 | } |
723 | 721 | ||
722 | static void view_child_damage(struct sway_view_child *child, bool whole); | ||
723 | |||
724 | static void view_subsurface_create(struct sway_view *view, | 724 | static void view_subsurface_create(struct sway_view *view, |
725 | struct wlr_subsurface *wlr_subsurface) { | 725 | struct wlr_subsurface *wlr_subsurface) { |
726 | struct sway_subsurface *subsurface = | 726 | struct sway_subsurface *subsurface = |
@@ -734,6 +734,9 @@ static void view_subsurface_create(struct sway_view *view, | |||
734 | 734 | ||
735 | wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); | 735 | wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); |
736 | subsurface->destroy.notify = subsurface_handle_destroy; | 736 | subsurface->destroy.notify = subsurface_handle_destroy; |
737 | |||
738 | subsurface->child.mapped = true; | ||
739 | view_child_damage(&subsurface->child, true); | ||
737 | } | 740 | } |
738 | 741 | ||
739 | static void view_child_damage(struct sway_view_child *child, bool whole) { | 742 | static void view_child_damage(struct sway_view_child *child, bool whole) { |
@@ -778,6 +781,7 @@ static void view_child_handle_surface_map(struct wl_listener *listener, | |||
778 | void *data) { | 781 | void *data) { |
779 | struct sway_view_child *child = | 782 | struct sway_view_child *child = |
780 | wl_container_of(listener, child, surface_map); | 783 | wl_container_of(listener, child, surface_map); |
784 | child->mapped = true; | ||
781 | view_child_damage(child, true); | 785 | view_child_damage(child, true); |
782 | } | 786 | } |
783 | 787 | ||
@@ -786,6 +790,7 @@ static void view_child_handle_surface_unmap(struct wl_listener *listener, | |||
786 | struct sway_view_child *child = | 790 | struct sway_view_child *child = |
787 | wl_container_of(listener, child, surface_unmap); | 791 | wl_container_of(listener, child, surface_unmap); |
788 | view_child_damage(child, true); | 792 | view_child_damage(child, true); |
793 | child->mapped = false; | ||
789 | } | 794 | } |
790 | 795 | ||
791 | void view_child_init(struct sway_view_child *child, | 796 | void view_child_init(struct sway_view_child *child, |
@@ -804,6 +809,7 @@ void view_child_init(struct sway_view_child *child, | |||
804 | wl_signal_add(&surface->events.destroy, &child->surface_destroy); | 809 | wl_signal_add(&surface->events.destroy, &child->surface_destroy); |
805 | child->surface_destroy.notify = view_child_handle_surface_destroy; | 810 | child->surface_destroy.notify = view_child_handle_surface_destroy; |
806 | 811 | ||
812 | // Not all child views have a map/unmap event | ||
807 | child->surface_map.notify = view_child_handle_surface_map; | 813 | child->surface_map.notify = view_child_handle_surface_map; |
808 | child->surface_unmap.notify = view_child_handle_surface_unmap; | 814 | child->surface_unmap.notify = view_child_handle_surface_unmap; |
809 | 815 | ||
@@ -814,7 +820,7 @@ void view_child_init(struct sway_view_child *child, | |||
814 | } | 820 | } |
815 | 821 | ||
816 | void view_child_destroy(struct sway_view_child *child) { | 822 | void view_child_destroy(struct sway_view_child *child) { |
817 | if (child->view->container != NULL) { | 823 | if (child->mapped && child->view->container != NULL) { |
818 | view_child_damage(child, true); | 824 | view_child_damage(child, true); |
819 | } | 825 | } |
820 | 826 | ||