surface: don't destroy surface while compositor has locks

References: https://github.com/swaywm/wlroots/issues/2957
This commit is contained in:
Simon Ser 2021-07-06 14:25:48 +02:00
parent 3fdf8cf07e
commit f0e695582a
2 changed files with 16 additions and 3 deletions

View file

@ -84,7 +84,7 @@ struct wlr_surface_output {
}; };
struct wlr_surface { struct wlr_surface {
struct wl_resource *resource; struct wl_resource *resource; // can be NULL if destroyed by the client
struct wlr_renderer *renderer; struct wlr_renderer *renderer;
/** /**
* The surface's buffer, if any. A surface has an attached buffer when it * The surface's buffer, if any. A surface has an attached buffer when it

View file

@ -683,8 +683,14 @@ static void subsurface_destroy(struct wlr_subsurface *subsurface) {
static void surface_output_destroy(struct wlr_surface_output *surface_output); static void surface_output_destroy(struct wlr_surface_output *surface_output);
static void surface_handle_resource_destroy(struct wl_resource *resource) { /**
struct wlr_surface *surface = wlr_surface_from_resource(resource); * Destroys the wlr_surface if the client has destroyed the protocol object
* and the compositor has released all cache locks.
*/
static void surface_consider_destroy(struct wlr_surface *surface) {
if (surface->resource != NULL || !wl_list_empty(&surface->cached)) {
return;
}
struct wlr_surface_output *surface_output, *surface_output_tmp; struct wlr_surface_output *surface_output, *surface_output_tmp;
wl_list_for_each_safe(surface_output, surface_output_tmp, wl_list_for_each_safe(surface_output, surface_output_tmp,
@ -712,6 +718,11 @@ static void surface_handle_resource_destroy(struct wl_resource *resource) {
free(surface); free(surface);
} }
static void surface_handle_resource_destroy(struct wl_resource *resource) {
struct wlr_surface *surface = wlr_surface_from_resource(resource);
surface_consider_destroy(surface);
}
static void surface_handle_renderer_destroy(struct wl_listener *listener, static void surface_handle_renderer_destroy(struct wl_listener *listener,
void *data) { void *data) {
struct wlr_surface *surface = struct wlr_surface *surface =
@ -847,6 +858,8 @@ void wlr_surface_unlock_cached(struct wlr_surface *surface, uint32_t seq) {
surface_commit_state(surface, next); surface_commit_state(surface, next);
surface_state_destroy_cached(next); surface_state_destroy_cached(next);
} }
surface_consider_destroy(surface);
} }
static const struct wl_subsurface_interface subsurface_implementation; static const struct wl_subsurface_interface subsurface_implementation;