+static void
+gtk_tooltips_show_tip (GtkWidget *widget)
+{
+ GtkTooltipsData *tooltipsdata;
+
+ tooltipsdata = gtk_tooltips_data_get (widget);
+
+ if (tooltipsdata &&
+ (!tooltipsdata->tooltips->active_tips_data ||
+ tooltipsdata->tooltips->active_tips_data->widget != widget))
+ {
+ gtk_tooltips_set_active_widget (tooltipsdata->tooltips, widget);
+ gtk_tooltips_draw_tips (tooltipsdata->tooltips);
+ }
+}
+
+static void
+gtk_tooltips_hide_tip (GtkWidget *widget)
+{
+ GtkTooltipsData *tooltipsdata;
+
+ tooltipsdata = gtk_tooltips_data_get (widget);
+
+ if (tooltipsdata &&
+ (tooltipsdata->tooltips->active_tips_data &&
+ tooltipsdata->tooltips->active_tips_data->widget == widget))
+ gtk_tooltips_set_active_widget (tooltipsdata->tooltips, NULL);
+}
+
+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 gboolean
+get_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ return GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (toplevel), "gtk-tooltips-keyboard-mode"));
+ else
+ return FALSE;
+}
+
+static void
+start_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ GtkWidget *focus = GTK_WINDOW (toplevel)->focus_widget;
+
+ g_object_set_data (G_OBJECT (toplevel), I_("gtk-tooltips-keyboard-mode"), GUINT_TO_POINTER (TRUE));
+
+ if (focus)
+ gtk_tooltips_show_tip (focus);
+ }
+}
+
+static void
+stop_keyboard_mode (GtkWidget *widget)
+{
+ GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ GtkWidget *focus = GTK_WINDOW (toplevel)->focus_widget;
+ if (focus)
+ gtk_tooltips_hide_tip (focus);
+
+ g_object_set_data (G_OBJECT (toplevel), I_("gtk-tooltips-keyboard-mode"), GUINT_TO_POINTER (FALSE));
+ }
+}
+
+static gboolean
+tooltips_enabled (GtkTooltips *tooltips, GtkWidget *w)
+{
+ GtkSettings *settings;
+ gboolean touchscreen;
+
+ if (!tooltips->enabled)
+ return FALSE;
+
+ settings = gtk_widget_get_settings (w);
+ g_object_get (settings, "gtk-touchscreen-mode", &touchscreen, NULL);
+
+ return !touchscreen;
+}
+
+static void
+gtk_tooltips_start_delay (GtkTooltips *tooltips,
+ GtkWidget *widget)
+{
+ GtkTooltipsData *old_tips_data;
+
+ old_tips_data = tooltips->active_tips_data;
+ if (tooltips_enabled (tooltips, widget) &&
+ (!old_tips_data || old_tips_data->widget != widget))
+ {
+ guint delay;
+
+ gtk_tooltips_set_active_widget (tooltips, widget);
+
+ if (tooltips->use_sticky_delay &&
+ gtk_tooltips_recently_shown (tooltips))
+ delay = STICKY_DELAY;
+ else
+ delay = tooltips->delay;
+ tooltips->timer_tag = g_timeout_add (delay,
+ gtk_tooltips_timeout,
+ (gpointer) tooltips);
+ }
+}
+
+static void