Re: Patch: "sticky" tooltips



On Fri, 2 Jun 2000, Jon K Hellan wrote:

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

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:

gtk_tooltips_set_active_widget (...
{
  [...]
+  tooltips->use_sticky_delay = FALSE;
}

gtk_tooltips_event_handler (...
{
  [...]
  switch (event->type)
    {
+     gboolean use_sticky_delay;
    case GDK_MOTION_NOTIFY:
    case GDK_EXPOSE:
      /* do nothing */
      break;

    case GDK_ENTER_NOTIFY:
      old_tips_data = tooltips->active_tips_data;
      if (tooltips->enabled &&
          (!old_tips_data || old_tips_data->widget != widget))
        {
          gtk_tooltips_set_active_widget (tooltips, widget);

-         tooltips->timer_tag = gtk_timeout_add (tooltips->delay,
+         tooltips->timer_tag = gtk_timeout_add (tooltips->use_sticky_delay ? tooltips->sticky_delay : tooltips->delay,
                                                 gtk_tooltips_timeout,
                                                 (gpointer) tooltips);
        }
      break;
+
+   case GDK_LEAVE_NOTIFY:
+     use_sticky_delay = 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;
    }

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

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

> The API to implement this is:
> 
> gtk_tooltips_set_sticky_delay (GtkTooltips *tooltips,
>                                guint        sticky_delay);
> 
> Setting sticky_delay to 0 yields traditional behaviour.

i'm of course changing the semantics of your sticky_delay settings here,
that is with sticky_delay==delay you get the traditional behaviour, and
with sticky_delay=0 you get immediate popups of successive tooltips when
just moving around.

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

i think that is fine, if you implement something like the above, letting
sticky_delay default to 0 is probably a good idea.

> 
> Regards
> 
> Jon Kåre
> 


> 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

> @@ -219,6 +222,15 @@
>    tooltips->delay = delay;
>  }
>  
> +void
> +gtk_tooltips_set_sticky_delay (GtkTooltips *tooltips,
> +			       guint        sticky_delay)
> +{
> +  g_return_if_fail (tooltips != NULL);

make this:

g_return_if_fail (GTK_IS_TOOLTIPS (tooltips));

> +  tooltips->sticky_delay = sticky_delay;
> +}
> +
>  GtkTooltipsData*
>  gtk_tooltips_data_get (GtkWidget       *widget)
>  {

>  static gint

this should return gboolean for better readability.

> +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;

gtk_tooltips_timeout() is (intended to be) a pure timeout function,
as such it should:
1) reset timer_tag to 0 if it returns FALSE (needs to be fixed)
2) only be called from the mainloop, so simply use gtk_timeout_add (0, ...)
   to invoke it.

---
ciaoTJ





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