From 242d0c5d2288bfab6f6674b94949719962b35b5e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 18 Jun 2013 11:11:14 +0200 Subject: [PATCH] Revert "GtkWindow: Move cairo_save/restore from marshaller" This reverts commit 6c7689506f8b6c71522e6c8a25a2b4523641592c. This is not right as we need to save/restore around *each* callback, not just each emission. --- gtk/gtkwidget.c | 70 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index c78522f762..9626c800f3 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -953,6 +953,64 @@ child_property_notify_dispatcher (GObject *object, GTK_WIDGET_GET_CLASS (object)->dispatch_child_properties_changed (GTK_WIDGET (object), n_pspecs, pspecs); } +/* We guard against the draw signal callbacks modifying the state of the + * cairo context by surounding it with save/restore. + * Maybe we should also cairo_new_path() just to be sure? + */ +static void +gtk_widget_draw_marshaller (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + cairo_t *cr = g_value_get_boxed (¶m_values[1]); + + cairo_save (cr); + + _gtk_marshal_BOOLEAN__BOXED (closure, + return_value, + n_param_values, + param_values, + invocation_hint, + marshal_data); + + + cairo_restore (cr); +} + +static void +gtk_widget_draw_marshallerv (GClosure *closure, + GValue *return_value, + gpointer instance, + va_list args, + gpointer marshal_data, + int n_params, + GType *param_types) +{ + cairo_t *cr; + va_list args_copy; + + G_VA_COPY (args_copy, args); + cr = va_arg (args_copy, gpointer); + + cairo_save (cr); + + _gtk_marshal_BOOLEAN__BOXEDv (closure, + return_value, + instance, + args, + marshal_data, + n_params, + param_types); + + + cairo_restore (cr); + + va_end (args_copy); +} + static void gtk_widget_class_init (GtkWidgetClass *klass) { @@ -1900,12 +1958,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GtkWidgetClass, draw), - _gtk_boolean_handled_accumulator, NULL, - _gtk_marshal_BOOLEAN__BOXED, + _gtk_boolean_handled_accumulator, NULL, + gtk_widget_draw_marshaller, G_TYPE_BOOLEAN, 1, - CAIRO_GOBJECT_TYPE_CONTEXT | G_SIGNAL_TYPE_STATIC_SCOPE); + CAIRO_GOBJECT_TYPE_CONTEXT); g_signal_set_va_marshaller (widget_signals[DRAW], G_TYPE_FROM_CLASS (klass), - _gtk_marshal_BOOLEAN__BOXEDv); + gtk_widget_draw_marshallerv); /** * GtkWidget::mnemonic-activate: @@ -6337,14 +6395,10 @@ _gtk_widget_draw_internal (GtkWidget *widget, { gboolean result; - cairo_save (cr); - g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); - cairo_restore (cr); - #ifdef G_ENABLE_DEBUG if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_BASELINES)) {