[gtkmm] Gtk::Application, Window: Always remove a window from its app when hidden
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::Application, Window: Always remove a window from its app when hidden
- Date: Thu, 14 Nov 2019 16:04:05 +0000 (UTC)
commit 01ff5c7a8ea28082c28794f35927be44c3b79d58
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Thu Nov 14 17:02:31 2019 +0100
Gtk::Application, Window: Always remove a window from its app when hidden
* gtk/src/application.[ccg|hg]: add_window() is not hand-coded.
* gtk/src/widget.ccg: Widget_Class::hide_callback(): Remove a hidden
window from its application.
* gtk/src/window.hg: set_application(): Update the description.
When Widget_Class::hide_callback() removes a hidden window from its
application, the removal is performed regardless of how the window
has been added to the application: by Application::add_window(),
by Window::set_application() or by some other means.
Fixes #56
gtk/src/application.ccg | 40 +++-------------------------------------
gtk/src/application.hg | 10 ++++++----
gtk/src/widget.ccg | 18 +++++++++++++++++-
gtk/src/window.hg | 17 +++++++++++++++++
4 files changed, 43 insertions(+), 42 deletions(-)
---
diff --git a/gtk/src/application.ccg b/gtk/src/application.ccg
index 8aa5ad6a..b7602ece 100644
--- a/gtk/src/application.ccg
+++ b/gtk/src/application.ccg
@@ -110,29 +110,6 @@ Glib::RefPtr<Application> Application::create(const Glib::ustring& application_i
return Glib::RefPtr<Application>( new Application(application_id, flags) );
}
-void Application::on_window_hide(Window* window)
-{
- //Tell GtkApplication to forget the window.
- //This can cause run() to return, if it is the last window.
- //Otherwise, GtkApplication waits for the window to be _destroyed_,
- //which is just not something that it should care about:
- //See https://bugzilla.gnome.org/show_bug.cgi?id=639931
- if(window && window->get_application()) //We check that it's still in an application anyway.
- remove_window(*window);
-}
-
-void Application::add_window(Window& window)
-{
- //Respond to window hiding, not destruction:
- //See https://bugzilla.gnome.org/show_bug.cgi?id=639931
- window.signal_hide().connect(
- sigc::bind(
- sigc::mem_fun(*this, &Application::on_window_hide),
- &window));
-
- gtk_application_add_window(gobj(), (window).gobj());
-}
-
int Application::run(int argc, char** argv)
{
return Gio::Application::run(argc, argv);
@@ -148,29 +125,18 @@ int Application::run(Window& window, int argc, char** argv)
sigc::mem_fun(*this, &Application::on_activate_add_and_show_main_window),
&window));
- const auto result = Gio::Application::run(argc, argv);
- return result;
+ return Gio::Application::run(argc, argv);
}
int Application::run(Window& window)
{
- //We cannot add and show the window until the GApplication::activate signal
- //has been emitted, or we will crash because the application has not been
- //registered. (At least if window is an ApplicationWindow.)
- signal_activate().connect(
- sigc::bind(
- sigc::mem_fun(*this, &Application::on_activate_add_and_show_main_window),
- &window));
-
- const auto result = Gio::Application::run(0, nullptr);
- return result;
+ return run(window, 0, nullptr);
}
int Application::run()
{
- const auto result = Gio::Application::run(0, nullptr);
- return result;
+ return Gio::Application::run(0, nullptr);
}
void Application::on_activate_add_and_show_main_window(Window* window)
diff --git a/gtk/src/application.hg b/gtk/src/application.hg
index 0d4fa10c..f46aef89 100644
--- a/gtk/src/application.hg
+++ b/gtk/src/application.hg
@@ -141,11 +141,14 @@ public:
#m4 _CONVERSION(`GList*',`std::vector<const Window*>',`Glib::ListHandler<const Window*>::list_to_vector($3,
Glib::OWNERSHIP_NONE)')
_WRAP_METHOD(std::vector<const Window*> get_windows() const, gtk_application_get_windows)
- //Concerning the note on quit(), see https://bugzilla.gnome.org/show_bug.cgi?id=731126
+ // Concerning the note on quit(), see https://bugzilla.gnome.org/show_bug.cgi?id=731126
+ // Concerning the return from run() on hidden windows, see
+ // https://bugzilla.gnome.org/show_bug.cgi?id=639931 and Gtk::Widget_Class::hide_callback().
/** Adds a window to the Gtk::Application.
*
* If all the windows managed by Gtk::Application are closed (hidden) or
- * removed from the application then the call to run() will return.
+ * removed from the application then the call to run() will return,
+ * unless Gio::Application::hold() has been called.
*
* This call is equivalent to calling Gtk::Window::set_application().
*
@@ -161,8 +164,7 @@ public:
*
* @param window A toplevel window to add to the application.
*/
- void add_window(Window& window);
- _IGNORE(gtk_application_add_window)
+ _WRAP_METHOD(void add_window(Window& window), gtk_application_add_window)
_WRAP_METHOD(void remove_window(Window& window), gtk_application_remove_window)
diff --git a/gtk/src/widget.ccg b/gtk/src/widget.ccg
index f20d12eb..17eb1758 100644
--- a/gtk/src/widget.ccg
+++ b/gtk/src/widget.ccg
@@ -113,9 +113,25 @@ namespace Gtk
{
// This default handler callback is custom implemented, so that we can refrain
-// from calling an on_hide() override, if the C++ wrapper is being deleted.
+// from calling an on_hide() override, if the C++ wrapper is being deleted,
+// and so that we can remove a hidden window from its application.
void Widget_Class::hide_callback(GtkWidget* self)
{
+ if (GTK_IS_WINDOW(self))
+ {
+ GtkWindow* window = GTK_WINDOW(self);
+ GtkApplication* appl = gtk_window_get_application(window);
+ if (appl)
+ {
+ // Tell GtkApplication to forget the window.
+ // This can cause Application::run() to return, if it is the last window.
+ // Otherwise, GtkApplication waits for the window to be _destroyed_,
+ // which is just not something that it should care about:
+ // See https://bugzilla.gnome.org/show_bug.cgi?id=639931
+ gtk_application_remove_window(appl, window);
+ }
+ }
+
const auto obj_base = static_cast<Glib::ObjectBase*>(
Glib::ObjectBase::_get_current_wrapper((GObject*)self));
diff --git a/gtk/src/window.hg b/gtk/src/window.hg
index 6c18d887..d946fa78 100644
--- a/gtk/src/window.hg
+++ b/gtk/src/window.hg
@@ -276,6 +276,23 @@ dnl
_WRAP_METHOD(Glib::RefPtr<Application> get_application(), gtk_window_get_application, refreturn)
_WRAP_METHOD(Glib::RefPtr<const Application> get_application() const, gtk_window_get_application,
refreturn)
+ // Concerning the removal of a hidden window from the application, see
+ // https://bugzilla.gnome.org/show_bug.cgi?id=639931 and Gtk::Widget_Class::hide_callback().
+ /** Sets the Gtk::Application associated with the window.
+ *
+ * The application will be kept alive for at least as long as it has any windows
+ * associated with it. (See Gio::Application::hold() for a way to keep it alive
+ * without windows.)
+ *
+ * Normally, the connection between the application and the window will remain
+ * until the window is closed (hidden), but you can explicitly remove it by
+ * calling unset_application().
+ *
+ * This is equivalent to calling Gtk::Application::remove_window() and/or
+ * Gtk::Application::add_window() on the old/new applications as relevant.
+ *
+ * @param application A Gtk::Application.
+ */
_WRAP_METHOD(void set_application(const Glib::RefPtr<Application>& application),
gtk_window_set_application)
/** Unsets the Application associated with the window.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]