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