Blob Blame History Raw
From 409bc356e6a7856795826c1e83b5b390e3183566 Mon Sep 17 00:00:00 2001
From: Benjamin Herr <ben@0x539.de>
Date: Sun, 20 Jul 2014 02:30:46 +0200
Subject: [PATCH] Track flash opacity explicitly

Retrieving the opacity of the flash, reducing it by an exponentially
small step, and setting it again does not always actually decrease the
widget's opacity, and so the fading does not actually terminate.

Incidentally, also unset the flash timeout tags to avoid calling
g_source_remove() spuriously.

https://bugzilla.gnome.org/show_bug.cgi?id=733433
---
 libcheese/cheese-flash.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/libcheese/cheese-flash.c b/libcheese/cheese-flash.c
index 3ea9848..7970b71 100644
--- a/libcheese/cheese-flash.c
+++ b/libcheese/cheese-flash.c
@@ -74,6 +74,7 @@ struct _CheeseFlashPrivate
   GtkWidget *parent;
   guint flash_timeout_tag;
   guint fade_timeout_tag;
+  gdouble opacity;
 };
 
 static void
@@ -86,6 +87,7 @@ cheese_flash_init (CheeseFlash *self)
 
   priv->flash_timeout_tag = 0;
   priv->fade_timeout_tag  = 0;
+  priv->opacity = 1.0;
 
   /* make it so it doesn't look like a window on the desktop (+fullscreen) */
   gtk_window_set_decorated (window, FALSE);
@@ -191,17 +193,24 @@ static gboolean
 cheese_flash_opacity_fade (gpointer data)
 {
   GtkWindow *flash_window = GTK_WINDOW (data);
-  gdouble opacity = gtk_window_get_opacity (flash_window);
+  CheeseFlashPrivate *flash_priv;
+
+  flash_priv = CHEESE_FLASH (data)->priv;
 
   /* exponentially decrease */
-  gtk_window_set_opacity (flash_window, opacity * FLASH_FADE_FACTOR);
+  flash_priv->opacity *= FLASH_FADE_FACTOR;
 
-  if (opacity <= FLASH_LOW_THRESHOLD)
+  if (flash_priv->opacity <= FLASH_LOW_THRESHOLD)
   {
     /* the flasher has finished when we reach the quit value */
     gtk_widget_hide (GTK_WIDGET (flash_window));
+    flash_priv->fade_timeout_tag = 0;
     return G_SOURCE_REMOVE;
   }
+  else
+  {
+    gtk_window_set_opacity (flash_window, flash_priv->opacity);
+  }
 
   return G_SOURCE_CONTINUE;
 }
@@ -229,6 +238,7 @@ cheese_flash_start_fade (gpointer data)
   }
 
   flash_priv->fade_timeout_tag = g_timeout_add (1000.0 / FLASH_ANIMATION_RATE, cheese_flash_opacity_fade, data);
+  flash_priv->flash_timeout_tag = 0;
   return G_SOURCE_REMOVE;
 }
 
@@ -257,9 +267,18 @@ cheese_flash_fire (CheeseFlash *flash)
   flash_window = GTK_WINDOW (flash);
 
   if (flash_priv->flash_timeout_tag > 0)
+  {
     g_source_remove (flash_priv->flash_timeout_tag);
+    flash_priv->flash_timeout_tag = 0;
+  }
+
   if (flash_priv->fade_timeout_tag > 0)
+  {
     g_source_remove (flash_priv->fade_timeout_tag);
+    flash_priv->fade_timeout_tag = 0;
+  }
+
+  flash_priv->opacity = 1.0;
 
   parent  = gtk_widget_get_toplevel (flash_priv->parent);
   screen  = gtk_widget_get_screen (parent);
-- 
2.1.0