[PATCH 07/16] xdg-shell: Implement xdg_popup.

Kristian Høgsberg hoegsberg at gmail.com
Fri Nov 29 15:47:24 PST 2013


On Wed, Nov 27, 2013 at 03:50:23PM -0200, Rafael Antognolli wrote:
> ---
>  src/shell.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 155 insertions(+), 4 deletions(-)
> 
> diff --git a/src/shell.c b/src/shell.c
> index 98fb0fe..0daa136 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -247,6 +247,12 @@ struct ping_timer {
>  	uint32_t serial;
>  };
>  
> +enum shell_surface_class_interface {
> +	SHELL_CLASS_WL_SHELL_SURFACE,
> +	SHELL_CLASS_XDG_SURFACE,
> +	SHELL_CLASS_XDG_POPUP
> +};
> +
>  struct shell_surface {
>  	struct wl_resource *resource;
>  	struct wl_signal destroy_signal;
> @@ -257,6 +263,7 @@ struct shell_surface {
>  	struct weston_surface *parent;
>  	struct desktop_shell *shell;
>  
> +	enum shell_surface_class_interface shell_class;
>  	enum shell_surface_type type, next_type;
>  	char *title, *class;
>  	int32_t saved_x, saved_y;
> @@ -1918,7 +1925,17 @@ ping_handler(struct weston_surface *surface, uint32_t serial)
>  			wl_event_loop_add_timer(loop, ping_timeout_handler, shsurf);
>  		wl_event_source_timer_update(shsurf->ping_timer->source, ping_timeout);
>  
> -		wl_shell_surface_send_ping(shsurf->resource, serial);
> +		switch (shsurf->shell_class) {

We can just use wl_resource_instance_of() on shsurf->resource here.

> +			case SHELL_CLASS_WL_SHELL_SURFACE:
> +				wl_shell_surface_send_ping(shsurf->resource, serial);
> +				break;
> +			case SHELL_CLASS_XDG_SURFACE:
> +				xdg_surface_send_ping(shsurf->resource, serial);
> +				break;
> +			case SHELL_CLASS_XDG_POPUP:
> +				xdg_popup_send_ping(shsurf->resource, serial);
> +				break;
> +		}
>  	}
>  }
>  
> @@ -2664,7 +2681,17 @@ popup_grab_end(struct weston_pointer *pointer)
>  		assert(!wl_list_empty(&shseat->popup_grab.surfaces_list));
>  		/* Send the popup_done event to all the popups open */
>  		wl_list_for_each(shsurf, &shseat->popup_grab.surfaces_list, popup.grab_link) {
> -			wl_shell_surface_send_popup_done(shsurf->resource);
> +			switch (shsurf->shell_class) {

Use wl_resource_instance_of() as well, and let's add a helper we can
use in shell_map_popup() as well.

> +				case SHELL_CLASS_WL_SHELL_SURFACE:
> +					wl_shell_surface_send_popup_done(shsurf->resource);
> +					break;
> +				case SHELL_CLASS_XDG_POPUP:
> +					xdg_popup_send_popup_done(shsurf->resource,
> +								  shsurf->popup.serial);
> +					break;
> +				default:
> +					break;
> +			}
>  			shsurf->popup.shseat = NULL;
>  			if (prev) {
>  				wl_list_init(&prev->popup.grab_link);
> @@ -2726,7 +2753,17 @@ shell_map_popup(struct shell_surface *shsurf)
>  	if (shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
>  		add_popup_grab(shsurf, shseat);
>  	} else {
> -		wl_shell_surface_send_popup_done(shsurf->resource);
> +		switch (shsurf->shell_class) {
> +			case SHELL_CLASS_WL_SHELL_SURFACE:
> +				wl_shell_surface_send_popup_done(shsurf->resource);
> +				break;
> +			case SHELL_CLASS_XDG_POPUP:
> +				xdg_popup_send_popup_done(shsurf->resource,
> +							  shsurf->popup.serial);
> +				break;
> +			default:
> +				break;
> +		}
>  		shseat->popup_grab.client = NULL;
>  	}
>  }
> @@ -2932,6 +2969,8 @@ shell_get_shell_surface(struct wl_client *client,
>  		return;
>  	}
>  
> +	shsurf->shell_class = SHELL_CLASS_WL_SHELL_SURFACE;
> +
>  	shsurf->resource =
>  		wl_resource_create(client,
>  				   &wl_shell_surface_interface, 1, id);
> @@ -3169,6 +3208,8 @@ xdg_get_xdg_surface(struct wl_client *client,
>  		return;
>  	}
>  
> +	shsurf->shell_class = SHELL_CLASS_XDG_SURFACE;
> +
>  	shsurf->resource =
>  		wl_resource_create(client,
>  				   &xdg_surface_interface, 1, id);
> @@ -3177,12 +3218,122 @@ xdg_get_xdg_surface(struct wl_client *client,
>  				       shsurf, shell_destroy_shell_surface);
>  }
>  
> +/* xdg-popup implementation */
> +
> +static void
> +xdg_popup_destroy(struct wl_client *client,
> +		  struct wl_resource *resource)
> +{
> +	wl_resource_destroy(resource);
> +}
> +
> +static void
> +xdg_popup_pong(struct wl_client *client,
> +	       struct wl_resource *resource,
> +	       uint32_t serial)
> +{
> +	struct shell_surface *shsurf = wl_resource_get_user_data(resource);
> +
> +	surface_pong(shsurf, serial);
> +}
> +
> +static const struct xdg_popup_interface xdg_popup_implementation = {
> +	xdg_popup_destroy,
> +	xdg_popup_pong
> +};
> +
> +static void
> +xdg_popup_send_configure(struct weston_surface *surface,
> +			 uint32_t edges, int32_t width, int32_t height)
> +{
> +}
> +
> +static const struct weston_shell_client xdg_popup_client = {
> +	xdg_popup_send_configure
> +};
> +
> +static struct shell_surface *
> +create_xdg_popup(void *shell, struct weston_surface *surface,
> +		 const struct weston_shell_client *client,
> +		 struct weston_surface *parent,
> +		 struct shell_seat *seat,
> +		 uint32_t serial,
> +		 int32_t x, int32_t y)
> +{
> +	struct shell_surface *shsurf;
> +	shsurf = create_common_surface(shell, surface, client);
> +
> +	shsurf->type = SHELL_SURFACE_NONE;
> +	shsurf->next_type = SHELL_SURFACE_POPUP;
> +	shsurf->parent = parent;
> +	shsurf->popup.shseat = seat;
> +	shsurf->popup.serial = serial;
> +	shsurf->popup.x = x;
> +	shsurf->popup.y = y;
> +	return shsurf;
> +}
> +
> +static void
> +xdg_get_xdg_popup(struct wl_client *client,
> +		  struct wl_resource *resource,
> +		  uint32_t id,
> +		  struct wl_resource *surface_resource,
> +		  struct wl_resource *parent_resource,
> +		  struct wl_resource *seat_resource,
> +		  uint32_t serial,
> +		  int32_t x, int32_t y, uint32_t flags)
> +{
> +	struct weston_surface *surface =
> +		wl_resource_get_user_data(surface_resource);
> +	struct desktop_shell *shell = wl_resource_get_user_data(resource);
> +	struct shell_surface *shsurf;
> +	struct weston_surface *parent;
> +	struct shell_seat *seat;
> +
> +	if (get_shell_surface(surface)) {
> +		wl_resource_post_error(surface_resource,
> +				       WL_DISPLAY_ERROR_INVALID_OBJECT,
> +				       "desktop_shell::get_shell_surface already requested");
> +		return;
> +	}
> +
> +	if (!parent_resource) {
> +		wl_resource_post_error(surface_resource,
> +				       WL_DISPLAY_ERROR_INVALID_OBJECT,
> +				       "xdg_shell::get_xdg_popup requires a parent shell surface");
> +	}
> +
> +	parent = wl_resource_get_user_data(parent_resource);
> +	seat = get_shell_seat(wl_resource_get_user_data(seat_resource));;
> +
> +	shsurf = create_xdg_popup(shell, surface, &xdg_popup_client,
> +				  parent, seat, serial, x, y);
> +	if (!shsurf) {
> +		wl_resource_post_error(surface_resource,
> +				       WL_DISPLAY_ERROR_INVALID_OBJECT,
> +				       "surface->configure already set");
> +		return;
> +	}
> +
> +	shsurf->shell_class = SHELL_CLASS_XDG_POPUP;
> +
> +	shsurf->resource =
> +		wl_resource_create(client,
> +				   &xdg_popup_interface, 1, id);
> +	wl_resource_set_implementation(shsurf->resource,
> +				       &xdg_popup_implementation,
> +				       shsurf, shell_destroy_shell_surface);
> +}
> +
>  static const struct xdg_shell_interface xdg_implementation = {
>  	xdg_use_unstable_version,
>  	xdg_get_xdg_surface,
> -	NULL // get_xdg_popup
> +	xdg_get_xdg_popup
>  };
>  
> +/* end of xdg-shell implementation */
> +/***********************************/
>  
>  static void
>  shell_fade(struct desktop_shell *shell, enum fade_type type);
> -- 
> 1.8.3.1
> 
> _______________________________________________
> 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