[weston PATCH v6 3/7] Shell: Hide panels when we have a top fullscreen surface.

Kristian Hoegsberg hoegsberg at gmail.com
Tue Feb 21 14:55:08 PST 2012


On Fri, Feb 17, 2012 at 03:26:12PM +0800, juan.j.zhao at linux.intel.com wrote:
> From: Zhiwen Wu <zhiwen.wu at linux.intel.com>

I agree with the behavior we're going for here: when the fullscreen
surface is on top, we hide the panels, when switch to a different
client, we bring the panels back.  However, I think we're better off
just raising the fullscreen surface (and the solid color black surface
I mentioned earlier) above the panels.  We do need a better data
structure for managing the window stack to do that properly and I hope
we can figure that out soon (this week).

I don't like the prepare_repaint hook though.  We control raising
window completely in shell.c and should be able to catch whenever we
raise a fullscreen surface or try to raise something else on top of a
fullscreen surface.  We should just adjust the surface stack at those
points.

Kristian
 
>  1.Add a struct wl_list wl_shell::hidden_panels to store the hidden panels.
>  2.Add a hook weston_shell:prepare_repaint to do the stacking adjustment before output repainting.
>  3.In the hook, check that if we had a top and fullscreen surface.
>    If yes, remove the panel surface from weston_compositor::surface_list and store them to wl_shell:hidden_panels.
>    If no, and we have hidden panels, unhide them.
> ---
>  src/compositor.c |    2 +
>  src/compositor.h |    1 +
>  src/shell.c      |  101 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 103 insertions(+), 1 deletions(-)
> 
> diff --git a/src/compositor.c b/src/compositor.c
> index 8e2e7e9..8d609c5 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -967,6 +967,8 @@ weston_output_repaint(struct weston_output *output, int msecs)
>  		overlap, surface_overlap;
>  	int32_t width, height;
>  
> +	ec->shell->prepare_repaint (ec->shell, output);
> +
>  	width = output->current->width +
>  		output->border.left + output->border.right;
>  	height = output->current->height +
> diff --git a/src/compositor.h b/src/compositor.h
> index 82d7d51..aa62c81 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -140,6 +140,7 @@ struct weston_shell {
>  			  struct weston_surface *surface,
>  			  GLfloat x, GLfloat y, int32_t width, int32_t height);
>  	void (*destroy)(struct weston_shell *shell);
> +	void (*prepare_repaint)(struct weston_shell *shell, struct weston_output *output);
>  };
>  
>  enum {
> diff --git a/src/shell.c b/src/shell.c
> index e0c8f07..03c4059 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -57,6 +57,7 @@ struct wl_shell {
>  	struct shell_surface *lock_surface;
>  	struct wl_listener lock_surface_listener;
>  	struct wl_list hidden_surface_list;
> +	struct wl_list hidden_panels;
>  
>  	struct wl_list backgrounds;
>  	struct wl_list panels;
> @@ -70,6 +71,7 @@ struct wl_shell {
>  	} screensaver;
>  };
>  
> +/*FIXME:Using bit flag for the type due to some surface may be both toplevel and fullscreen*/
>  enum shell_surface_type {
>  	SHELL_SURFACE_NONE,
>  
> @@ -1322,6 +1324,101 @@ weston_surface_set_fullscreen(struct weston_surface *surface)
>  	return 0;
>  }
>  
> +static struct weston_surface *
> +top_regular_surface (struct weston_shell *base)
> +{
> +	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
> +	struct weston_compositor *compositor = shell->compositor;
> +	struct wl_list *list;
> +	struct weston_surface *surf;
> +	struct weston_surface *tmp;
> +	bool   done = false;
> +
> +	list = &compositor->surface_list;
> +
> +	wl_list_for_each_safe(surf, tmp, list, link) {
> +	/*skip non-client surface*/
> +		if (surf->surface.resource.client == NULL)
> +			continue;
> +		if (get_shell_surface_type(surf) == SHELL_SURFACE_LOCK)
> +			continue;
> +		if (get_shell_surface_type(surf) == SHELL_SURFACE_SCREENSAVER)
> +			continue;
> +		if (get_shell_surface_type(surf) == SHELL_SURFACE_PANEL)
> +			continue;
> +		if (get_shell_surface_type(surf) == SHELL_SURFACE_BACKGROUND) {
> +			break;
> +		}
> +		/*got the top regular surface*/
> +		done = true;
> +		break;
> +	}
> +
> +	if (!done) {
> +		printf ("no regular surface\n");
> +		surf = NULL;
> +	}
> +
> +	return surf;
> +}
> +
> +static bool
> +is_fullscreen_surface (struct weston_surface *base)
> +{
> +	struct shell_surface *shsurf;
> +	enum shell_surface_type surf_type;
> +	
> +	if (!base) {
> +		return false;
> +	}
> +
> +	shsurf = get_shell_surface (base);
> +	surf_type = get_shell_surface_type (base);
> +
> +	if (surf_type == SHELL_SURFACE_FULLSCREEN)
> +		return true;
> +	else
> +		return false;
> +}
> +
> +static void
> +prepare_repaint (struct weston_shell *base, struct weston_output *output)
> +{
> +	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
> +	struct weston_compositor *compositor = shell->compositor;
> +	struct weston_surface *top_regular_surf;
> +	struct weston_surface *tmp;
> +	struct shell_surface *panel;
> +	bool   do_damage = false;
> +
> +	top_regular_surf = top_regular_surface (base);
> +
> +	if (is_fullscreen_surface (top_regular_surf)){ 
> +		if (wl_list_empty (&shell->hidden_panels) && !wl_list_empty (&shell->panels)) {
> +			/*hide panels*/
> +			wl_list_for_each(panel, &shell->panels, link) {
> +				panel->surface->output = NULL;
> +				wl_list_remove(&panel->surface->link);
> +				wl_list_insert(shell->hidden_panels.prev, &panel->surface->link);
> +			}
> +			do_damage = true;
> +		}
> +	} else {
> +		if (!wl_list_empty (&shell->hidden_panels)) {
> +			/*unhide panels*/
> +			struct wl_list *list = weston_compositor_top(compositor);
> +			wl_list_insert_list(list, &shell->hidden_panels);
> +			wl_list_init(&shell->hidden_panels);
> +			do_damage = true;
> +		}
> +	}
> +
> +	if (do_damage) {
> +		weston_output_damage (output);
> +	}
> +	return;
> +}
> +
>  static void
>  map(struct weston_shell *base,
>      struct weston_surface *surface, int32_t width, int32_t height)
> @@ -1400,7 +1497,7 @@ map(struct weston_shell *base,
>  		break;
>  	default:
>  		/* everything else just below the panel */
> -		if (!wl_list_empty(&shell->panels)) {
> +		if (!wl_list_empty(&shell->panels) && wl_list_empty (&shell->hidden_panels)) {
>  			struct shell_surface *panel =
>  				container_of(shell->panels.prev,
>  					     struct shell_surface, link);
> @@ -1650,8 +1747,10 @@ shell_init(struct weston_compositor *ec)
>  	shell->shell.map = map;
>  	shell->shell.configure = configure;
>  	shell->shell.destroy = shell_destroy;
> +	shell->shell.prepare_repaint = prepare_repaint;
>  
>  	wl_list_init(&shell->hidden_surface_list);
> +	wl_list_init(&shell->hidden_panels);
>  	wl_list_init(&shell->backgrounds);
>  	wl_list_init(&shell->panels);
>  	wl_list_init(&shell->screensaver.surfaces);
> -- 
> 1.7.5.4
> 


More information about the wayland-devel mailing list