[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