aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-03-09 02:23:20 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-03-11 10:57:16 -0400
commit4284de1c7b4ef56011f95f5f126e808312dd2cc3 (patch)
treeff80ce1a11e57b1a4485bd08ba01e2d4346279ca
parentdetect_proprietary: use strncmp (diff)
downloadsway-4284de1c7b4ef56011f95f5f126e808312dd2cc3.tar.gz
sway-4284de1c7b4ef56011f95f5f126e808312dd2cc3.tar.zst
sway-4284de1c7b4ef56011f95f5f126e808312dd2cc3.zip
sway_view_child: add listener for view unmap
Since not all child views's have an unmap event, it is possible for it to still be mapped (default state) in the destruction handler. When the destruction handler is called, the corresponding view may have already been freed and the memory location reallocated. This adds a listener for the view unmapping and removes the mapped status. This ensures that the child view is damaged due to destruction while the view still exists and not after.
-rw-r--r--include/sway/tree/view.h1
-rw-r--r--sway/tree/view.c12
2 files changed, 13 insertions, 0 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 5cc9777b..ac203ac7 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -202,6 +202,7 @@ struct sway_view_child {
202 struct wl_listener surface_map; 202 struct wl_listener surface_map;
203 struct wl_listener surface_unmap; 203 struct wl_listener surface_unmap;
204 struct wl_listener surface_destroy; 204 struct wl_listener surface_destroy;
205 struct wl_listener view_unmap;
205}; 206};
206 207
207struct sway_subsurface { 208struct sway_subsurface {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ca13def7..293b5c58 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -817,6 +817,14 @@ static void view_child_handle_surface_unmap(struct wl_listener *listener,
817 child->mapped = false; 817 child->mapped = false;
818} 818}
819 819
820static void view_child_handle_view_unmap(struct wl_listener *listener,
821 void *data) {
822 struct sway_view_child *child =
823 wl_container_of(listener, child, view_unmap);
824 view_child_damage(child, true);
825 child->mapped = false;
826}
827
820void view_child_init(struct sway_view_child *child, 828void view_child_init(struct sway_view_child *child,
821 const struct sway_view_child_impl *impl, struct sway_view *view, 829 const struct sway_view_child_impl *impl, struct sway_view *view,
822 struct wlr_surface *surface) { 830 struct wlr_surface *surface) {
@@ -837,6 +845,9 @@ void view_child_init(struct sway_view_child *child,
837 child->surface_map.notify = view_child_handle_surface_map; 845 child->surface_map.notify = view_child_handle_surface_map;
838 child->surface_unmap.notify = view_child_handle_surface_unmap; 846 child->surface_unmap.notify = view_child_handle_surface_unmap;
839 847
848 wl_signal_add(&view->events.unmap, &child->view_unmap);
849 child->view_unmap.notify = view_child_handle_view_unmap;
850
840 struct sway_output *output = child->view->container->workspace->output; 851 struct sway_output *output = child->view->container->workspace->output;
841 wlr_surface_send_enter(child->surface, output->wlr_output); 852 wlr_surface_send_enter(child->surface, output->wlr_output);
842 853
@@ -850,6 +861,7 @@ void view_child_destroy(struct sway_view_child *child) {
850 861
851 wl_list_remove(&child->surface_commit.link); 862 wl_list_remove(&child->surface_commit.link);
852 wl_list_remove(&child->surface_destroy.link); 863 wl_list_remove(&child->surface_destroy.link);
864 wl_list_remove(&child->view_unmap.link);
853 865
854 if (child->impl && child->impl->destroy) { 866 if (child->impl && child->impl->destroy) {
855 child->impl->destroy(child); 867 child->impl->destroy(child);