[libadwaita/wip/exalm/new-glib: 1/8] swipe-tracker: Make swipeable a weak ref




commit 752217178f63d62c31578b8eebc982c0d816482e
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Tue Nov 2 23:28:18 2021 +0500

    swipe-tracker: Make swipeable a weak ref
    
    Fix a refcycle between the widget and the swipe tracker.

 src/adw-swipe-tracker.c | 46 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 5 deletions(-)
---
diff --git a/src/adw-swipe-tracker.c b/src/adw-swipe-tracker.c
index 418f49cd..7bc65a20 100644
--- a/src/adw-swipe-tracker.c
+++ b/src/adw-swipe-tracker.c
@@ -117,6 +117,36 @@ enum {
 
 static guint signals[SIGNAL_LAST_SIGNAL];
 
+static void
+swipeable_notify_cb (AdwSwipeTracker *self)
+{
+  self->motion_controller = NULL;
+  self->scroll_controller = NULL;
+  self->touch_gesture = NULL;
+  self->touch_gesture_capture = NULL;
+  self->swipeable = NULL;
+}
+
+static void
+set_swipeable (AdwSwipeTracker *self,
+               AdwSwipeable    *swipeable)
+{
+  if (self->swipeable == swipeable)
+    return;
+
+  if (self->swipeable)
+    g_object_weak_unref (G_OBJECT (self->swipeable),
+                         (GWeakNotify) swipeable_notify_cb,
+                         self);
+
+  self->swipeable = swipeable;
+
+  if (self->swipeable)
+    g_object_weak_ref (G_OBJECT (self->swipeable),
+                       (GWeakNotify) swipeable_notify_cb,
+                       self);
+}
+
 static void
 reset (AdwSwipeTracker *self)
 {
@@ -860,20 +890,26 @@ adw_swipe_tracker_dispose (GObject *object)
   if (self->touch_gesture) {
     gtk_widget_remove_controller (GTK_WIDGET (self->swipeable),
                                   GTK_EVENT_CONTROLLER (self->touch_gesture));
-    g_clear_object (&self->touch_gesture);
+    self->touch_gesture = NULL;
+  }
+
+  if (self->touch_gesture_capture) {
+    gtk_widget_remove_controller (GTK_WIDGET (self->swipeable),
+                                  GTK_EVENT_CONTROLLER (self->touch_gesture_capture));
+    self->touch_gesture_capture = NULL;
   }
 
   if (self->motion_controller) {
     gtk_widget_remove_controller (GTK_WIDGET (self->swipeable), self->motion_controller);
-    g_clear_object (&self->motion_controller);
+    self->motion_controller = NULL;
   }
 
   if (self->scroll_controller) {
     gtk_widget_remove_controller (GTK_WIDGET (self->swipeable), self->scroll_controller);
-    g_clear_object (&self->scroll_controller);
+    self->scroll_controller = NULL;
   }
 
-  g_clear_object (&self->swipeable);
+  set_swipeable (self, NULL);
 
   G_OBJECT_CLASS (adw_swipe_tracker_parent_class)->dispose (object);
 }
@@ -926,7 +962,7 @@ adw_swipe_tracker_set_property (GObject      *object,
 
   switch (prop_id) {
   case PROP_SWIPEABLE:
-    self->swipeable = ADW_SWIPEABLE (g_object_ref (g_value_get_object (value)));
+    set_swipeable (self, g_value_get_object (value));
     break;
 
   case PROP_ENABLED:


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