[weston PATCH v6 3/7] Shell: Hide panels when we have a top fullscreen surface.
juan.j.zhao at linux.intel.com
juan.j.zhao at linux.intel.com
Thu Feb 16 23:26:12 PST 2012
From: Zhiwen Wu <zhiwen.wu at 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
More information about the wayland-devel
mailing list