[PATCH weston] libweston-desktop: listen for the wl_surface resource destruction

Giulio Camuffo giuliocamuffo at gmail.com
Wed Sep 28 19:28:27 UTC 2016


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 <giuliocamuffo at gmail.com>:
> 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
>


More information about the wayland-devel mailing list