[gtk+] eventcontroller, widget: Don't crash if destroyed before the other



commit 7c4bf742e82d812ecc5b0c3280db86d2689eb093
Author: Debarshi Ray <debarshir gnome org>
Date:   Sun Mar 1 13:28:21 2015 +0100

    eventcontroller, widget: Don't crash if destroyed before the other
    
    There are two scenarios. A widget sub-class owns a GtkEventController
    and passes itself to it, or a controller owned by something else is
    passed a widget.
    
    In the second case, if the widget is destroyed before the controller,
    we will have a crash when destructing the controller because we will
    be accessing invalid memory. Adding a weak reference on the widget
    addresses that problem.
    
    This leads to a crash in the first case. When the widget is getting
    destroyed, it will drop the reference to its own controller. The
    controller will skip touching the widget because the weak reference
    would have turned it to NULL. However, when the widget sub-class chains
    up to GtkWidget it will try to free all the controllers in its list.
    Unfortunately, all these controllers have already been destroyed. So
    we need to guard against this too.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745225

 gtk/gtkeventcontroller.c |    1 +
 gtk/gtkwidget.c          |    2 ++
 2 files changed, 3 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkeventcontroller.c b/gtk/gtkeventcontroller.c
index 4a77040..c20c84e 100644
--- a/gtk/gtkeventcontroller.c
+++ b/gtk/gtkeventcontroller.c
@@ -75,6 +75,7 @@ gtk_event_controller_set_property (GObject      *object,
     {
     case PROP_WIDGET:
       priv->widget = g_value_get_object (value);
+      g_object_add_weak_pointer (G_OBJECT (priv->widget), (gpointer *) &priv->widget);
       break;
     case PROP_PROPAGATION_PHASE:
       gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (object),
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 11307c6..7f132df 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -17221,6 +17221,8 @@ _gtk_widget_add_controller (GtkWidget           *widget,
     g_signal_connect (widget, "grab-notify",
                       G_CALLBACK (event_controller_grab_notify), data);
 
+  g_object_add_weak_pointer (G_OBJECT (data->controller), (gpointer *) &data->controller);
+
   if (GTK_IS_GESTURE (controller))
     {
       data->sequence_state_changed_id =


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