summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <[email protected]>2018-11-26 23:57:33 +0100
committeremersion <[email protected]>2018-11-27 11:46:30 +0100
commitfc79b7c2d27af881c57d193667d1efb2f7f90eb5 (patch)
tree3b45b771c4a0ff205de5431f043ad8b0298ba499
parentdbf8e1cead12ba775a9a702140576c5f7406c380 (diff)
Handle destroyed subsurfaces
Damage subsurfaces when they are destroyed. Since subsurfaces don't have an unmap event we need to do that on destroy. We also don't want to keep a sway_view_child when the wlr_subsurface has been destroyed. Fixes https://github.com/swaywm/sway/issues/3197
-rw-r--r--include/sway/tree/view.h6
-rw-r--r--sway/tree/view.c39
2 files changed, 41 insertions, 4 deletions
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 4716c688..d74f1bc9 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -203,6 +203,12 @@ struct sway_view_child {
struct wl_listener surface_destroy;
};
+struct sway_subsurface {
+ struct sway_view_child child;
+
+ struct wl_listener destroy;
+};
+
struct sway_xdg_popup_v6 {
struct sway_view_child child;
diff --git a/sway/tree/view.c b/sway/tree/view.c
index febba3b9..c56b96f9 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -674,6 +674,8 @@ void view_update_size(struct sway_view *view, int width, int height) {
container_set_geometry_from_content(view->container);
}
+static const struct sway_view_child_impl subsurface_impl;
+
static void subsurface_get_root_coords(struct sway_view_child *child,
int *root_sx, int *root_sy) {
struct wlr_surface *surface = child->surface;
@@ -689,18 +691,47 @@ static void subsurface_get_root_coords(struct sway_view_child *child,
}
}
+static void subsurface_destroy(struct sway_view_child *child) {
+ if (!sway_assert(child->impl == &subsurface_impl,
+ "Expected a subsurface")) {
+ return;
+ }
+ struct sway_subsurface *subsurface = (struct sway_subsurface *)child;
+ wl_list_remove(&subsurface->destroy.link);
+ free(subsurface);
+}
+
static const struct sway_view_child_impl subsurface_impl = {
.get_root_coords = subsurface_get_root_coords,
+ .destroy = subsurface_destroy,
};
+static void view_child_damage(struct sway_view_child *child, bool whole);
+
+static void subsurface_handle_destroy(struct wl_listener *listener,
+ void *data) {
+ struct sway_subsurface *subsurface =
+ wl_container_of(listener, subsurface, destroy);
+ struct sway_view_child *child = &subsurface->child;
+ if (child->view->container != NULL) {
+ view_child_damage(child, true);
+ }
+ view_child_destroy(child);
+}
+
static void view_subsurface_create(struct sway_view *view,
- struct wlr_subsurface *subsurface) {
- struct sway_view_child *child = calloc(1, sizeof(struct sway_view_child));
- if (child == NULL) {
+ struct wlr_subsurface *wlr_subsurface) {
+ struct sway_subsurface *subsurface =
+ calloc(1, sizeof(struct sway_subsurface));
+ if (subsurface == NULL) {
wlr_log(WLR_ERROR, "Allocation failed");
return;
}
- view_child_init(child, &subsurface_impl, view, subsurface->surface);
+ view_child_init(&subsurface->child, &subsurface_impl, view,
+ wlr_subsurface->surface);
+
+ wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
+ subsurface->destroy.notify = subsurface_handle_destroy;
}
static void view_child_damage(struct sway_view_child *child, bool whole) {