[gtk+/wip/scrolledwindow-overlay-on-captured] scrolledwindow: Enable "hover" mode in scrollbars after a timeout



commit 880fcf199a4e1360a57d6c7ba17fd9d0e9fec7ff
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Dec 1 14:25:23 2014 +0100

    scrolledwindow: Enable "hover" mode in scrollbars after a timeout
    
    This way transient mouse movements over scrollbars don't cause flickering,
    and more spaced movements have it enabled shortly.

 gtk/gtkscrolledwindow.c |   71 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 57 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index e9fea39..bf118bc 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -174,6 +174,7 @@ typedef struct
   gint64     start_time;
   gint64     end_time;
   guint      tick_id;
+  guint      over_timeout_id;
 } Indicator;
 
 struct _GtkScrolledWindowPrivate
@@ -931,6 +932,12 @@ indicator_set_over (Indicator *indicator,
 {
   GtkStyleContext *context;
 
+  if (indicator->over_timeout_id)
+    {
+      g_source_remove (indicator->over_timeout_id);
+      indicator->over_timeout_id = 0;
+    }
+
   if (indicator->over == over)
     return;
 
@@ -989,6 +996,38 @@ event_close_to_indicator (GtkScrolledWindow *sw,
 }
 
 static gboolean
+enable_over_timeout_cb (gpointer user_data)
+{
+  Indicator *indicator = user_data;
+
+  indicator_set_over (indicator, TRUE);
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean
+check_update_scrollbar_proximity (GtkScrolledWindow *sw,
+                                  Indicator         *indicator,
+                                  GdkEvent          *event)
+{
+  gboolean indicator_close;
+
+  indicator_close = event_close_to_indicator (sw, indicator, event);
+
+  if (indicator->over_timeout_id)
+    {
+      g_source_remove (indicator->over_timeout_id);
+      indicator->over_timeout_id = 0;
+    }
+
+  if (indicator_close)
+    indicator->over_timeout_id = gdk_threads_add_timeout (30, enable_over_timeout_cb, indicator);
+  else
+    indicator_set_over (indicator, FALSE);
+
+  return indicator_close;
+}
+
+static gboolean
 captured_event_cb (GtkWidget *widget,
                    GdkEvent  *event)
 {
@@ -1016,13 +1055,17 @@ captured_event_cb (GtkWidget *widget,
       indicator_start_fade (&priv->hindicator, 1.0);
       indicator_start_fade (&priv->vindicator, 1.0);
 
-      /* Check whether we're hovering close to the horizontal scrollbar */
-      indicator_close = event_close_to_indicator (sw, &priv->hindicator, event);
-      indicator_set_over (&priv->hindicator, indicator_close);
+      /* Check whether we're hovering close to the vertical scrollbar */
+      indicator_close = check_update_scrollbar_proximity (sw, &priv->vindicator,
+                                                          event);
 
-      /* Same for the vertical scrollbar */
-      indicator_close = event_close_to_indicator (sw, &priv->vindicator, event);
-      indicator_set_over (&priv->vindicator, indicator_close);
+      if (!indicator_close)
+        {
+          /* Otherwise check the vertical scrollbar */
+          check_update_scrollbar_proximity (sw, &priv->hindicator, event);
+        }
+      else
+        indicator_set_over (&priv->hindicator, FALSE);
     }
   else if (event->type == GDK_LEAVE_NOTIFY &&
            event->crossing.mode == GDK_CROSSING_UNGRAB)
@@ -1032,15 +1075,9 @@ captured_event_cb (GtkWidget *widget,
       scrollbar = gtk_get_event_widget (event);
 
       if (scrollbar == priv->hindicator.scrollbar)
-        {
-          indicator_close = event_close_to_indicator (sw, &priv->hindicator, event);
-          indicator_set_over (&priv->hindicator, indicator_close);
-        }
+        check_update_scrollbar_proximity (sw, &priv->hindicator, event);
       else if (scrollbar == priv->vindicator.scrollbar)
-        {
-          indicator_close = event_close_to_indicator (sw, &priv->vindicator, event);
-          indicator_set_over (&priv->vindicator, indicator_close);
-        }
+        check_update_scrollbar_proximity (sw, &priv->vindicator, event);
     }
 
   return GDK_EVENT_PROPAGATE;
@@ -3736,6 +3773,12 @@ remove_indicator (GtkScrolledWindow *scrolled_window,
       indicator->conceil_timer = 0;
     }
 
+  if (indicator->over_timeout_id)
+    {
+      g_source_remove (indicator->over_timeout_id);
+      indicator->over_timeout_id = 0;
+    }
+
   if (indicator->tick_id)
     {
       gtk_widget_remove_tick_callback (scrollbar, indicator->tick_id);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]