On Fri, Feb 17, 2012 at 03:26:12PM +0800, juan.j.z...@linux.intel.com wrote:
> From: Zhiwen Wu <zhiwen...@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
> 
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to