[gtkmm] Gtk::Object::_release_c_instance(): Don't release if in a container
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::Object::_release_c_instance(): Don't release if in a container
- Date: Thu, 1 Mar 2018 08:41:29 +0000 (UTC)
commit f75eb806f8fbdfe5455f54825c4b870787fef438
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Thu Mar 1 09:39:31 2018 +0100
Gtk::Object::_release_c_instance(): Don't release if in a container
Don't release the C instance, if it's a widget in a container widget.
Just steal the GQuark that points from the C instance to the C++ wrapper,
and accept that a new wrapper is later created, if necessary.
Nowadays it's difficult to know which container the widget has been added to.
It's not necessarily the one returned by gtk_widget_get_parent().
Bug 773642 comments 20-22. See also gtk+ bug 786048 comment 5.
gtk/gtkmm/object.cc | 27 +++++++++++++++++++++------
gtk/gtkmm/object.h | 2 +-
2 files changed, 22 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkmm/object.cc b/gtk/gtkmm/object.cc
index 27bf8a7..30ea269 100644
--- a/gtk/gtkmm/object.cc
+++ b/gtk/gtkmm/object.cc
@@ -92,6 +92,7 @@ void Object::_release_c_instance()
if (object)
{
g_assert(G_IS_OBJECT(object));
+ bool prevent_creation_of_another_wrapper = true;
if(referenced_)
{
@@ -120,7 +121,17 @@ void Object::_release_c_instance()
#endif
g_assert(G_IS_OBJECT(object));
- g_object_run_dispose(object); //Container widgets can respond to this.
+ if (GTK_IS_WIDGET(object) && gtk_widget_get_parent(GTK_WIDGET(object)))
+ // It's a widget which has been added to a container widget.
+ // It can't be safely destroyed, unless you know which container it
+ // was added to and remove it from there. That may or may not be its
+ // immediate parent, returned by gtk_widget_get_parent().
+ // Accept that another wrapper is possibly created if a signal
+ // is emitted or a vfunc is called.
+ // The widget will be destroyed, when the container widget is destroyed.
+ prevent_creation_of_another_wrapper = false;
+ else
+ g_object_run_dispose(object); //Container widgets can respond to this.
}
}
else
@@ -132,12 +143,15 @@ void Object::_release_c_instance()
#endif
g_assert(G_IS_OBJECT(object));
- g_object_run_dispose(object);
+ if (GTK_IS_WIDGET(object) && gtk_widget_get_parent(GTK_WIDGET(object)))
+ prevent_creation_of_another_wrapper = false;
+ else
+ g_object_run_dispose(object);
}
//If the GObject still exists, disconnect the C++ wrapper from it.
//The C++ wrapper is being deleted right now.
- disconnect_cpp_wrapper();
+ disconnect_cpp_wrapper(prevent_creation_of_another_wrapper);
//Glib::Object::~Object() will not g_object_unref() it too. because gobject_ is now 0.
}
@@ -166,7 +180,7 @@ Object::~Object() noexcept
_release_c_instance();
}
-void Object::disconnect_cpp_wrapper()
+void Object::disconnect_cpp_wrapper(bool prevent_creation_of_another_wrapper)
{
//GTKMM_LIFECYCLE:
@@ -181,8 +195,9 @@ void Object::disconnect_cpp_wrapper()
//Prevent gtk vfuncs and default signal handlers from calling our instance methods:
g_object_steal_qdata((GObject*)gobj(), Glib::quark_); //It will no longer be possible to get the C++
instance from the C instance.
- //Allow us to prevent generation of a new C++ wrapper during destruction:
- g_object_set_qdata((GObject*)gobj(), Glib::quark_cpp_wrapper_deleted_, (gpointer)true);
+ if (prevent_creation_of_another_wrapper)
+ //Allow us to prevent generation of a new C++ wrapper during destruction:
+ g_object_set_qdata((GObject*)gobj(), Glib::quark_cpp_wrapper_deleted_, (gpointer)true);
//Prevent C++ instance from using GTK+ object:
gobject_ = nullptr;
diff --git a/gtk/gtkmm/object.h b/gtk/gtkmm/object.h
index e4f4ba3..a818d40 100644
--- a/gtk/gtkmm/object.h
+++ b/gtk/gtkmm/object.h
@@ -117,7 +117,7 @@ protected:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
void _init_unmanage();
void destroy_notify_() override;
- void disconnect_cpp_wrapper();
+ void disconnect_cpp_wrapper(bool prevent_creation_of_another_wrapper = true);
void _release_c_instance();
// set if flags used by derived classes.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]