From: Zhiwen Wu <zhiwen...@linux.intel.com>

 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