summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Ashworth <bosrsf04@gmail.com>2019-03-09 02:23:20 -0500
committerDrew DeVault <sir@cmpwn.com>2019-03-11 10:57:16 -0400
commit4284de1c7b4ef56011f95f5f126e808312dd2cc3 (patch)
treeff80ce1a11e57b1a4485bd08ba01e2d4346279ca
parentc01a3ca538ae53e9981e99b3aecadca23b1737ba (diff)
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 5cc9777b4..ac203ac79 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -202,6 +202,7 @@ struct sway_view_child {
struct wl_listener surface_map;
struct wl_listener surface_unmap;
struct wl_listener surface_destroy;
+ struct wl_listener view_unmap;
};
struct sway_subsurface {
diff --git a/sway/tree/view.c b/sway/tree/view.c
index ca13def72..293b5c58a 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,
child->mapped = false;
}
+static void view_child_handle_view_unmap(struct wl_listener *listener,
+ void *data) {
+ struct sway_view_child *child =
+ wl_container_of(listener, child, view_unmap);
+ view_child_damage(child, true);
+ child->mapped = false;
+}
+
void view_child_init(struct sway_view_child *child,
const struct sway_view_child_impl *impl, struct sway_view *view,
struct wlr_surface *surface) {
@@ -837,6 +845,9 @@ void view_child_init(struct sway_view_child *child,
child->surface_map.notify = view_child_handle_surface_map;
child->surface_unmap.notify = view_child_handle_surface_unmap;
+ wl_signal_add(&view->events.unmap, &child->view_unmap);
+ child->view_unmap.notify = view_child_handle_view_unmap;
+
struct sway_output *output = child->view->container->workspace->output;
wlr_surface_send_enter(child->surface, output->wlr_output);
@@ -850,6 +861,7 @@ void view_child_destroy(struct sway_view_child *child) {
wl_list_remove(&child->surface_commit.link);
wl_list_remove(&child->surface_destroy.link);
+ wl_list_remove(&child->view_unmap.link);
if (child->impl && child->impl->destroy) {
child->impl->destroy(child);