[gtkmm: 1/2] Fix object ownership in the wrapper of the render signal.




commit 790f1eca8fc4a689637a89b9353176f4d0671e4b
Author: Baldvin Kovacs <baldvin kovacs gmail com>
Date:   Wed Feb 16 11:02:16 2022 +0100

    Fix object ownership in the wrapper of the render signal.
    
    This change ensures that the wrapper implementation of the render
    signal emission does not take ownership of the underlying cairo_region_t
    C instance. It is necessary, because the C implementation expects to
    keep ownership, and destroys the underlying C instance after the signal
    was emitted.
    
    The wrapped signal is emitted from gdk_surface_process_update_internal.
    
    The relevant lines:
    
    expose_region = cairo_region_copy (surface->active_update_area);
    
    // here expose_region has a reference count of 1
    
    g_signal_emit (surface, signals[RENDER], 0, expose_region, &handled);
    
    // ...and here it needs to remain one, but with the current implementation
    // we get a double destroy below:
    
    cairo_region_destroy (expose_region);

 gdk/gdkmm/cairoutils.h | 15 +++++++++------
 gdk/src/surface.hg     |  2 +-
 2 files changed, 10 insertions(+), 7 deletions(-)
---
diff --git a/gdk/gdkmm/cairoutils.h b/gdk/gdkmm/cairoutils.h
index 15a0d55b..db5d4748 100644
--- a/gdk/gdkmm/cairoutils.h
+++ b/gdk/gdkmm/cairoutils.h
@@ -36,8 +36,9 @@ namespace Cairo
 /** Creates a Cairo::RefPtr with a C++ wrapper for the C instance.
  *
  * @param cobject The C instance.
- * @param has_reference Whether we already have a reference. Otherwise, the
- *        function will take an extra reference.
+ * @param has_reference If true, then the wrapper object takes ownership of
+ *        the C instance without increasing its reference count. The reference
+ *        count is decreased in the destructor in all cases.
  * @returns A C++ instance that wraps this C instance. If @a cobject is a nullptr,
  *          returns an empty Cairo::RefPtr.
  *
@@ -49,8 +50,9 @@ GDKMM_API
 /** Creates a Cairo::RefPtr with a C++ wrapper for the C instance.
  *
  * @param cobject The C instance.
- * @param has_reference Whether we already have a reference. Otherwise, the
- *        function will take an extra reference.
+ * @param has_reference If true, then the wrapper object takes ownership of
+ *        the C instance without increasing its reference count. The reference
+ *        count is decreased in the destructor in all cases.
  * @returns A C++ instance that wraps this C instance. If @a cobject is a nullptr,
  *          returns an empty Cairo::RefPtr.
  *
@@ -63,8 +65,9 @@ GDKMM_API
  *
  * @tparam T Cairo::Surface or a subclass of Cairo::Surface.
  * @param cobject The C instance.
- * @param has_reference Whether we already have a reference. Otherwise, the
- *        function will take an extra reference.
+ * @param has_reference If true, then the wrapper object takes ownership of
+ *        the C instance without increasing its reference count. The reference
+ *        count is decreased in the destructor in all cases.
  * @returns A C++ instance that wraps this C instance. If @a cobject is a nullptr,
  *          returns an empty Cairo::RefPtr.
  *
diff --git a/gdk/src/surface.hg b/gdk/src/surface.hg
index 53b6e1db..205628ed 100644
--- a/gdk/src/surface.hg
+++ b/gdk/src/surface.hg
@@ -169,7 +169,7 @@ public:
 
   // no_default_handler because the wrapped C signals have no default handlers.
   _WRAP_SIGNAL(void layout(int width, int height), "layout", no_default_handler)
-#m4 _CONVERSION(`CairoRegion*',`const ::Cairo::RefPtr<const ::Cairo::Region>&',`Gdk::Cairo::wrap($3)')
+#m4 _CONVERSION(`CairoRegion*',`const ::Cairo::RefPtr<const ::Cairo::Region>&',`Gdk::Cairo::wrap($3, false)')
   _WRAP_SIGNAL(bool render(const ::Cairo::RefPtr<const ::Cairo::Region>& expose_region),
     "render", no_default_handler)
 #m4 _CONVERSION(`GdkEvent*',`const Glib::RefPtr<const Event>&',`Glib::wrap($3, true)')


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