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