[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