[PATCH 3/3] Dim unresponsive windows
Scott Moreau
oreaus at gmail.com
Mon Apr 16 10:25:42 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/compositor.c | 3 ++
src/compositor.h | 10 +++++++
src/shell.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 0 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 3667f39..2b00f6c 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -656,6 +656,9 @@ destroy_surface(struct wl_resource *resource)
if (!region_is_undefined(&surface->input))
pixman_region32_fini(&surface->input);
+ if (surface->unresponsive_animation.exists)
+ wl_list_remove(&surface->unresponsive_animation.current.link);
+
free(surface);
}
diff --git a/src/compositor.h b/src/compositor.h
index a9fa69f..6aaa4de 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -336,6 +336,16 @@ struct weston_surface {
struct wl_listener buffer_destroy_listener;
/*
+ * This is used to indicate a client is currently not responding
+ */
+ struct {
+ struct weston_animation current;
+ int exists;
+ int fading_in;
+ uint32_t timestamp;
+ } unresponsive_animation;
+
+ /*
* If non-NULL, this function will be called on surface::attach after
* a new buffer has been set up for this surface. The integer params
* are the sx and sy paramerters supplied to surface::attach .
diff --git a/src/shell.c b/src/shell.c
index d8374fa..9e2a108 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -275,6 +275,69 @@ static const struct wl_pointer_grab_interface move_grab_interface = {
move_grab_button,
};
+static void
+unresponsive_surface_fade(struct weston_surface *surface, bool reverse)
+{
+ surface->unresponsive_animation.fading_in = reverse ? 0 : 1;
+
+ if(!surface->unresponsive_animation.exists) {
+ wl_list_insert(&surface->compositor->animation_list,
+ &surface->unresponsive_animation.current.link);
+ surface->unresponsive_animation.exists = 1;
+ surface->unresponsive_animation.timestamp = weston_compositor_get_time();
+ weston_surface_damage(surface);
+ }
+}
+
+static void
+ping_timeout_fade_frame(struct weston_animation *animation,
+ struct weston_output *output, uint32_t msecs)
+{
+ struct weston_surface *surface =
+ container_of(animation, struct weston_surface, unresponsive_animation.current);
+ struct shell_surface *shsurf =
+ container_of(&surface, struct shell_surface, surface);
+ unsigned int step = 32;
+
+ if (!surface || !shsurf)
+ return;
+
+ if (surface->unresponsive_animation.fading_in) {
+ while (step < msecs - surface->unresponsive_animation.timestamp) {
+ if (surface->saturation > 1)
+ surface->saturation -= 5;
+ if (surface->brightness > 200)
+ surface->brightness--;
+
+ surface->unresponsive_animation.timestamp += step;
+ }
+
+ if (surface->saturation <= 1 && surface->brightness <= 200) {
+ wl_list_remove(&surface->unresponsive_animation.current.link);
+ surface->unresponsive_animation.exists = 0;
+ }
+ }
+ else {
+ while (step < msecs - surface->unresponsive_animation.timestamp) {
+ if (surface->saturation < 255)
+ surface->saturation += 5;
+ if (surface->brightness < 255)
+ surface->brightness++;
+
+ surface->unresponsive_animation.timestamp += step;
+ }
+
+ if (surface->saturation >= 255 && surface->brightness >= 255) {
+ surface->saturation = surface->brightness = 255;
+ wl_list_remove(&surface->unresponsive_animation.current.link);
+ surface->unresponsive_animation.exists = 0;
+ }
+ }
+
+ surface->geometry.dirty = 1;
+ weston_surface_damage(surface);
+}
+
static int
ping_timeout_handler(void *data)
{
@@ -303,6 +366,7 @@ ping_timeout_handler(void *data)
else {
/* Client is not responding */
timer->shsurf->is_not_responsive = 1;
+ unresponsive_surface_fade(timer->shsurf->surface, false);
}
return 1;
@@ -345,6 +409,10 @@ shell_surface_pong(struct wl_client *client, struct wl_resource *resource,
wl_list_for_each(timer, &shsurf->ping_timer_list, link) {
if (timer->serial == serial) {
+ if (timer->shsurf->is_not_responsive) {
+ /* Received pong from previously unresponsive client */
+ unresponsive_surface_fade(timer->shsurf->surface, true);
+ }
timer->pong_received = 1;
timer->shsurf->is_not_responsive = 0;
}
@@ -1009,6 +1077,9 @@ shell_get_shell_surface(struct wl_client *client,
}
surface->configure = shell_surface_configure;
+ surface->unresponsive_animation.exists = 0;
+ surface->unresponsive_animation.fading_in = 0;
+ surface->unresponsive_animation.current.frame = ping_timeout_fade_frame;
shsurf->is_not_responsive = 0;
--
1.7.4.1
More information about the wayland-devel
mailing list