summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurkan Sahin <furkan-dev@proton.me>2018-11-26 23:57:33 +0100
committerFurkan Sahin <furkan-dev@proton.me>2018-11-26 23:57:33 +0100
commitfb2e6df6215fbcca3fcca1195eb24821ef3389af (patch)
tree3b45b771c4a0ff205de5431f043ad8b0298ba499
parent12e7e5c5b3a5d15f2cce95fa3a6b38f3ce416db9 (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) {