[PATCH 10/10] desktop-shell: Enable per-output fade animations

Bryce Harrington bryce at osg.samsung.com
Sat Mar 5 00:18:47 UTC 2016


Instead of creating a single global fade surface across all outputs,
create a separate surface for each output.  This lets us individually
fade each output (or block fading if the output has an inhibiting
surface).

This also fixes a potential issue if on multihead layout spanning a
desktop wider than 8096 (or higher than 8096), the fade animation may
not completely cover all surfaces.

This assumes the output geometry doesn't change larger during the course
of the fade animation.

Signed-off-by: Bryce Harrington <bryce at osg.samsung.com>
---
 desktop-shell/shell.c | 92 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 56 insertions(+), 36 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 2d54524..d31e29d 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -5239,7 +5239,7 @@ shell_fade_done(struct weston_view_animation *animation, void *data)
 }
 
 static struct weston_view *
-shell_fade_create_surface(struct desktop_shell *shell)
+shell_fade_create_surface_for_output(struct desktop_shell *shell, struct weston_output *output)
 {
 	struct weston_compositor *compositor = shell->compositor;
 	struct weston_surface *surface;
@@ -5255,8 +5255,8 @@ shell_fade_create_surface(struct desktop_shell *shell)
 		return NULL;
 	}
 
-	weston_surface_set_size(surface, 8192, 8192);
-	weston_view_set_position(view, 0, 0);
+	weston_surface_set_size(surface, output->width, output->height);
+	weston_view_set_position(view, output->x, output->y);
 	weston_surface_set_color(surface, 0.0, 0.0, 0.0, 1.0);
 	weston_layer_entry_insert(&compositor->fade_layer.view_list,
 				  &view->layer_link);
@@ -5269,6 +5269,7 @@ static void
 shell_fade(struct desktop_shell *shell, enum fade_type type)
 {
 	float tint;
+	struct weston_output *output;
 
 	switch (type) {
 	case FADE_IN:
@@ -5278,36 +5279,45 @@ shell_fade(struct desktop_shell *shell, enum fade_type type)
 		tint = 1.0;
 		break;
 	default:
-		weston_log("shell: invalid fade type\n");
 		return;
 	}
 
-	shell->fade.type = type;
+	/* TODO: This should create a separate fade surface for each output */
+        wl_list_for_each(output, &shell->compositor->output_list, link) {
+                uint32_t inhibit_mask = weston_output_inhibited_outputs(shell->compositor);
 
-	if (shell->fade.view == NULL) {
-		shell->fade.view = shell_fade_create_surface(shell);
-		if (!shell->fade.view)
-			return;
+		if (inhibit_mask & (1 << output->id))
+			continue;
 
-		shell->fade.view->alpha = 1.0 - tint;
-		weston_view_update_transform(shell->fade.view);
-	}
+		shell->fade.type = type;
 
-	if (shell->fade.view->output == NULL) {
-		/* If the black view gets a NULL output, we lost the
-		 * last output and we'll just cancel the fade.  This
-		 * happens when you close the last window under the
-		 * X11 or Wayland backends. */
-		shell->locked = false;
-		weston_surface_destroy(shell->fade.view->surface);
-		shell->fade.view = NULL;
-	} else if (shell->fade.animation) {
-		weston_fade_update(shell->fade.animation, tint);
-	} else {
-		shell->fade.animation =
-			weston_fade_run(shell->fade.view,
-					1.0 - tint, tint, 300.0,
-					shell_fade_done, shell);
+		if (shell->fade.view == NULL) {
+			shell->fade.view = shell_fade_create_surface_for_output(shell, output);
+			if (!shell->fade.view)
+				return;
+
+			shell->fade.view->alpha = 1.0 - tint;
+			weston_view_update_transform(shell->fade.view);
+		}
+
+		/* FIXME: Lookup what outputs the fade view should fade on */
+
+		if (shell->fade.view->output == NULL) {
+			/* If the black view gets a NULL output, we lost the
+			 * last output and we'll just cancel the fade.  This
+			 * happens when you close the last window under the
+			 * X11 or Wayland backends. */
+			shell->locked = false;
+			weston_surface_destroy(shell->fade.view->surface);
+			shell->fade.view = NULL;
+		} else if (shell->fade.animation) {
+			weston_fade_update(shell->fade.animation, tint);
+		} else {
+			shell->fade.animation =
+				weston_fade_run(shell->fade.view,
+						1.0 - tint, tint, 300.0,
+						shell_fade_done, shell);
+		}
 	}
 }
 
@@ -5360,6 +5370,9 @@ shell_fade_init(struct desktop_shell *shell)
 	 */
 
 	struct wl_event_loop *loop;
+	struct weston_output *output;
+
+	/* FIXME: Handle per-output fade surfaces */
 
 	if (shell->fade.view != NULL) {
 		weston_log("%s: warning: fade surface already exists\n",
@@ -5370,17 +5383,24 @@ shell_fade_init(struct desktop_shell *shell)
 	if (shell->startup_animation_type == ANIMATION_NONE)
 		return;
 
-	shell->fade.view = shell_fade_create_surface(shell);
-	if (!shell->fade.view)
-		return;
+	wl_list_for_each(output, &shell->compositor->output_list, link) {
+		uint32_t inhibit_mask = weston_output_inhibited_outputs(shell->compositor);
 
-	weston_view_update_transform(shell->fade.view);
-	weston_surface_damage(shell->fade.view->surface);
+		if (inhibit_mask & (1 << output->id))
+			continue;
 
-	loop = wl_display_get_event_loop(shell->compositor->wl_display);
-	shell->fade.startup_timer =
-		wl_event_loop_add_timer(loop, fade_startup_timeout, shell);
-	wl_event_source_timer_update(shell->fade.startup_timer, 15000);
+		shell->fade.view = shell_fade_create_surface_for_output(shell, output);
+		if (!shell->fade.view)
+			return;
+
+		weston_view_update_transform(shell->fade.view);
+		weston_surface_damage(shell->fade.view->surface);
+
+		loop = wl_display_get_event_loop(shell->compositor->wl_display);
+		shell->fade.startup_timer =
+			wl_event_loop_add_timer(loop, fade_startup_timeout, shell);
+		wl_event_source_timer_update(shell->fade.startup_timer, 15000);
+	}
 }
 
 static void
-- 
1.9.1



More information about the wayland-devel mailing list