[gtkmm] Allow managed Gtk::Window's
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Allow managed Gtk::Window's
- Date: Tue, 22 Mar 2022 13:46:23 +0000 (UTC)
commit 39e1941c6b06fab5a1e7ccc317ddfeea1aae78e5
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Tue Mar 22 14:40:45 2022 +0100
Allow managed Gtk::Window's
A managed Window is deleted when its underlying C instance is destroyed.
* gtk/gtkmm/object.h: Add more documentation of Gtk::manage().
* gtk/src/window.[ccg|hg]: Add set_destroy_with_parent() and destroy().
set_manage() makes the window managed.
Fixes #24, see also #114
gtk/gtkmm/object.h | 10 ++++++++--
gtk/src/window.ccg | 12 +++++++++++-
gtk/src/window.hg | 40 +++++++++++++++++++++++++++++-----------
3 files changed, 48 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkmm/object.h b/gtk/gtkmm/object.h
index e36007f3..66d772b0 100644
--- a/gtk/gtkmm/object.h
+++ b/gtk/gtkmm/object.h
@@ -35,6 +35,11 @@ class GTKMM_API Object;
* vbox.append(*button); //vbox will delete button when vbox is deleted.
* @endcode
*
+ * Beginning with gtkmm 4.8, a Gtk::Window can be managed, although it has no parent.
+ * A managed Gtk::Window is deleted when its underlying C instance is destroyed.
+ * The C instance will be destroyed when the window manager's close button
+ * is clicked, unless Gtk::Window::set_hide_on_close() has been called.
+ *
* @param obj A Gtk::Object, such as a gtkmm widget.
* @result The Gtk::Object passed as the @a obj parameter.
*/
@@ -47,7 +52,7 @@ T* manage(T* obj)
/** Create a Gtk::Object such as a widget and Gtk::manage() it in a single step.
* This matches standard functions like std::make_unique<T>(args) and avoids you
- * manually invoking the new operator, which is discouraged in modern C++ style.
+ * manually invoking the @c new operator, which is discouraged in modern C++ style.
*
* For instance,
* @code
@@ -55,6 +60,7 @@ T* manage(T* obj)
* vbox.append(*button); //vbox will delete button when vbox is deleted.
* @endcode
*
+ * @tparam T The type of object to create.
* @param args Arguments to pass to the constructor of the given template type.
* @result A new, managed object of that type, constructed with those arguments.
*/
@@ -115,7 +121,7 @@ public:
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
- /** Used by Gtk::manage(). You should not need to use this directly.
+ /** Used by Gtk::manage() and Gtk::make_managed(). You should not need to use this directly.
*/
void set_manage() override;
#endif //DOXYGEN_SHOULD_SKIP_THIS
diff --git a/gtk/src/window.ccg b/gtk/src/window.ccg
index 21300d9f..6037a52e 100644
--- a/gtk/src/window.ccg
+++ b/gtk/src/window.ccg
@@ -98,7 +98,9 @@ void Window::on_window_hide()
void Window::set_manage()
{
- g_warning("gtkmm: Attempt to call Gtk::manage() on a Gtk::Window, but a Gtk::Window has no parent
container to manage its lifetime.\n");
+ // This C++ wrapper is deleted by Gtk::Object::destroy_notify_() when the
+ // underlying C instance is destroyed.
+ referenced_ = false; // Managed
}
void Window::destroy_()
@@ -209,6 +211,14 @@ void Window_Class::dispose_vfunc_callback(GObject* self)
#endif
}
+void Window::destroy()
+{
+ // Don't crash if destroy() is called twice.
+ // gobj() can be nullptr after the first call to destroy().
+ if (gobj())
+ gtk_window_destroy(gobj());
+}
+
void Window::unset_focus()
{
gtk_window_set_focus(gobj(), nullptr /* See GTK+ docs */);
diff --git a/gtk/src/window.hg b/gtk/src/window.hg
index 194431e6..1dad7ff1 100644
--- a/gtk/src/window.hg
+++ b/gtk/src/window.hg
@@ -45,8 +45,6 @@ class GTKMM_API WindowGroup;
* This represents all widgets which are physical windows controlled
* by the window manager.
*
- * Gtk::manage() has no effect on Windows because they have no parent containers.
- *
* The window will be destroyed when the window manager's close button is clicked.
* Call set_hide_on_close() if you want it to be hidden instead.
*
@@ -62,9 +60,6 @@ class GTKMM_API Window : public Widget, public Native, public ShortcutManager, p
_IMPLEMENTS_INTERFACE(ShortcutManager)
_IMPLEMENTS_INTERFACE(Root)
_UNMANAGEABLE
- _IGNORE(gtk_window_destroy, gtk_window_set_destroy_with_parent)
-
- //TODO: Use gtk_window_set_destroy_with_parent() to allow use of Gtk::manage() with top-level windows,
using the transient-parent?
public:
// Disambiguate calls to get_display(). Use Root::get_display(), not Widget::get_display().
@@ -156,12 +151,31 @@ dnl
_WRAP_METHOD(Window* get_transient_for(), gtk_window_get_transient_for)
_WRAP_METHOD(const Window* get_transient_for() const, gtk_window_get_transient_for, constversion)
- //_WRAP_METHOD(void set_destroy_with_parent(bool setting = true), gtk_window_set_destroy_with_parent)
- // I don't that that this is ever a good thing for C++.murrayc.
-
- //TODO: Remove?
+ _WRAP_METHOD(void set_destroy_with_parent(bool setting = true),
+ gtk_window_set_destroy_with_parent, newin "4,8")
_WRAP_METHOD(bool get_destroy_with_parent() const, gtk_window_get_destroy_with_parent)
- // I don't that that this is ever a good thing for C++.murrayc.
+
+ /** Drop the internal reference GTK holds on toplevel windows.
+ *
+ * If this window is managed, this C++ wrapper will be deleted when the
+ * underlying C instance is destroyed.
+ *
+ * After a call to %destroy(), don't call any method that accesses the
+ * underlying C instance.
+ *
+ * If the C++ wrapper is deleted, the underlying C instance will be destroyed.
+ * If the C instance is destroyed and the C++ wrapper is managed, the wrapper
+ * will be deleted. The difference is in the order in which actions are taken.
+ * That may or may not be important. If the C instance is destroyed before
+ * the wrapper is deleted, C++ signal handlers can be called during the destruction.
+ * For instance, if you connect to Gtk::Widget::signal_unrealize() or override
+ * Gtk::Widget::on_unrealize(), those signal handlers can be called only if
+ * the wrapper still exists when the signal is emitted.
+ *
+ * @newin{4,8}
+ */
+ void destroy();
+ _IGNORE(gtk_window_destroy)
_WRAP_METHOD(void set_hide_on_close(bool setting = true), gtk_window_set_hide_on_close)
_WRAP_METHOD(bool get_hide_on_close() const, gtk_window_get_hide_on_close)
@@ -277,7 +291,11 @@ dnl
//TODO: _WRAP_METHOD(void show_uri(const Glib::ustring& uri, guint32 timestamp), gtk_show_uri)
// gtk_show_uri_full[_finish]()
- ///Overriden to warn that it doesn't make sense to use Gtk::manage() on this class because it has no
parent container.
+ /** Used by Gtk::manage() and Gtk::make_managed(). You should not need to use this directly.
+ * Overridden because a %Gtk::Window is not managed by a container.
+ * Beginning with gtkmm 4.8, a %Gtk::Window can be managed. If managed, it's
+ * deleted when its underlying C instance is destroyed.
+ */
void set_manage() override;
protected:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]