Re: Patch: "sticky" tooltips (again)



I posted the following before I went on vacation a month ago. There have been
no reactions. Is it all junk, or do you want me to change it in some
way?

Some time ago, I proposed a patch to change tooltips behaviour as
follows:

> 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.

Tim Janik responded with some comments. Here is a version with his
suggested changes.

Tim Janik <timj@gtk.org> wrote:
> the way i read your patch, you stay in sticky mode even if you perform
> normal actions like pressing a button or a key.
> there, you should actually leave sticky mode, i.e. the tooltips only popup
> with a (shorter) sticky delay if we just recently showed a tooltip and
> only processed enter/leave events meanwhile. that is, to pseudo patch the
> code:

I've done as suggested. It won't catch button or key presses in
widgets which do not use this tooltip, but that's not much of a
problem in practice.

> rather than comparing the timestamp against the sticky delay, i'd probably
> use it to constrain the code path (in the above patch) for usage of the
> sticky_delay to a certain threshold, say 3 seconds (so when a tooltip popped
> down, and the next one is supposed to popup with sticky_delay, that'll only
> happen within the next three seconds).

OK. I've hardcoded 1 s. STICKY_REVERT_DELAY. I hate to hardcode
things, but it isn't very useful to tune.

> > 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.
> 
> i think that is fine, if you implement something like the above, letting
> sticky_delay default to 0 is probably a good idea.

Have done so.

Regards

Jon Kåre

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.1341
diff -u -r1.1341 ChangeLog
--- ChangeLog	2000/07/21 13:26:23	1.1341
+++ ChangeLog	2000/07/21 14:11:35
@@ -1,3 +1,25 @@
+2000-07-21  Jon K Hellan  <hellan@acm.org>
+
+	Implement fast browsing of tooltips:
+	
+	* gtk/gtktooltips.h (struct _GtkTooltips): Add sticky_delay,
+	use_sticky_delay and last_popdown
+	(gtk_tooltips_set_sticky_delay): Declare it.
+	
+	* gtk/gtktooltips.c (gtk_tooltips_init): Initialize sticky_delay,
+	use_sticky_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_set_active_widget): Unset sticky behaviour if widget
+	is NULL.
+	(gtk_tooltips_recently_shown): New static function.  Return true
+	if < sticky_delay has elapsed since last popdown.
+	(gtk_tooltips_event_handler): Display window after sticky_delay
+	(presumably < normal delay) if < STICKY_REVERT_DELAY has elapsed
+	since last popdown.
+
 Fri Jul 21 14:23:51 BST 2000  Tony Gale <gale@gtk.org>
 
 	* docs/tutorial/gtk-tut.sgml: Minor updates
@@ -61,7 +83,6 @@
  	* gtk/themes.[ch]: add a function gtk_theme_engine_register_type()
 	to register a type associated with an engine. (The engine
 	won't be unloaded as there is an instance of the type.)
-
 
 Mon Jul 17 18:19:06 BST 2000  Tony Gale <gale@gtk.org>
 
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/07/21 14:11:36
@@ -38,6 +38,8 @@
 
 
 #define DEFAULT_DELAY 500           /* Default delay in ms */
+#define STICKY_REVERT_DELAY 1000    /* Delay before sticky tooltips revert
+				     * to normal */
 
 static void gtk_tooltips_class_init        (GtkTooltipsClass *klass);
 static void gtk_tooltips_init              (GtkTooltips      *tooltips);
@@ -103,8 +105,12 @@
   tooltips->tips_data_list = NULL;
   
   tooltips->delay = DEFAULT_DELAY;
+  tooltips->sticky_delay = 0;
   tooltips->enabled = TRUE;
   tooltips->timer_tag = 0;
+  tooltips->use_sticky_delay = FALSE;
+  tooltips->last_popdown.tv_sec = -1;
+  tooltips->last_popdown.tv_usec = -1;
 }
 
 GtkTooltips *
@@ -219,6 +225,16 @@
   tooltips->delay = delay;
 }
 
+void
+gtk_tooltips_set_sticky_delay (GtkTooltips *tooltips,
+			       guint        sticky_delay)
+{
+  g_return_if_fail (tooltips != NULL);
+  g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));
+
+  tooltips->sticky_delay = sticky_delay;
+}
+
 GtkTooltipsData*
 gtk_tooltips_data_get (GtkWidget       *widget)
 {
@@ -314,7 +330,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 +393,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);
@@ -400,8 +425,24 @@
 	    }
 	}
     }
+  else
+    {
+      tooltips->use_sticky_delay = FALSE;
+    }
 }
 
+static gboolean
+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 < STICKY_REVERT_DELAY);
+}
+
 static gint
 gtk_tooltips_event_handler (GtkWidget *widget,
                             GdkEvent  *event)
@@ -433,14 +474,31 @@
       if (tooltips->enabled &&
 	  (!old_tips_data || old_tips_data->widget != widget))
 	{
+	  guint delay;
+	  
 	  gtk_tooltips_set_active_widget (tooltips, widget);
 	  
-	  tooltips->timer_tag = gtk_timeout_add (tooltips->delay,
+	  if (tooltips->use_sticky_delay  &&
+	      gtk_tooltips_recently_shown (tooltips))
+	    delay = tooltips->sticky_delay;
+	  else
+	    delay = tooltips->delay;
+	  tooltips->timer_tag = gtk_timeout_add (delay,
 						 gtk_tooltips_timeout,
 						 (gpointer) tooltips);
 	}
       break;
 
+    case GDK_LEAVE_NOTIFY:
+      {
+	gboolean use_sticky_delay;
+
+	use_sticky_delay = tooltips->tip_window &&
+		GTK_WIDGET_VISIBLE (tooltips->tip_window);
+	gtk_tooltips_set_active_widget (tooltips, NULL);
+	tooltips->use_sticky_delay = use_sticky_delay;
+      }
+      break;
     default:
       gtk_tooltips_set_active_widget (tooltips, NULL);
       break;
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/07/21 14:11:36
@@ -68,6 +68,9 @@
   guint   delay : 30;
   guint	  enabled : 1;
   gint	  timer_tag;
+  guint   sticky_delay;
+  gboolean use_sticky_delay;
+  GTimeVal last_popdown;
 };
 
 struct _GtkTooltipsClass
@@ -82,6 +85,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,




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