[PATCH 3/3 v2] Dim unresponsive windows

Scott Moreau oreaus at gmail.com
Tue Apr 17 18:06:20 PDT 2012


If a client is not responding, lower the brightness and
saturation to indicate it's stalled. The surface is restored
to it's original color values if the client later becomes
responsive.
---
 src/shell.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/src/shell.c b/src/shell.c
index 3e69320..1c97df2 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -137,6 +137,13 @@ struct shell_surface {
 
 	struct ping_timer *ping_timer;
 
+	struct {
+		struct weston_animation current;
+		int exists;
+		int fading_in;
+		uint32_t timestamp;
+	} unresponsive_animation;
+
 	struct weston_output *fullscreen_output;
 	struct weston_output *output;
 	struct wl_list link;
@@ -273,6 +280,68 @@ static const struct wl_pointer_grab_interface move_grab_interface = {
 	move_grab_button,
 };
 
+static void
+unresponsive_surface_fade(struct shell_surface *shsurf, bool reverse)
+{
+	shsurf->unresponsive_animation.fading_in = reverse ? 0 : 1;
+
+	if(!shsurf->unresponsive_animation.exists) {
+		wl_list_insert(&shsurf->surface->compositor->animation_list,
+		       &shsurf->unresponsive_animation.current.link);
+		shsurf->unresponsive_animation.exists = 1;
+		shsurf->unresponsive_animation.timestamp = weston_compositor_get_time();
+		weston_surface_damage(shsurf->surface);
+	}
+}
+
+static void
+ping_timeout_fade_frame(struct weston_animation *animation,
+		struct weston_output *output, uint32_t msecs)
+{
+	struct shell_surface *shsurf =
+		container_of(animation, struct shell_surface, unresponsive_animation.current);
+	struct weston_surface *surface = shsurf->surface;
+	unsigned int step = 32;
+
+	if (!surface || !shsurf)
+		return;
+
+	if (shsurf->unresponsive_animation.fading_in) {
+		while (step < msecs - shsurf->unresponsive_animation.timestamp) {
+			if (surface->saturation > 1)
+				surface->saturation -= 5;
+			if (surface->brightness > 200)
+				surface->brightness--;
+
+			shsurf->unresponsive_animation.timestamp += step;
+		}
+
+		if (surface->saturation <= 1 && surface->brightness <= 200) {
+			wl_list_remove(&shsurf->unresponsive_animation.current.link);
+			shsurf->unresponsive_animation.exists = 0;
+		}
+	}
+	else {
+		while (step < msecs - shsurf->unresponsive_animation.timestamp) {
+			if (surface->saturation < 255)
+				surface->saturation += 5;
+			if (surface->brightness < 255)
+				surface->brightness++;
+
+			shsurf->unresponsive_animation.timestamp += step;
+		}
+
+		if (surface->saturation >= 255 && surface->brightness >= 255) {
+			surface->saturation = surface->brightness = 255;
+			wl_list_remove(&shsurf->unresponsive_animation.current.link);
+			shsurf->unresponsive_animation.exists = 0;
+		}
+	}
+
+	surface->geometry.dirty = 1;
+	weston_surface_damage(surface);
+}
+
 static int
 ping_timeout_handler(void *data)
 {
@@ -287,6 +356,7 @@ ping_timeout_handler(void *data)
 	} else {
 		/* Client is not responding */
 		shsurf->unresponsive = 1;
+		unresponsive_surface_fade(shsurf, false);
 	}
 
 	return 1;
@@ -329,6 +399,10 @@ shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
 		return;
 
 	if (shsurf->ping_timer->serial == serial) {
+		if (shsurf->unresponsive) {
+			/* Received pong from previously unresponsive client */
+			unresponsive_surface_fade(shsurf, true);
+		}
 		shsurf->ping_timer->pong_received = 1;
 		shsurf->unresponsive = 0;
 		free(shsurf->ping_timer);
@@ -993,6 +1067,9 @@ shell_get_shell_surface(struct wl_client *client,
 	surface->configure = shell_surface_configure;
 
 	shsurf->unresponsive = 0;
+	shsurf->unresponsive_animation.exists = 0;
+	shsurf->unresponsive_animation.fading_in = 0;
+	shsurf->unresponsive_animation.current.frame = ping_timeout_fade_frame;
 
 	shsurf->resource.destroy = destroy_shell_surface;
 	shsurf->resource.object.id = id;
-- 
1.7.4.1



More information about the wayland-devel mailing list