1 /* Utility functions for timing widgets
4 * Federico Mena-Quintero <federico@novell.com>
6 * To measure how long it takes to fully map and expose a toplevel window, we
7 * use a trick which Owen Taylor described on IRC one day:
10 * 2. Call gtk_widget_show_all() on the toplevel window.
11 * 3. In the expose_event handler of the window, queue an idle handler with
13 * 4. In the idle handler, change a property on the toplevel window.
14 * 5. In the property_notify_event handler, stop the timer.
19 #include <gtk/gtkmain.h>
26 TimerReportFunc report_func;
31 widget_property_notify_event_cb (GtkWidget *widget, GdkEventProperty *event, gpointer data)
33 struct timer_closure *closure;
38 if (event->atom != gdk_atom_intern ("window_property_change", FALSE))
41 /* Finish timing map/expose */
43 elapsed = g_timer_elapsed (closure->timer, NULL);
44 (* closure->report_func) (TIMER_REPORT_WIDGET_SHOW, elapsed, closure->user_data);
46 /* Time destruction */
48 g_timer_reset (closure->timer);
49 gtk_widget_destroy (widget);
50 elapsed = g_timer_elapsed (closure->timer, NULL);
51 (* closure->report_func) (TIMER_REPORT_WIDGET_DESTRUCTION, elapsed, closure->user_data);
53 gtk_main_quit (); /* This will get us back to the end of timer_time_widget() */
58 idle_after_expose_cb (gpointer data)
60 struct timer_closure *closure;
64 gdk_property_change (closure->widget->window,
65 gdk_atom_intern ("window_property_change", FALSE),
66 gdk_atom_intern ("STRING", FALSE),
68 GDK_PROP_MODE_REPLACE,
76 widget_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data)
78 struct timer_closure *closure;
82 g_idle_add_full (G_PRIORITY_HIGH, idle_after_expose_cb, closure, NULL);
87 instrument_widget (GtkWidget *widget,
88 struct timer_closure *closure)
90 g_signal_connect (widget, "expose-event",
91 G_CALLBACK (widget_expose_event_cb), closure);
93 gtk_widget_add_events (widget, GDK_PROPERTY_CHANGE_MASK);
94 g_signal_connect (widget, "property-notify-event",
95 G_CALLBACK (widget_property_notify_event_cb), closure);
99 timer_time_widget (TimerWidgetCreateFunc create_func,
100 TimerReportFunc report_func,
106 struct timer_closure closure;
108 g_assert (create_func != NULL);
109 g_assert (report_func != NULL);
113 timer = g_timer_new ();
114 widget = (* create_func) (user_data);
115 g_assert (widget != NULL);
116 g_assert (!GTK_WIDGET_VISIBLE (widget) && !GTK_WIDGET_MAPPED (widget));
117 elapsed = g_timer_elapsed (timer, NULL);
119 (* report_func) (TIMER_REPORT_WIDGET_CREATION, elapsed, user_data);
121 /* Start timing map/expose */
123 closure.timer = timer;
124 closure.widget = widget;
125 closure.report_func = report_func;
126 closure.user_data = user_data;
127 instrument_widget (widget, &closure);
129 g_timer_reset (timer);
130 gtk_widget_show_all (widget);
133 /* Expose time and destruction time get recorded in widget_property_notify_event_cb() */