[gtk+] Reduce roundtrips



commit 0f00d3fdb084eac236072361df19e030d390ea9b
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jun 20 13:54:33 2009 -0400

    Reduce roundtrips
    
    Setting a tooltip on a widget unfortunately triggers several roundtrips
    to the X server. We reduce this overhead by only doing it if the
    widget is visible, and by deferring to an idle. See bug 585626.

 gtk/gtkwidget.c |   49 +++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 41 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 16fdc2b..5cbf155 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -274,6 +274,7 @@ static void             gtk_widget_buildable_custom_finished    (GtkBuildable
 static void             gtk_widget_buildable_parser_finished    (GtkBuildable     *buildable,
                                                                  GtkBuilder       *builder);
 
+static void             gtk_widget_queue_tooltip_query          (GtkWidget *widget);
      
 static void gtk_widget_set_usize_internal (GtkWidget *widget,
 					   gint       width,
@@ -2488,17 +2489,18 @@ gtk_widget_set_property (GObject         *object,
        * because an empty string would be useless for a tooltip:
        */
       if (tooltip_markup && (strlen (tooltip_markup) == 0))
-      {
-	g_free (tooltip_markup);
-        tooltip_markup = NULL;
-      }
+        {
+	  g_free (tooltip_markup);
+          tooltip_markup = NULL;
+        }
 
       g_object_set_qdata_full (object, quark_tooltip_markup,
 			       tooltip_markup, g_free);
 
       tmp = (tooltip_window != NULL || tooltip_markup != NULL);
       gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
-      gtk_widget_trigger_tooltip_query (widget);
+      if (GTK_WIDGET_VISIBLE (widget))
+        gtk_widget_queue_tooltip_query (widget);
       break;
     case PROP_TOOLTIP_TEXT:
       tooltip_window = g_object_get_qdata (object, quark_tooltip_window);
@@ -2518,7 +2520,8 @@ gtk_widget_set_property (GObject         *object,
 
       tmp = (tooltip_window != NULL || tooltip_markup != NULL);
       gtk_widget_real_set_has_tooltip (widget, tmp, FALSE);
-      gtk_widget_trigger_tooltip_query (widget);
+      if (GTK_WIDGET_VISIBLE (widget))
+        gtk_widget_queue_tooltip_query (widget);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -10144,8 +10147,8 @@ gtk_widget_set_tooltip_window (GtkWidget *widget,
   has_tooltip = (custom_window != NULL || tooltip_markup != NULL);
   gtk_widget_real_set_has_tooltip (widget, has_tooltip, FALSE);
 
-  if (has_tooltip)
-    gtk_widget_trigger_tooltip_query (widget);
+  if (has_tooltip && GTK_WIDGET_VISIBLE (widget))
+    gtk_widget_queue_tooltip_query (widget);
 }
 
 /**
@@ -10184,6 +10187,36 @@ gtk_widget_trigger_tooltip_query (GtkWidget *widget)
   gtk_tooltip_trigger_tooltip_query (gtk_widget_get_display (widget));
 }
 
+static guint tooltip_query_id;
+static GSList *tooltip_query_displays;
+
+static gboolean
+tooltip_query_idle (gpointer data)
+{
+  g_slist_foreach (tooltip_query_displays, (GFunc)gtk_tooltip_trigger_tooltip_query, NULL);
+  g_slist_foreach (tooltip_query_displays, (GFunc)g_object_unref, NULL);
+  g_slist_free (tooltip_query_displays);
+
+  tooltip_query_displays = NULL;
+  tooltip_query_id = 0;
+
+  return FALSE;
+}
+
+static void
+gtk_widget_queue_tooltip_query (GtkWidget *widget)
+{
+  GdkDisplay *display;
+
+  display = gtk_widget_get_display (widget);
+
+  if (!g_slist_find (tooltip_query_displays, display))
+    tooltip_query_displays = g_slist_prepend (tooltip_query_displays, g_object_ref (display));
+
+  if (tooltip_query_id == 0)
+    tooltip_query_id = gdk_threads_add_idle (tooltip_query_idle, NULL);
+}
+
 /**
  * gtk_widget_set_tooltip_text:
  * @widget: a #GtkWidget



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