[gtk+/gtk-3-22] Widget: Don’t call reset() on NULL EventController



commit b8e2430486ae3dac4f0c0441608f2d1b032ac794
Author: Daniel Boles <dboles src gnome org>
Date:   Thu Jan 18 00:51:24 2018 +0000

    Widget: Don’t call reset() on NULL EventController
    
    GtkGesture is a GtkEventController. gtk_event_controller_dispose() calls
    _gtk_widget_remove_controller(). That NULLs the pointer-to-Controller in
    our EventControllerData but does not delete said ECData from our GList.
    
    Subsequently, if that same Widget gets unparent()ed, that method calls
    unset_state_flags(), which leads to doing reset_controllers() if we are
    insensitive. Now, unlike most most other loops over the GList of ECData,
    reset_controllers() does not skip nodes whose pointer-to-Controller is
    NULL. So, we call gtk_event_controller_reset(NULL) and get a CRITICAL.
    
    This surfaced in a gtkmm program. The Gesture is destroyed before the
    Widget. The Widget then gets dispose()d, which calls unparent()… boom.
    I didn’t find an MCVE yet but would hope this logic is correct anyway:
    
    The simplest fix is to make the loop in gtk_widget_reset_controllers()
    skip GList nodes with a NULL Controller pointer, like most other such
    loops, so we avoid passing the NULL to gtk_event_controller_reset().
    
    In other, live cases, _gtk_widget_run_controllers() loops over the GList
    and removes/frees nodes having NULL Controllers, so that should suffice.
    But this clearly was not getting a chance to happen in the failing case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=792624

 gtk/gtkwidget.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index e920161..35ad5b2 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -17483,6 +17483,10 @@ gtk_widget_reset_controllers (GtkWidget *widget)
   for (l = priv->event_controllers; l; l = l->next)
     {
       controller_data = l->data;
+
+      if (controller_data->controller == NULL)
+        continue;
+
       gtk_event_controller_reset (controller_data->controller);
     }
 }


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