[PATCH v2 1/4] shell: add fullscreen path for activate() and switcher

zhiwen.wu at linux.intel.com zhiwen.wu at linux.intel.com
Tue Mar 13 08:18:23 PDT 2012


From: Alex Wu <zhiwen.wu at linux.intel.com>

For activate(), stack the surface atop fullscreen layer instead of
toplevel layer.
For switcher, involve the fullscreen surfaces into surface iteration,
and make fullscreen surface and its black surface transparent if
necessary.
---
 src/shell.c |   70 +++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index 765b0a4..984c75d 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -144,6 +144,9 @@ struct rotate_grab {
 	} center;
 };
 
+static struct shell_surface *
+get_shell_surface(struct weston_surface *surface);
+
 static void
 center_on_output(struct weston_surface *surface,
 		 struct weston_output *output);
@@ -1344,6 +1347,7 @@ activate(struct weston_shell *base, struct weston_surface *es,
 {
 	struct wl_shell *shell = container_of(base, struct wl_shell, shell);
 	struct weston_compositor *compositor = shell->compositor;
+	struct wl_list *lst;
 
 	weston_surface_activate(es, device, time);
 
@@ -1364,14 +1368,48 @@ activate(struct weston_shell *base, struct weston_surface *es,
 		break;
 	case SHELL_SURFACE_FULLSCREEN:
 		/* should on top of panels */
+		shell_stack_fullscreen(get_shell_surface(es));
 		break;
 	default:
-		weston_surface_restack(es,
-				       &shell->toplevel_layer.surface_list);
+		if (wl_list_empty(&shell->fullscreen_layer.surface_list))
+			lst = &shell->toplevel_layer.surface_list;
+		else
+			lst = &shell->fullscreen_layer.surface_list;
+		weston_surface_restack(es, lst);
 		break;
 	}
 }
 
+
+static struct weston_surface *
+get_upper_surface(struct weston_surface *es)
+{
+	if (es->link.prev == &es->compositor->surface_list)
+		return NULL;
+
+	return container_of(es->link.prev, struct weston_surface, link);
+}
+
+static struct weston_surface *
+get_lower_surface(struct weston_surface *es)
+{
+	if (es->link.next == &es->compositor->surface_list)
+		return NULL;
+
+	return container_of(es->link.next, struct weston_surface, link);
+}
+
+static bool
+is_black_surface(struct weston_surface *es)
+{
+	struct weston_surface *upper;
+
+	if ((upper = get_upper_surface(es)) && 
+            get_shell_surface_type(upper) == SHELL_SURFACE_FULLSCREEN)
+		return true;
+	return false;
+}
+
 static void
 click_to_activate_binding(struct wl_input_device *device,
 			  uint32_t time, uint32_t key,
@@ -1380,19 +1418,13 @@ click_to_activate_binding(struct wl_input_device *device,
 	struct weston_input_device *wd = (struct weston_input_device *) device;
 	struct weston_compositor *compositor = data;
 	struct weston_surface *focus;
-	struct weston_surface *upper;
 
 	focus = (struct weston_surface *) device->pointer_focus;
 	if (!focus)
 		return;
 
-	upper = container_of(focus->link.prev, struct weston_surface, link);
-	if (focus->link.prev != &compositor->surface_list &&
-	    get_shell_surface_type(upper) == SHELL_SURFACE_FULLSCREEN) {
-		printf("%s: focus is black surface, raise its fullscreen surface\n", __func__);
-		shell_stack_fullscreen(get_shell_surface(upper));
-		focus = upper;
-	}
+	if (is_black_surface(focus))
+		focus = get_upper_surface(focus);
 
 	if (state && device->pointer_grab == &device->default_pointer_grab)
 		activate(compositor->shell, focus, wd, time);
@@ -1833,6 +1865,12 @@ switcher_next(struct switcher *switcher)
 			weston_surface_damage(surface);
 			break;
 		default:
+			if (is_black_surface(surface)) {
+				weston_surface_set_color(surface, 
+						         0.0, 0.0, 0.0, (GLfloat)64/(GLfloat)255);
+				surface->geometry.dirty = 1;
+				weston_surface_damage(surface);
+			}
 			break;
 		}
 	}
@@ -1840,12 +1878,19 @@ switcher_next(struct switcher *switcher)
 	if (next == NULL)
 		next = first;
 
+	if (next == NULL)
+		return;
+
 	wl_list_remove(&switcher->listener.link);
 	wl_list_insert(next->surface.resource.destroy_listener_list.prev,
 		       &switcher->listener.link);
 
 	switcher->current = next;
 	next->alpha = 255;
+
+	if (get_shell_surface_type(next) == SHELL_SURFACE_FULLSCREEN) {
+		weston_surface_set_color(get_lower_surface(next), 0.0, 0.0, 0.0, 1.0);
+	}
 }
 
 static void
@@ -1867,11 +1912,14 @@ switcher_destroy(struct switcher *switcher, uint32_t time)
 		(struct weston_input_device *) switcher->grab.input_device;
 
 	wl_list_for_each(surface, &compositor->surface_list, link) {
+		if (is_black_surface(surface))
+			weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
 		surface->alpha = 255;
 		weston_surface_damage(surface);
 	}
 
-	activate(compositor->shell, switcher->current, device, time);
+	if (switcher->current)
+		activate(compositor->shell, switcher->current, device, time);
 	wl_list_remove(&switcher->listener.link);
 	wl_input_device_end_keyboard_grab(&device->input_device, time);
 	free(switcher);
-- 
1.7.5.4



More information about the wayland-devel mailing list