Patch: "sticky" tooltips



Here is a patch which I believe makes tooltips more user friendly.

E.g. in a toolbar or the Glade palette, you can pause over the first
widget until a tooltip window pops up (after normal delay). Then you
can move the mouse around, and tooltips pop up without delay. Normal
behaviour returns a certain time after the last tooltip pops down.

More precisely, what happens is this:

A timestamp is recorded each time a tooltip window pops down. When a
widget with tooltips is entered, we check if < tooltips->sticky_delay
has elapsed since last popdown. If true, the tooltip window pops up
immediately.

The API to implement this is:

gtk_tooltips_set_sticky_delay (GtkTooltips *tooltips,
                               guint        sticky_delay);

Setting sticky_delay to 0 yields traditional behaviour.

The private fields 

  guint   sticky_delay;
  GTimeVal last_popdown;

are added to the GtkTooltips struct.

The included patch is against the 1.3 branch of CVS. I enabled the new
behaviour by default. I see no reason not to do that, but if you
disagree, that's easy to change.

Regards

Jon Kåre

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.1259
diff -u -r1.1259 ChangeLog
--- ChangeLog	2000/06/02 03:13:52	1.1259
+++ ChangeLog	2000/06/02 08:48:01
@@ -1,3 +1,22 @@
+2000-06-02  Jon K Hellan  <hellan@acm.org>
+
+	Implement fast browsing of tooltips:
+	
+	* gtk/gtktooltips.h (struct _GtkTooltips): Add sticky_delay and
+	last_popdown
+	(gtk_tooltips_set_sticky_delay): Declare it.
+	
+	* gtk/gtktooltips.c (gtk_tooltips_init): Initialize stick_delay
+	and last_popdown.
+	(gtk_tooltips_set_sticky_delay): New public function. Set sticky
+	delay.
+	(gtk_tooltips_draw_tips, gtk_tooltips_set_active_widget): Record
+	time of popdown.
+	(gtk_tooltips_recently_shown): New static function. 
+	Return true if < sticky_delay has elapsed since last popdown.
+	(gtk_tooltips_event_handler): Display window without delay 
+	if < sticky_delay has elapsed since last popdown.
+
 Thu Jun  1 23:05:13 2000  Owen Taylor  <otaylor@redhat.com>
 
 	* gtk/gtkwidget.c: Remove all references to 
Index: gtk/gtktooltips.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktooltips.h,v
retrieving revision 1.14
diff -u -r1.14 gtktooltips.h
--- gtk/gtktooltips.h	2000/06/02 03:14:06	1.14
+++ gtk/gtktooltips.h	2000/06/02 08:48:02
@@ -68,6 +68,8 @@
   guint   delay : 30;
   guint	  enabled : 1;
   gint	  timer_tag;
+  guint   sticky_delay;
+  GTimeVal last_popdown;
 };
 
 struct _GtkTooltipsClass
@@ -82,6 +84,8 @@
 void		 gtk_tooltips_disable	   (GtkTooltips   *tooltips);
 void		 gtk_tooltips_set_delay	   (GtkTooltips   *tooltips,
 					    guint	   delay);
+void		 gtk_tooltips_set_sticky_delay (GtkTooltips   *tooltips,
+					    guint	   sticky_delay);
 void		 gtk_tooltips_set_tip	   (GtkTooltips   *tooltips,
 					    GtkWidget	  *widget,
 					    const gchar   *tip_text,
Index: gtk/gtktooltips.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtktooltips.c,v
retrieving revision 1.28
diff -u -r1.28 gtktooltips.c
--- gtk/gtktooltips.c	2000/06/02 03:14:06	1.28
+++ gtk/gtktooltips.c	2000/06/02 08:48:02
@@ -103,8 +103,11 @@
   tooltips->tips_data_list = NULL;
   
   tooltips->delay = DEFAULT_DELAY;
+  tooltips->sticky_delay = DEFAULT_DELAY;
   tooltips->enabled = TRUE;
   tooltips->timer_tag = 0;
+  tooltips->last_popdown.tv_sec = -1;
+  tooltips->last_popdown.tv_usec = -1;
 }
 
 GtkTooltips *
@@ -219,6 +222,15 @@
   tooltips->delay = delay;
 }
 
+void
+gtk_tooltips_set_sticky_delay (GtkTooltips *tooltips,
+			       guint        sticky_delay)
+{
+  g_return_if_fail (tooltips != NULL);
+
+  tooltips->sticky_delay = sticky_delay;
+}
+
 GtkTooltipsData*
 gtk_tooltips_data_get (GtkWidget       *widget)
 {
@@ -314,7 +326,11 @@
   if (!tooltips->tip_window)
     gtk_tooltips_force_window (tooltips);
   else if (GTK_WIDGET_VISIBLE (tooltips->tip_window))
-    gtk_widget_hide (tooltips->tip_window);
+    {
+      gtk_widget_hide (tooltips->tip_window);
+      if (tooltips->sticky_delay > 0)
+	g_get_current_time (&tooltips->last_popdown);
+    }
 
   gtk_widget_ensure_style (tooltips->tip_window);
   style = tooltips->tip_window->style;
@@ -373,7 +389,12 @@
                                 GtkWidget   *widget)
 {
   if (tooltips->tip_window)
-    gtk_widget_hide (tooltips->tip_window);
+    {
+      if (tooltips->sticky_delay > 0 &&
+	  GTK_WIDGET_VISIBLE (tooltips->tip_window))
+	g_get_current_time (&tooltips->last_popdown);
+      gtk_widget_hide (tooltips->tip_window);
+    }
   if (tooltips->timer_tag)
     {
       gtk_timeout_remove (tooltips->timer_tag);
@@ -403,6 +424,19 @@
 }
 
 static gint
+gtk_tooltips_recently_shown (GtkTooltips *tooltips)
+{
+  GTimeVal now;
+  glong msec;
+  
+  g_get_current_time (&now);
+  msec = (now.tv_sec  - tooltips->last_popdown.tv_sec) * 1000 +
+	  (now.tv_usec - tooltips->last_popdown.tv_usec) / 1000;
+  
+  return (msec < tooltips->sticky_delay);
+}
+
+static gint
 gtk_tooltips_event_handler (GtkWidget *widget,
                             GdkEvent  *event)
 {
@@ -435,9 +469,13 @@
 	{
 	  gtk_tooltips_set_active_widget (tooltips, widget);
 	  
-	  tooltips->timer_tag = gtk_timeout_add (tooltips->delay,
-						 gtk_tooltips_timeout,
-						 (gpointer) tooltips);
+	  if (tooltips->sticky_delay > 0 &&
+	      gtk_tooltips_recently_shown (tooltips))
+	    gtk_tooltips_timeout ((gpointer) tooltips);
+	  else
+  	    tooltips->timer_tag = gtk_timeout_add (tooltips->delay,
+						   gtk_tooltips_timeout,
+						   (gpointer) tooltips);
 	}
       break;
 





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