From 7808862454aa50afde85462c1b55a256096bfdef Mon Sep 17 00:00:00 2001
From: Rafostar <rafostar.github@gmail.com>
Date: Thu, 12 Nov 2020 18:16:23 +0100
Subject: [PATCH] gtk4: do not depend on "destroy" signal for cleanup

In GTK4 the "destroy" signal will not be emitted
as long as someone is holding a ref on an object.
We cannot use it to do the unref anymore.

This commit removes the floating ref and "destroy"
signal connection used to do the unref.
---
 ext/gtk/gstgtkbasesink.c | 27 ++++++---------------------
 ext/gtk/gstgtkbasesink.h |  1 -
 2 files changed, 6 insertions(+), 22 deletions(-)

diff --git a/ext/gtk/gstgtkbasesink.c b/ext/gtk/gstgtkbasesink.c
index 1f5319089..ea11bec40 100644
--- a/ext/gtk/gstgtkbasesink.c
+++ b/ext/gtk/gstgtkbasesink.c
@@ -153,21 +153,12 @@ gst_gtk_base_sink_finalize (GObject * object)
   GST_OBJECT_LOCK (gtk_sink);
   if (gtk_sink->window && gtk_sink->window_destroy_id)
     g_signal_handler_disconnect (gtk_sink->window, gtk_sink->window_destroy_id);
-  if (gtk_sink->widget && gtk_sink->widget_destroy_id)
-    g_signal_handler_disconnect (gtk_sink->widget, gtk_sink->widget_destroy_id);
 
-  g_clear_object (&gtk_sink->widget);
+  gtk_sink->widget = NULL;
   GST_OBJECT_UNLOCK (gtk_sink);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-widget_destroy_cb (GtkWidget * widget, GstGtkBaseSink * gtk_sink)
-{
-  GST_OBJECT_LOCK (gtk_sink);
-  g_clear_object (&gtk_sink->widget);
-  GST_OBJECT_UNLOCK (gtk_sink);
+  GST_DEBUG ("finalized base sink");
 }
 
 static void
@@ -211,12 +202,6 @@ gst_gtk_base_sink_get_widget (GstGtkBaseSink * gtk_sink)
       "ignore-alpha", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 #endif
 
-  /* Take the floating ref, other wise the destruction of the container will
-   * make this widget disappear possibly before we are done. */
-  gst_object_ref_sink (gtk_sink->widget);
-  gtk_sink->widget_destroy_id = g_signal_connect (gtk_sink->widget, "destroy",
-      G_CALLBACK (widget_destroy_cb), gtk_sink);
-
   /* back pointer */
   gtk_gst_base_widget_set_element (GTK_GST_BASE_WIDGET (gtk_sink->widget),
       GST_ELEMENT (gtk_sink));
@@ -236,7 +221,7 @@ gst_gtk_base_sink_get_property (GObject * object, guint prop_id,
       GObject *widget = NULL;
 
       GST_OBJECT_LOCK (gtk_sink);
-      if (gtk_sink->widget != NULL)
+      if (GTK_IS_WIDGET (gtk_sink->widget))
         widget = G_OBJECT (gtk_sink->widget);
       GST_OBJECT_UNLOCK (gtk_sink);
 
@@ -457,7 +442,7 @@ gst_gtk_base_sink_change_state (GstElement * element, GstStateChange transition)
     }
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       GST_OBJECT_LOCK (gtk_sink);
-      if (gtk_sink->widget)
+      if (GTK_IS_WIDGET (gtk_sink->widget))
         gtk_gst_base_widget_set_buffer (gtk_sink->widget, NULL);
       GST_OBJECT_UNLOCK (gtk_sink);
       break;
@@ -503,7 +488,7 @@ gst_gtk_base_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
 
   GST_OBJECT_LOCK (gtk_sink);
 
-  if (gtk_sink->widget == NULL) {
+  if (!GTK_IS_WIDGET (gtk_sink->widget)) {
     GST_OBJECT_UNLOCK (gtk_sink);
     GST_ELEMENT_ERROR (gtk_sink, RESOURCE, NOT_FOUND,
         ("%s", "Output widget was destroyed"), (NULL));
@@ -530,7 +515,7 @@ gst_gtk_base_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf)
 
   GST_OBJECT_LOCK (vsink);
 
-  if (gtk_sink->widget == NULL) {
+  if (!GTK_IS_WIDGET (gtk_sink->widget)) {
     GST_OBJECT_UNLOCK (gtk_sink);
     GST_ELEMENT_ERROR (gtk_sink, RESOURCE, NOT_FOUND,
         ("%s", "Output widget was destroyed"), (NULL));
diff --git a/ext/gtk/gstgtkbasesink.h b/ext/gtk/gstgtkbasesink.h
index 650175036..f2668fabc 100644
--- a/ext/gtk/gstgtkbasesink.h
+++ b/ext/gtk/gstgtkbasesink.h
@@ -69,7 +69,6 @@ struct _GstGtkBaseSink
   GBinding             *bind_ignore_alpha;
 
   GtkWidget            *window;
-  gulong               widget_destroy_id;
   gulong               window_destroy_id;
 };
 
-- 
2.26.2

