[PATCH 3/3] desktop-shell: resize background and panel surfaces on output resize

Pekka Paalanen ppaalanen at gmail.com
Wed Jun 8 11:38:20 UTC 2016


On Fri, 27 May 2016 23:22:58 +0200
David Fort <rdp.effort at gmail.com> wrote:

> When an output is resized (permanent mode switch), we should also notify the
> shell client so that the panel and background fits to the new screen dimensions.
> 
> Signed-off-by: David Fort <contact at hardening-consulting.com>
> ---
>  desktop-shell/shell.c | 93 +++++++++++++++++++++++++++++++++++++++++++--------
>  desktop-shell/shell.h |  8 ++++-
>  2 files changed, 86 insertions(+), 15 deletions(-)
> 
> diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
> index 7d5bca9..42c0757 100644
> --- a/desktop-shell/shell.c
> +++ b/desktop-shell/shell.c
> @@ -4364,6 +4364,20 @@ configure_static_view(struct weston_view *ev, struct weston_layer *layer)
>  	}
>  }
>  
> +
> +static struct shell_output *
> +find_shell_output_from_weston_output(struct desktop_shell *shell, struct weston_output *output)
> +{
> +	struct shell_output *shell_output;
> +
> +	wl_list_for_each(shell_output, &shell->output_list, link) {
> +		if (shell_output->output == output)
> +			return shell_output;
> +	}
> +
> +	return NULL;
> +}
> +
>  static int
>  background_get_label(struct weston_surface *surface, char *buf, size_t len)
>  {
> @@ -4383,6 +4397,16 @@ background_configure(struct weston_surface *es, int32_t sx, int32_t sy)
>  }
>  
>  static void
> +handle_background_surface_destroy(struct wl_listener *listener, void *data)
> +{
> +	struct shell_output *output =
> +	    container_of(listener, struct shell_output, background_surface_listener);
> +
> +	weston_log("background surface gone\n");
> +	output->background_surface = NULL;
> +}
> +
> +static void
>  desktop_shell_set_background(struct wl_client *client,
>  			     struct wl_resource *resource,
>  			     struct wl_resource *output_resource,
> @@ -4391,6 +4415,7 @@ desktop_shell_set_background(struct wl_client *client,
>  	struct desktop_shell *shell = wl_resource_get_user_data(resource);
>  	struct weston_surface *surface =
>  		wl_resource_get_user_data(surface_resource);
> +	struct shell_output *sh_output;
>  	struct weston_view *view, *next;
>  
>  	if (surface->configure) {
> @@ -4413,6 +4438,12 @@ desktop_shell_set_background(struct wl_client *client,
>  					    surface_resource,
>  					    surface->output->width,
>  					    surface->output->height);
> +
> +	sh_output = find_shell_output_from_weston_output(shell, surface->output);
> +	sh_output->background_surface = surface;
> +
> +	sh_output->background_surface_listener.notify = handle_background_surface_destroy;
> +	wl_signal_add(&surface->destroy_signal, &sh_output->background_surface_listener);
>  }
>  
>  static int
> @@ -4434,6 +4465,17 @@ panel_configure(struct weston_surface *es, int32_t sx, int32_t sy)
>  }
>  
>  static void
> +handle_panel_surface_destroy(struct wl_listener *listener, void *data)
> +{
> +	struct shell_output *output =
> +	    container_of(listener, struct shell_output, panel_surface_listener);
> +
> +	weston_log("panel surface gone\n");
> +	output->panel_surface = NULL;
> +}
> +
> +
> +static void
>  desktop_shell_set_panel(struct wl_client *client,
>  			struct wl_resource *resource,
>  			struct wl_resource *output_resource,
> @@ -4443,6 +4485,7 @@ desktop_shell_set_panel(struct wl_client *client,
>  	struct weston_surface *surface =
>  		wl_resource_get_user_data(surface_resource);
>  	struct weston_view *view, *next;
> +	struct shell_output *sh_output;
>  
>  	if (surface->configure) {
>  		wl_resource_post_error(surface_resource,
> @@ -4464,6 +4507,12 @@ desktop_shell_set_panel(struct wl_client *client,
>  					    surface_resource,
>  					    surface->output->width,
>  					    surface->output->height);
> +
> +	sh_output = find_shell_output_from_weston_output(shell, surface->output);
> +	sh_output->panel_surface = surface;
> +
> +	sh_output->panel_surface_listener.notify = handle_panel_surface_destroy;
> +	wl_signal_add(&surface->destroy_signal, &sh_output->panel_surface_listener);
>  }
>  

Hi,

up to this point things look good.


>  static int
> @@ -4494,16 +4543,6 @@ lock_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
>  }
>  
>  static void
> -handle_lock_surface_destroy(struct wl_listener *listener, void *data)
> -{
> -	struct desktop_shell *shell =
> -	    container_of(listener, struct desktop_shell, lock_surface_listener);
> -
> -	weston_log("lock surface gone\n");
> -	shell->lock_surface = NULL;
> -}
> -
> -static void
>  desktop_shell_set_lock_surface(struct wl_client *client,
>  			       struct wl_resource *resource,
>  			       struct wl_resource *surface_resource)
> @@ -4519,10 +4558,6 @@ desktop_shell_set_lock_surface(struct wl_client *client,
>  
>  	shell->lock_surface = surface;
>  
> -	shell->lock_surface_listener.notify = handle_lock_surface_destroy;
> -	wl_signal_add(&surface->destroy_signal,
> -		      &shell->lock_surface_listener);
> -

Why do you remove the lock surface listener?
It does not seem to fit in the scope of this patch.

>  	weston_view_create(surface);
>  	surface->configure = lock_surface_configure;
>  	surface->configure_private = shell;
> @@ -6376,11 +6411,39 @@ handle_output_destroy(struct wl_listener *listener, void *data)
>  	shell_for_each_layer(shell, shell_output_destroy_move_layer, output);
>  
>  	wl_list_remove(&output_listener->destroy_listener.link);
> +	wl_list_remove(&output_listener->resized_listener.link);
>  	wl_list_remove(&output_listener->link);
>  	free(output_listener);
>  }
>  
>  static void
> +shell_resize_surface_to_output(struct desktop_shell *shell,
> +				struct weston_surface *surface,
> +				const struct weston_output *output)
> +{
> +	if (!surface)
> +		return;
> +
> +	weston_desktop_shell_send_configure(shell->child.desktop_shell, 0,
> +					surface->resource,
> +					output->width,
> +					output->height);
> +}

This function is very much alike the last statement in
desktop_shell_set_background() and desktop_shell_set_panel(). It is ok
as is, but maybe a follow-up (or a prerequisite) patch could
consolidate even more.

> +
> +
> +static void
> +handle_output_resized(struct wl_listener *listener, void *data)
> +{
> +	struct shell_output *output_listener =
> +		container_of(listener, struct shell_output, resized_listener);
> +	struct weston_output *output = output_listener->output;

struct weston_output *output = data;
then look up the shell_output from the weston_output.

This ties in with the resize listener being in the wrong place below.

Either you would assert(output_listener->output == data) which would
currently fail with multiple outputs because this function gets called
for every listener, not just the resized one, or you need to look up
the shell output from weston_output. Given that the signal is already
in weston_compositor and not in weston_output, the latter alternative
is the correct one.

> +	struct desktop_shell *shell = output_listener->shell;
> +
> +	shell_resize_surface_to_output(shell, output_listener->background_surface, output);
> +	shell_resize_surface_to_output(shell, output_listener->panel_surface, output);
> +}
> +
> +static void
>  create_shell_output(struct desktop_shell *shell,
>  					struct weston_output *output)
>  {
> @@ -6395,6 +6458,8 @@ create_shell_output(struct desktop_shell *shell,
>  	shell_output->destroy_listener.notify = handle_output_destroy;
>  	wl_signal_add(&output->destroy_signal,
>  		      &shell_output->destroy_listener);
> +	shell_output->resized_listener.notify = handle_output_resized;
> +	wl_signal_add(&output->compositor->output_resized_signal, &shell_output->resized_listener);

Resized listener is in the wrong place, see below.

>  	wl_list_insert(shell->output_list.prev, &shell_output->link);
>  }
>  
> diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
> index b430fa2..7df1157 100644
> --- a/desktop-shell/shell.h
> +++ b/desktop-shell/shell.h
> @@ -112,8 +112,15 @@ struct shell_output {
>  	struct desktop_shell  *shell;
>  	struct weston_output  *output;
>  	struct exposay_output eoutput;
> +	struct wl_listener    resized_listener;

The resized listener is still in the wrong place. The signal is
compositor-wide.

Here you register one listener per output. When one output gets
resized, all your listeners will get called with the same output.

This listener needs to be a single, not per output.

>  	struct wl_listener    destroy_listener;
>  	struct wl_list        link;
> +
> +	struct weston_surface *panel_surface;
> +	struct wl_listener panel_surface_listener;
> +
> +	struct weston_surface *background_surface;
> +	struct wl_listener background_surface_listener;
>  };
>  
>  struct desktop_shell {
> @@ -157,7 +164,6 @@ struct desktop_shell {
>  	} text_input;
>  
>  	struct weston_surface *lock_surface;
> -	struct wl_listener lock_surface_listener;
>  
>  	struct {
>  		struct wl_array array;

Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160608/ec5c6348/attachment-0001.sig>


More information about the wayland-devel mailing list