[gtkmm] Gtk::Application: Try to make this a replacement for Gtk::Main.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::Application: Try to make this a replacement for Gtk::Main.
- Date: Thu, 20 Jan 2011 08:14:11 +0000 (UTC)
commit ecaf1dd3614a10a95b000a1a18a3cac7bf682e74
Author: Murray Cumming <murrayc murrayc com>
Date: Thu Jan 20 09:14:00 2011 +0100
Gtk::Application: Try to make this a replacement for Gtk::Main.
* gtk/src/application.[hg|ccg]: Add a copy of init_gtkmm_internals() from
Gtk::Main's main.cc and call it from the constructor, so that
Gtk::Application can be a replacement for Gtk::Main.
Add a constructor that takes argc and argv, so we can completely
initialize GTK+ and gtkmm, because doing it in run() will be too late for
some code: See bug #639925.
Add a run() that does not take argc, argv, for when you have supplied them
to the constructor instead.
Add a run() that takes a window, like Gtk::Main::run(), so it can return
when the window closes. However, see bug #639931 about it really responding to
destruction, not closing.
We show the window in an activate signal handler, because GTK+ complains if
we don't have such a handler. See bug #640042.
ChangeLog | 18 ++++++++
gtk/src/application.ccg | 108 +++++++++++++++++++++++++++++++++++++++++++++++
gtk/src/application.hg | 88 +++++++++++++++++++++++++++++++++++++-
3 files changed, 212 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index dcae841..58dd407 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-01-20 Murray Cumming <murrayc murrayc com>
+
+ Gtk::Application: Try to make this a replacement for Gtk::Main.
+
+ * gtk/src/application.[hg|ccg]: Add a copy of init_gtkmm_internals() from
+ Gtk::Main's main.cc and call it from the constructor, so that
+ Gtk::Application can be a replacement for Gtk::Main.
+ Add a constructor that takes argc and argv, so we can completely
+ initialize GTK+ and gtkmm, because doing it in run() will be too late for
+ some code: See bug #639925.
+ Add a run() that does not take argc, argv, for when you have supplied them
+ to the constructor instead.
+ Add a run() that takes a window, like Gtk::Main::run(), so it can return
+ when the window closes. However, see bug #639931 about it really responding to
+ destruction, not closing.
+ We show the window in an activate signal handler, because GTK+ complains if
+ we don't have such a handler. See bug #640042.
+
2011-01-18 Murray Cumming <murrayc murrayc com>
Range: Added get/set_round_digits() and property.
diff --git a/gtk/src/application.ccg b/gtk/src/application.ccg
index 00066c3..3ef51ca 100644
--- a/gtk/src/application.ccg
+++ b/gtk/src/application.ccg
@@ -20,9 +20,117 @@
#include <gtk/gtk.h>
#include <gtkmm/window.h>
+#include <glibmm/init.h>
+#include <giomm/init.h>
+#include <pangomm/wrap_init.h>
+#ifdef GTKMM_ATKMM_ENABLED
+#include <atkmm/wrap_init.h>
+#endif //GTKMM_ATKMM_ENABLED
+#include <gdkmm/wrap_init.h>
+#include <gtkmm/wrap_init.h>
namespace Gtk
{
+static void init_gtkmm_internals()
+{
+ static bool init_done = false;
+
+ if(!init_done)
+ {
+ Glib::init();
+ Gio::init();
+
+ // Populate the map of GTypes to C++ wrap_new() functions.
+ Pango::wrap_init();
+#ifdef GTKMM_ATKMM_ENABLED
+ Atk::wrap_init();
+#endif //GTKMM_ATKMM_ENABLED
+ Gdk::wrap_init();
+ Gtk::wrap_init();
+
+ init_done = true;
+ }
+}
+
+const Glib::Class& Application::custom_class_init()
+{
+ Glib::init();
+ return application_class_.init();
+}
+
+Application::Application(const Glib::ustring& application_id, Gio::ApplicationFlags flags)
+:
+ // Mark this class as non-derived to allow C++ vfuncs to be skipped.
+ Glib::ObjectBase(0),
+ Gio::Application(Glib::ConstructParams(custom_class_init(), "application_id", application_id.c_str(), "flags", GApplicationFlags(flags), static_cast<char*>(0))),
+ m_main_window(0),
+ m_argc(0),
+ m_argv(0)
+{
+}
+
+Application::Application(int argc, char** argv, const Glib::ustring& application_id, Gio::ApplicationFlags flags)
+:
+ // Mark this class as non-derived to allow C++ vfuncs to be skipped.
+ Glib::ObjectBase(0),
+ Gio::Application(Glib::ConstructParams(custom_class_init(), "application_id", application_id.c_str(), "flags", GApplicationFlags(flags), static_cast<char*>(0))),
+ m_main_window(0),
+ m_argc(argc),
+ m_argv(argv)
+{
+ gtk_init(&argc, &argv);
+ init_gtkmm_internals();
+}
+
+void Application::on_activate_showwindow()
+{
+ if(m_main_window)
+ m_main_window->show();
+}
+
+int Application::run(int argc, char** argv)
+{
+ return Gio::Application::run(argc, argv);
+}
+
+
+int Application::run(Gtk::Window& window, int argc, char** argv)
+{
+ add_window(window);
+
+ //Show the window when the application starts.
+ //We could just call show() now,
+ //but GApplication currently warns if we don't connect to the activate signal,
+ //which seems very C-centric. See https://bugzilla.gnome.org/show_bug.cgi?id=640042
+ m_main_window = &window;
+ signal_activate().connect(
+ sigc::mem_fun(*this, &Application::on_activate_showwindow));
+
+ const int result = Gio::Application::run(argc, argv);
+ init_gtkmm_internals();
+ return result;
+}
+
+int Application::run(Gtk::Window& window)
+{
+ g_assert(m_argc);
+ g_assert(m_argv);
+
+ add_window(window);
+
+ //Show the window when the application starts.
+ //We could just call show() now,
+ //but GApplication currently warns if we don't connect to the activate signal,
+ //which seems very C-centric. See https://bugzilla.gnome.org/show_bug.cgi?id=640042
+ m_main_window = &window;
+ signal_activate().connect(
+ sigc::mem_fun(*this, &Application::on_activate_showwindow));
+
+ const int result = Gio::Application::run(m_argc, m_argv);
+ init_gtkmm_internals();
+ return result;
+}
+
} // namespace Gtk
diff --git a/gtk/src/application.hg b/gtk/src/application.hg
index b63679b..d662e01 100644
--- a/gtk/src/application.hg
+++ b/gtk/src/application.hg
@@ -37,12 +37,38 @@ protected:
_CLASS_GOBJECT(Application, GtkApplication, GTK_APPLICATION, Gio::Application, GApplication)
protected:
-#m4 _CONVERSION(`Gio::ApplicationFlags',`GApplicationFlags',`(GApplicationFlags)($3)')
- _WRAP_CTOR(Application(const Glib::ustring& application_id, Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE), gtk_application_new)
+ /** Creates a new Application instance.
+ * This constructor calls g_type_init() for you.
+ * You should call run() with your main() function's argc and argv parameters
+ * to initialize gtkmm too.
+ *
+ * @param application_id A valid application id
+ * @param flags The application flags
+ */
+ explicit Application(const Glib::ustring& application_id, Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE);
+ _IGNORE(gtk_application_new)
+
+ //This constructor does not correspond to anything in the C API.
+ //We added it so we can choose to always initialize gtkmm as early as possible.
+ //See https://bugzilla.gnome.org/show_bug.cgi?id=639925
+ /** Creates a new Application instance.
+ * This constructor initializes gtkmm for you, so you should call run()
+ * without specifying the the argc and argv parameters again.
+ *
+ * @param argc The parameter received by your main() function.
+ * @param argv The parameter received by your main() function.
+ * @param application_id A valid application id
+ * @param flags The application flags
+ */
+ explicit Application(int argc, char** argv, const Glib::ustring& application_id, Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE);
+
public:
+#m4 _CONVERSION(`Gio::ApplicationFlags',`GApplicationFlags',`(GApplicationFlags)($3)')
_WRAP_CREATE(const Glib::ustring& application_id, Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE)
+
+ _WRAP_CREATE(int argc, char** argv, const Glib::ustring& application_id, Gio::ApplicationFlags flags = Gio::APPLICATION_FLAGS_NONE)
#m4 _CONVERSION(`GList*',`Glib::ListHandle<Window*>',`$2($3, Glib::OWNERSHIP_NONE)')
_WRAP_METHOD(Glib::ListHandle<Window*> get_windows(), gtk_application_get_windows)
@@ -52,6 +78,64 @@ public:
_WRAP_METHOD(void add_window(Window& window), gtk_application_add_window)
_WRAP_METHOD(void remove_window(Window& window), gtk_application_remove_window)
+
+ /** Starts the application.
+ *
+ * The default implementation of this virtual function will simply run
+ * a main loop.
+ *
+ * It is an error to call this function if @a application is a proxy for
+ * a remote application.
+ *
+ * @newin{2,28}
+ */
+ int run(int argc, char** argv);
+
+ /** Starts the application.
+ *
+ * The default implementation of this virtual function will simply run
+ * a main loop.
+ *
+ * It is an error to call this function if @a application is a proxy for
+ * a remote application.
+ *
+ * @param window The window to show. This method will return when the window is hidden.
+ *
+ * @newin{2,28}
+ */
+ int run(Gtk::Window& window, int argc, char** argv);
+
+ /** Starts the application.
+ *
+ * The default implementation of this virtual function will simply run
+ * a main loop.
+ *
+ * It is an error to call this function if @a application is a proxy for
+ * a remote application.
+ *
+ * @param window The window to show. This method will return when the window is hidden.
+ *
+ * @newin{2,28}
+ */
+ int run(Gtk::Window& window);
+
+private:
+ /** This is just a way to call Glib::init() (which calls g_type_init()) before
+ * calling application_class_.init(), so that
+ * gtk_application_get_type() will always succeed.
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=639925
+ */
+ const Glib::Class& custom_class_init();
+
+ void on_activate_showwindow();
+
+ ///We show the window in the activate signal handler.
+ Gtk::Window* m_main_window;
+
+ //We need these to call g_application_run(),
+ //even if we have already called gtk_init().
+ int m_argc;
+ char** m_argv;
};
} // namespace Gtk
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]