As per the discussion on IRC, i've sent a new one actually destroying the weston_desktop_surface. So, ignore this one.
Cheers, Giulio 2016-09-28 11:13 GMT+02:00 Giulio Camuffo <[email protected]>: > Weston's desktop shell increments the ref_count on the surfaces so that > when the wl_resource of the wl_surface is destroyed the weston_surface > keeps living. In that case, the weston_desktop_surface keeps living too > but the shell resource doesn't. In the xdg_shell case it is destroyed > by the client with the destroy request, in the wl_shell case it needs > to be destroyed by the server when the wl_surface is destroyed. > That means that a weston_desktop_surface can have no active shell > implementation, and we need to guard that. > --- > libweston-desktop/client.c | 2 +- > libweston-desktop/surface.c | 63 > +++++++++++++++++++++++++++++++++++---------- > 2 files changed, 51 insertions(+), 14 deletions(-) > > diff --git a/libweston-desktop/client.c b/libweston-desktop/client.c > index 810b6ba..a8968b8 100644 > --- a/libweston-desktop/client.c > +++ b/libweston-desktop/client.c > @@ -186,7 +186,7 @@ weston_desktop_client_ping(struct weston_desktop_client > *client) > void *implementation_data = > weston_desktop_surface_get_implementation_data(surface); > > - if (implementation->ping == NULL) > + if (implementation == NULL || implementation->ping == NULL) > return -1; > > if (client->ping_serial != 0) > diff --git a/libweston-desktop/surface.c b/libweston-desktop/surface.c > index 2205107..103f34f 100644 > --- a/libweston-desktop/surface.c > +++ b/libweston-desktop/surface.c > @@ -54,6 +54,7 @@ struct weston_desktop_surface { > struct weston_position buffer_move; > struct wl_listener surface_commit_listener; > struct wl_listener surface_destroy_listener; > + struct wl_listener wl_surface_resource_destroy_listener; > struct wl_listener client_destroy_listener; > struct wl_list children_list; > > @@ -130,6 +131,7 @@ weston_desktop_surface_destroy(struct > weston_desktop_surface *surface) > > wl_list_remove(&surface->surface_commit_listener.link); > wl_list_remove(&surface->surface_destroy_listener.link); > + wl_list_remove(&surface->wl_surface_resource_destroy_listener.link); > wl_list_remove(&surface->client_destroy_listener.link); > > if (!wl_list_empty(&surface->resource_list)) { > @@ -140,7 +142,9 @@ weston_desktop_surface_destroy(struct > weston_desktop_surface *surface) > } > } > > - surface->implementation->destroy(surface, > surface->implementation_data); > + if (surface->implementation) > + surface->implementation->destroy(surface, > + > surface->implementation_data); > > surface->surface->committed = NULL; > surface->surface->committed_private = NULL; > @@ -169,6 +173,9 @@ weston_desktop_surface_surface_committed(struct > wl_listener *listener, > struct weston_desktop_surface *surface = > wl_container_of(listener, surface, surface_commit_listener); > > + /* committed cannot be called if the resource for the wl_surface does > + * not exist anymore, so we don't need to check if implementation is > + * valid here. */ > if (surface->implementation->committed != NULL) > surface->implementation->committed(surface, > > surface->implementation_data, > @@ -218,6 +225,20 @@ weston_desktop_surface_resource_destroy(struct > wl_resource *resource) > } > > static void > +weston_desktop_wl_surface_resource_destroyed(struct wl_listener *listener, > + void *data) > +{ > + struct weston_desktop_surface *surface = > + wl_container_of(listener, surface, > + wl_surface_resource_destroy_listener); > + > + wl_list_init(&surface->wl_surface_resource_destroy_listener.link); > + > + surface->implementation->destroy(surface, > surface->implementation_data); > + surface->implementation = NULL; > +} > + > +static void > weston_desktop_surface_committed(struct weston_surface *wsurface, > int32_t sx, int32_t sy) > { > @@ -277,6 +298,10 @@ weston_desktop_surface_create(struct weston_desktop > *desktop, > weston_desktop_surface_surface_destroyed; > wl_signal_add(&surface->surface->destroy_signal, > &surface->surface_destroy_listener); > + surface->wl_surface_resource_destroy_listener.notify = > + weston_desktop_wl_surface_resource_destroyed; > + wl_resource_add_destroy_listener(wsurface->resource, > + > &surface->wl_surface_resource_destroy_listener); > > wl_list_init(&surface->client_link); > wl_list_init(&surface->resource_list); > @@ -459,7 +484,8 @@ weston_desktop_surface_propagate_layer(struct > weston_desktop_surface *surface) > WL_EXPORT void > weston_desktop_surface_set_activated(struct weston_desktop_surface *surface, > bool activated) > { > - if (surface->implementation->set_activated != NULL) > + if (surface->implementation != NULL && > + surface->implementation->set_activated != NULL) > surface->implementation->set_activated(surface, > > surface->implementation_data, > activated); > @@ -468,7 +494,8 @@ weston_desktop_surface_set_activated(struct > weston_desktop_surface *surface, boo > WL_EXPORT void > weston_desktop_surface_set_fullscreen(struct weston_desktop_surface > *surface, bool fullscreen) > { > - if (surface->implementation->set_fullscreen != NULL) > + if (surface->implementation != NULL && > + surface->implementation->set_fullscreen != NULL) > surface->implementation->set_fullscreen(surface, > > surface->implementation_data, > fullscreen); > @@ -477,7 +504,8 @@ weston_desktop_surface_set_fullscreen(struct > weston_desktop_surface *surface, bo > WL_EXPORT void > weston_desktop_surface_set_maximized(struct weston_desktop_surface *surface, > bool maximized) > { > - if (surface->implementation->set_maximized != NULL) > + if (surface->implementation != NULL && > + surface->implementation->set_maximized != NULL) > surface->implementation->set_maximized(surface, > > surface->implementation_data, > maximized); > @@ -486,7 +514,8 @@ weston_desktop_surface_set_maximized(struct > weston_desktop_surface *surface, boo > WL_EXPORT void > weston_desktop_surface_set_resizing(struct weston_desktop_surface *surface, > bool resizing) > { > - if (surface->implementation->set_resizing != NULL) > + if (surface->implementation != NULL && > + surface->implementation->set_resizing != NULL) > surface->implementation->set_resizing(surface, > > surface->implementation_data, > resizing); > @@ -495,7 +524,8 @@ weston_desktop_surface_set_resizing(struct > weston_desktop_surface *surface, bool > WL_EXPORT void > weston_desktop_surface_set_size(struct weston_desktop_surface *surface, > int32_t width, int32_t height) > { > - if (surface->implementation->set_size != NULL) > + if (surface->implementation != NULL && > + surface->implementation->set_size != NULL) > surface->implementation->set_size(surface, > > surface->implementation_data, > width, height); > @@ -504,7 +534,8 @@ weston_desktop_surface_set_size(struct > weston_desktop_surface *surface, int32_t > WL_EXPORT void > weston_desktop_surface_close(struct weston_desktop_surface *surface) > { > - if (surface->implementation->close != NULL) > + if (surface->implementation != NULL && > + surface->implementation->close != NULL) > surface->implementation->close(surface, > surface->implementation_data); > } > @@ -606,7 +637,8 @@ weston_desktop_surface_get_pid(struct > weston_desktop_surface *surface) > WL_EXPORT bool > weston_desktop_surface_get_activated(struct weston_desktop_surface *surface) > { > - if (surface->implementation->get_activated == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_activated == NULL) > return false; > return surface->implementation->get_activated(surface, > > surface->implementation_data); > @@ -615,7 +647,8 @@ weston_desktop_surface_get_activated(struct > weston_desktop_surface *surface) > WL_EXPORT bool > weston_desktop_surface_get_resizing(struct weston_desktop_surface *surface) > { > - if (surface->implementation->get_resizing == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_resizing == NULL) > return false; > return surface->implementation->get_resizing(surface, > > surface->implementation_data); > @@ -624,7 +657,8 @@ weston_desktop_surface_get_resizing(struct > weston_desktop_surface *surface) > WL_EXPORT bool > weston_desktop_surface_get_maximized(struct weston_desktop_surface *surface) > { > - if (surface->implementation->get_maximized == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_maximized == NULL) > return false; > return surface->implementation->get_maximized(surface, > > surface->implementation_data); > @@ -633,7 +667,8 @@ weston_desktop_surface_get_maximized(struct > weston_desktop_surface *surface) > WL_EXPORT bool > weston_desktop_surface_get_fullscreen(struct weston_desktop_surface *surface) > { > - if (surface->implementation->get_fullscreen == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_fullscreen == NULL) > return false; > return surface->implementation->get_fullscreen(surface, > > surface->implementation_data); > @@ -652,7 +687,8 @@ weston_desktop_surface_get_max_size(struct > weston_desktop_surface *surface) > { > struct weston_size size = { 0, 0 }; > > - if (surface->implementation->get_max_size == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_max_size == NULL) > return size; > return surface->implementation->get_max_size(surface, > > surface->implementation_data); > @@ -663,7 +699,8 @@ weston_desktop_surface_get_min_size(struct > weston_desktop_surface *surface) > { > struct weston_size size = { 0, 0 }; > > - if (surface->implementation->get_min_size == NULL) > + if (surface->implementation == NULL || > + surface->implementation->get_min_size == NULL) > return size; > return surface->implementation->get_min_size(surface, > > surface->implementation_data); > -- > 2.10.0 > _______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
