aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2017-09-30 13:24:59 -0400
committerTony Crisci <tony@dubstepdish.com>2017-09-30 13:24:59 -0400
commit8b7ae61ad4e8c991982cb15d46687ffbe6168530 (patch)
tree4c7e9d9717715ddfc5e5612e0d080108deb6ab65
parent4c1bd9bde8e56814ca9c73b138bd8c9dc0469062 (diff)
subsurface handle parent destroy
-rw-r--r--include/wlr/types/wlr_surface.h2
-rw-r--r--types/wlr_surface.c29
2 files changed, 28 insertions, 3 deletions
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 38d6b453..ae278815 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -52,6 +52,8 @@ struct wlr_subsurface {
struct wl_list parent_link;
struct wl_list parent_pending_link;
+
+ struct wl_listener parent_destroy_listener;
};
struct wlr_surface {
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 8c084ceb..e44ea9fc 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -537,7 +537,13 @@ static void wlr_surface_state_destroy(struct wlr_surface_state *state) {
void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) {
wlr_surface_state_destroy(subsurface->cached);
- wl_list_remove(&subsurface->parent_link);
+
+ if (subsurface->parent) {
+ wl_list_remove(&subsurface->parent_link);
+ wl_list_remove(&subsurface->parent_pending_link);
+ wl_list_remove(&subsurface->parent_destroy_listener.link);
+ }
+
wl_resource_set_user_data(subsurface->resource, NULL);
if (subsurface->surface) {
subsurface->surface->subsurface = NULL;
@@ -742,6 +748,16 @@ static const struct wl_subsurface_interface subsurface_implementation = {
.set_desync = subsurface_set_desync,
};
+static void subsurface_handle_parent_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_subsurface *subsurface =
+ wl_container_of(listener, subsurface, parent_destroy_listener);
+ wl_list_remove(&subsurface->parent_link);
+ wl_list_remove(&subsurface->parent_pending_link);
+ wl_list_remove(&subsurface->parent_destroy_listener.link);
+ subsurface->parent = NULL;
+}
+
void wlr_surface_make_subsurface(struct wlr_surface *surface,
struct wlr_surface *parent, uint32_t id) {
assert(surface->subsurface == NULL);
@@ -752,11 +768,18 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface,
return;
}
subsurface->cached = wlr_surface_state_create();
-
+ subsurface->synchronized = true;
subsurface->surface = surface;
+
+ // link parent
subsurface->parent = parent;
- subsurface->synchronized = true;
+ wl_signal_add(&parent->signals.destroy,
+ &subsurface->parent_destroy_listener);
+ subsurface->parent_destroy_listener.notify =
+ subsurface_handle_parent_destroy;
wl_list_insert(&parent->subsurface_list, &subsurface->parent_link);
+ wl_list_insert(&parent->subsurface_pending_list,
+ &subsurface->parent_pending_link);
struct wl_client *client = wl_resource_get_client(surface->resource);