[PATCH weston 02/17] xdg-shell: Require proper object tree destruction

Bryce Harrington bryce at osg.samsung.com
Tue Apr 7 17:25:17 PDT 2015


On Tue, Apr 07, 2015 at 05:01:17PM +0800, Jonas Ådahl wrote:
> Require all child objects to be destroyed before the parent. In other
> words, all popups and surfaces created by one xdg_shell instance needs
> to be destroyed before the xdg_shell object, otherwise a protocol error
> is raised.
> 
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>

> ---
>  desktop-shell/shell.c  | 26 ++++++++++++++++++++++++++
>  protocol/xdg-shell.xml |  6 +++---
>  2 files changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 826692f..778c120 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -107,6 +107,7 @@ struct shell_surface {
>  	struct wl_resource *resource;
>  	struct wl_signal destroy_signal;
>  	struct shell_client *owner;
> +	struct wl_resource *owner_resource;
>  
>  	struct weston_surface *surface;
>  	struct weston_view *view;
> @@ -239,6 +240,7 @@ struct shell_client {
>  	struct wl_event_source *ping_timer;
>  	uint32_t ping_serial;
>  	int unresponsive;
> +	struct wl_list surface_list;
>  };
>  
>  static struct desktop_shell *
> @@ -3554,6 +3556,7 @@ shell_destroy_shell_surface(struct wl_resource *resource)
>  
>  	if (!wl_list_empty(&shsurf->popup.grab_link))
>  		remove_popup_grab(shsurf);
> +	wl_list_remove(wl_resource_get_link(shsurf->resource));
>  	shsurf->resource = NULL;
>  }
>  
> @@ -3725,6 +3728,7 @@ shell_get_shell_surface(struct wl_client *client,
>  	wl_resource_set_implementation(shsurf->resource,
>  				       &shell_surface_implementation,
>  				       shsurf, shell_destroy_shell_surface);
> +	wl_list_init(wl_resource_get_link(shsurf->resource));
>  }
>  
>  static bool
> @@ -3988,6 +3992,21 @@ static void
>  xdg_shell_destroy(struct wl_client *client,
>  		  struct wl_resource *resource)
>  {
> +	struct shell_client *sc = wl_resource_get_user_data(resource);
> +	struct wl_resource *shsurf_resource;
> +	struct shell_surface *shsurf;
> +
> +	wl_resource_for_each(shsurf_resource, &sc->surface_list) {
> +		shsurf = wl_resource_get_user_data(shsurf_resource);
> +		if (shsurf->owner_resource == resource) {
> +			wl_resource_post_error(
> +				resource,
> +				XDG_SHELL_ERROR_DEFUNCT_SURFACES,
> +				"not all child surface objects destroyed");
> +			return;
> +		}
> +	}
> +
>  	wl_resource_destroy(resource);
>  }
>  
> @@ -4056,6 +4075,9 @@ xdg_get_xdg_surface(struct wl_client *client,
>  	wl_resource_set_implementation(shsurf->resource,
>  				       &xdg_surface_implementation,
>  				       shsurf, shell_destroy_shell_surface);
> +	shsurf->owner_resource = resource;
> +	wl_list_insert(&sc->surface_list,
> +		       wl_resource_get_link(shsurf->resource));
>  }
>  
>  static bool
> @@ -4181,6 +4203,9 @@ xdg_get_xdg_popup(struct wl_client *client,
>  	wl_resource_set_implementation(shsurf->resource,
>  				       &xdg_popup_implementation,
>  				       shsurf, shell_destroy_shell_surface);
> +	shsurf->owner_resource = resource;
> +	wl_list_insert(&sc->surface_list,
> +		       wl_resource_get_link(shsurf->resource));
>  }
>  
>  static void
> @@ -5798,6 +5823,7 @@ shell_client_create(struct wl_client *client, struct desktop_shell *shell,
>  	sc->shell = shell;
>  	sc->destroy_listener.notify = handle_shell_client_destroy;
>  	wl_client_add_destroy_listener(client, &sc->destroy_listener);
> +	wl_list_init(&sc->surface_list);
>  
>  	return sc;
>  }
> diff --git a/protocol/xdg-shell.xml b/protocol/xdg-shell.xml
> index d1b47d1..09ce019 100644
> --- a/protocol/xdg-shell.xml
> +++ b/protocol/xdg-shell.xml
> @@ -49,6 +49,7 @@
>  
>      <enum name="error">
>        <entry name="role" value="0" summary="given wl_surface has another role"/>
> +      <entry name="defunct_surfaces" value="1" summary="xdg_shell was destroyed before children"/>
>      </enum>
>  
>      <request name="destroy" type="destructor">
> @@ -56,9 +57,8 @@
>          Destroy this xdg_shell object.
>  
>          Destroying a bound xdg_shell object while there are surfaces
> -        still alive with roles from this interface is illegal and will
> -        result in a protocol error. Make sure to destroy all surfaces
> -        before destroying this object.
> +        still alive created by this xdg_shell object instance is illegal
> +        and will result in a protocol error.
>        </description>
>      </request>
>  
> -- 
> 2.1.4
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list