[gtk+/wip/gapplication] Add GtkApplication



commit ff9fa36ddda7d26a56daf116aae62f31d4682240
Author: Colin Walters <walters verbum org>
Date:   Wed Mar 31 13:59:04 2010 -0400

    Add GtkApplication
    
    This is a work in progress to stub out an application class.  The
    primary goal is to provide a mechanism for applications to export
    GtkActions, and there is a standard "Quit".
    
    This is based on GApplication.
    
    Future work:
     * Manage toplevel GtkWindows
     * Add a way to say "This is my application menubar", which gets
       put into all toplevel windows on non-OS-X, and into the top
       on OS X.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=127958

 gtk/Makefile.am         |    2 +
 gtk/gtk.h               |    1 +
 gtk/gtkapplication.c    |  304 +++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkapplication.h    |   94 +++++++++++++++
 tests/Makefile.am       |    4 +-
 tests/testapplication.c |   81 +++++++++++++
 6 files changed, 485 insertions(+), 1 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ce1e2af..e10be5f 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -170,6 +170,7 @@ gtk_public_h_sources =          \
 	gtkactivatable.h	\
 	gtkadjustment.h		\
 	gtkalignment.h		\
+	gtkapplication.h    \
 	gtkarrow.h		\
 	gtkaspectframe.h	\
 	gtkassistant.h		\
@@ -428,6 +429,7 @@ gtk_base_c_sources =            \
 	gtkactivatable.c	\
 	gtkadjustment.c		\
 	gtkalignment.c		\
+	gtkapplication.c \
 	gtkarrow.c		\
 	gtkaspectframe.c	\
 	gtkassistant.c		\
diff --git a/gtk/gtk.h b/gtk/gtk.h
index cbac475..120555b 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -40,6 +40,7 @@
 #include <gtk/gtkactivatable.h>
 #include <gtk/gtkadjustment.h>
 #include <gtk/gtkalignment.h>
+#include <gtk/gtkapplication.h>
 #include <gtk/gtkarrow.h>
 #include <gtk/gtkaspectframe.h>
 #include <gtk/gtkassistant.h>
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c
new file mode 100644
index 0000000..36cc76d
--- /dev/null
+++ b/gtk/gtkapplication.c
@@ -0,0 +1,304 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters verbum org>
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+#include "gtkapplication.h"
+#include "gtkmain.h"
+#include "gtkintl.h"
+#include "gtkprivate.h"
+
+enum
+{
+  PROP_0,
+  PROP_WINDOW
+};
+
+struct _GtkApplicationPrivate
+{
+  char *appid;
+  GtkActionGroup *main_actions;
+  
+  GtkWindow *default_window;
+};
+
+G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
+
+static gboolean
+gtk_application_default_quit (GApplication *application, guint timestamp)
+{
+  gtk_main_quit ();
+  return TRUE;
+}
+
+static void
+gtk_application_default_run (GApplication *application)
+{
+  gtk_main ();
+}
+
+static void
+gtk_application_default_action (GApplication *application, const char *action, guint timestamp)
+{
+  GtkApplication *app = GTK_APPLICATION (application);
+  GList *actions, *iter;
+  
+  actions = gtk_action_group_list_actions (app->priv->main_actions);
+  for (iter = actions; iter; iter = iter->next)
+    {
+      GtkAction *gtkaction = iter->data;
+      if (strcmp (action, gtk_action_get_name (gtkaction)) == 0)
+        {
+          /* TODO set timestamp */
+          gtk_action_activate (gtkaction);
+          break;
+        }
+    }
+  g_list_free (actions);
+}
+
+/**
+ * gtk_application_new:
+ * @argc: (allow-none) (inout): System argument count
+ * @argv: (allow-none) (inout): System argument vector
+ * @appid: System-dependent application identifier
+ *
+ * Create a new #GtkApplication, or if one has already been initialized
+ * in this process, return the existing instance. This function will as a side effect
+ * initialize the display system; see gtk_init().
+ *
+ * For the behavior if this application is running in another process,
+ * see g_application_new().
+ *
+ * Returns: (transfer full): A newly-referenced #GtkApplication
+ */
+GtkApplication*
+gtk_application_new (int                  *argc,
+                     char               ***argv,
+                     const char           *appid)
+{  
+  gtk_init (argc, argv);
+
+  return g_object_new (GTK_TYPE_APPLICATION, "appid", appid, NULL);
+}
+
+static void
+on_action_sensitive (GtkAction      *action,
+		     GParamSpec     *pspec,
+		     GtkApplication *app)
+{
+  
+  g_application_set_action_enabled (G_APPLICATION (app), 
+				    gtk_action_get_name (action),
+				    gtk_action_get_sensitive (action));
+}
+
+/**
+ * gtk_application_set_main_action_group:
+ * @app: A #GtkApplication
+ * @group: A #GtkActionGroup
+ *
+ * Set @group as this application's global action group.  This will
+ * ensure the operating system interface uses these actions as follows:
+ *
+ * <itemizedlist>
+ *   <listitem>In GNOME 2 this exposes the actions for scripting.<listitem>
+ *   <listitem>In GNOME 3, this function populates the application menu.</listitem>
+ *   <listitem>In Windows prior to version 7, this function does nothing.</listitem>
+ *   <listitem>In Windows 7, this function adds "Tasks" to the Jump List.</listitem>
+ *   <listitem>In Mac OS X, this function extends the Dock menu.</listitem>
+ * </itemizedlist>
+ *
+ * It is an error to call this function more than once.
+ */
+void
+gtk_application_set_main_action_group (GtkApplication *app,
+                                       GtkActionGroup *group)
+{
+  GList *actions, *iter;
+
+  g_return_if_fail (GTK_IS_APPLICATION (app));
+  g_return_if_fail (app->priv->main_actions == NULL);
+  
+  app->priv->main_actions = g_object_ref (group);
+  actions = gtk_action_group_list_actions (group);
+  for (iter = actions; iter; iter = iter->next)
+    {
+      GtkAction *action = iter->data;
+      g_application_add_action (G_APPLICATION (app),
+                                gtk_action_get_name (action),
+                                gtk_action_get_tooltip (action));
+      g_signal_connect (action, "notify::sensitive", G_CALLBACK (on_action_sensitive), app);
+    }
+  g_list_free (actions);
+}
+
+static gboolean
+gtk_application_on_window_destroy (GtkWidget  *window,
+                                   gpointer    user_data)
+{
+  GtkApplication *app = GTK_APPLICATION (user_data);
+
+  gtk_application_quit (app);
+  return FALSE;
+}
+
+/**
+ * gtk_application_get_window:
+ * @app: a #GtkApplication
+ *
+ * A #GtkApplication has a "default window".  This window should act as
+ * the primary user interaction point with your application.  This
+ * window is of type #GTK_WINDOW_TYPE_TOPLEVEL and its properties such
+ * as "title" and "icon-name" will be initialized as appropriate for the
+ * platform.
+ *
+ * If the user closes this window, and your application hasn't created
+ * any other windows, the default action will be to call gtk_application_quit().
+ *
+ * Returns: (transfer none): The default #GtkWindow for this application
+ */
+GtkWindow *
+gtk_application_get_window (GtkApplication *app)
+{
+  if (app->priv->default_window != NULL)
+    return app->priv->default_window;
+
+  app->priv->default_window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
+  g_object_ref_sink (app->priv->default_window);
+  /* TODO look up .desktop file on freedesktop platform, initialize title etc. */
+  g_signal_connect (app->priv->default_window, "destroy",
+                    G_CALLBACK (gtk_application_on_window_destroy), app);
+
+  return app->priv->default_window;
+}
+
+/**
+ * gtk_application_run:
+ * @app: a #GtkApplication
+ *
+ * Runs the main loop; see g_application_run().  The default
+ * implementation for #GtkApplication uses gtk_main().
+ */
+void
+gtk_application_run (GtkApplication  *app)
+{
+  g_application_run (G_APPLICATION (app));
+}
+
+/**
+ * gtk_application_quit:
+ * @app: a #GtkApplication
+ *
+ * Request the application exit.  By default, this
+ * method will exit the main loop; see gtk_main_quit().
+ */
+void
+gtk_application_quit (GtkApplication *app)
+{
+  g_application_quit (G_APPLICATION (app), gtk_get_current_event_time ());
+}
+
+static void
+gtk_application_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  GtkApplication *app = GTK_APPLICATION (object);
+
+  switch (prop_id)
+    {
+      case PROP_WINDOW:
+        g_value_set_object (value, gtk_application_get_window (app));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtk_application_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  GtkApplication *app = GTK_APPLICATION (object);
+  
+  g_assert (app != NULL);
+
+  switch (prop_id)
+    {
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+
+static void
+gtk_application_init (GtkApplication *application)
+{
+  application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application, GTK_TYPE_APPLICATION, GtkApplicationPrivate);
+}
+
+static GObject*
+gtk_application_constructor (GType                  type,
+                             guint                  n_construct_properties,
+                             GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  
+  object = (* G_OBJECT_CLASS (gtk_application_parent_class)->constructor) (type,
+                                                                           n_construct_properties,
+                                                                           construct_params);
+  
+  return object;
+}
+
+static void
+gtk_application_class_init (GtkApplicationClass *klass)
+{
+  GObjectClass *gobject_class;
+  GApplicationClass *application_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  application_class = G_APPLICATION_CLASS (klass);
+
+  gobject_class->constructor = gtk_application_constructor;
+  gobject_class->get_property = gtk_application_get_property;
+  gobject_class->set_property = gtk_application_set_property;
+  
+  application_class->run = gtk_application_default_run;
+  application_class->quit = gtk_application_default_quit;
+  application_class->action = gtk_application_default_action;
+
+  g_type_class_add_private (gobject_class, sizeof (GtkApplicationPrivate));
+}
+
+#define __GTK_APPLICATION_C__
+#include "gtkaliasdef.c"
diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h
new file mode 100644
index 0000000..8ab81b2
--- /dev/null
+++ b/gtk/gtkapplication.h
@@ -0,0 +1,94 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters verbum org>
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_APPLICATION_H__
+#define __GTK_APPLICATION_H__
+
+#include <gio/gio.h>
+#include <gtk/gtkaction.h>
+#include <gtk/gtkactiongroup.h>
+#include <gtk/gtkwindow.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_APPLICATION            (gtk_application_get_type ())
+#define GTK_APPLICATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_APPLICATION, GtkApplication))
+#define GTK_APPLICATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_APPLICATION, GtkApplicationClass))
+#define GTK_IS_APPLICATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_APPLICATION))
+#define GTK_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_APPLICATION))
+#define GTK_APPLICATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_APPLICATION, GtkApplicationClass))
+
+typedef struct _GtkApplication        GtkApplication;
+typedef struct _GtkApplicationClass   GtkApplicationClass;
+typedef struct _GtkApplicationPrivate GtkApplicationPrivate;
+
+struct _GtkApplication
+{
+  GApplication parent;
+
+  /*< private >*/
+
+  GtkApplicationPrivate *priv;
+};
+
+struct _GtkApplicationClass
+{
+  GApplicationClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+  void (*_gtk_reserved5) (void);
+  void (*_gtk_reserved6) (void);
+};
+
+GType           gtk_application_get_type        (void) G_GNUC_CONST;
+GtkApplication* gtk_application_new             (int                 *argc,
+                                                 char              ***argv,
+                                                 const char          *appid);
+
+void            gtk_application_set_main_action_group (GtkApplication *app,
+                                                       GtkActionGroup *group);
+
+GtkWindow *     gtk_application_get_window (GtkApplication *app);
+   
+void            gtk_application_run (GtkApplication  *app);
+
+void            gtk_application_quit (GtkApplication *app);
+
+G_END_DECLS
+
+#endif /* __GTK_APPLICATION_H__ */
+
diff --git a/tests/Makefile.am b/tests/Makefile.am
index df80043..0d0da2e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -31,6 +31,7 @@ noinst_PROGRAMS =  $(TEST_PROGS)	\
 	print-editor			\
 	extendedlayoutexample		\
 	testaccel			\
+	testapplication			\
 	testassistant			\
 	testbbox			\
 	testbuttons			\
@@ -116,6 +117,7 @@ extendedlayoutexample_DEPENDENCIES = $(TEST_DEPS)
 testicontheme_DEPENDENCIES = $(TEST_DEPS)
 testiconview_DEPENDENCIES = $(TEST_DEPS)
 testaccel_DEPENDENCIES = $(TEST_DEPS)
+testapplication_DEPENDENCIES = $(TEST_DEPS)
 testassistant_DEPENDENCIES = $(TEST_DEPS)
 testbbox_DEPENDENCIES = $(TEST_DEPS)
 testbuttons_DEPENDENCIES = $(TEST_DEPS)
@@ -178,6 +180,7 @@ simple_LDADD = $(LDADDS)
 print_editor_LDADD = $(LDADDS)
 extendedlayoutexample_LDADD = $(LDADDS)
 testaccel_LDADD = $(LDADDS)
+testapplication_LDADD = $(LDADDS)
 testassistant_LDADD = $(LDADDS)
 testbbox_LDADD = $(LDADDS)
 testbuttons_LDADD = $(LDADDS)
@@ -245,7 +248,6 @@ testtooltips_LDADD = $(LDADDS)
 testvolumebutton_LDADD = $(LDADDS)
 testwindows_LDADD = $(LDADDS)
 
-
 testentrycompletion_SOURCES = 	\
 	prop-editor.c		\
 	testentrycompletion.c
diff --git a/tests/testapplication.c b/tests/testapplication.c
new file mode 100644
index 0000000..06c6db8
--- /dev/null
+++ b/tests/testapplication.c
@@ -0,0 +1,81 @@
+/* GTK - The GIMP Toolkit
+ * testapplication.c: Using GtkApplication
+ * Copyright (C) 2010, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+
+static const char *builder_data =
+"<interface>"
+"<object class=\"GtkAboutDialog\" id=\"about_dialog\">"
+"  <property name=\"program-name\">Test Application</property>"
+"  <property name=\"website\">http://gtk.org</property>"
+"</object>"
+"<object class=\"GtkActionGroup\" id=\"main_actions\">"
+"  <child>"
+"      <object class=\"GtkAction\" id=\"About\">"
+"          <property name=\"name\">About</property>"
+"          <property name=\"stock_id\">gtk-about</property>"
+"      </object>"
+"  </child>"
+"</object>"
+"</interface>";
+
+static GtkWidget *about_dialog;
+
+static void
+about_activate (GtkAction *action,
+                gpointer   user_data)
+{
+  gtk_dialog_run (GTK_DIALOG (about_dialog));
+  gtk_widget_hide (GTK_WIDGET (about_dialog));
+}
+
+int
+main (int argc, char **argv)
+{
+  GtkApplication *app;
+  GtkWindow *window;
+  GtkBuilder *builder;
+  GtkAction *action;
+  GtkActionGroup *actions;
+
+  app = gtk_application_new (&argc, &argv, "org.gtk.TestApp");
+  builder = gtk_builder_new ();
+  if (!gtk_builder_add_from_string (builder, builder_data, -1, NULL))
+    g_error ("failed to parse UI");
+  actions = GTK_ACTION_GROUP (gtk_builder_get_object (builder, "main_actions"));
+  gtk_application_set_main_action_group (app, actions);
+  
+  action = gtk_action_group_get_action (actions, "About");
+  g_signal_connect (action, "activate", G_CALLBACK (about_activate), app);
+  
+  about_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "about_dialog"));
+  
+  gtk_builder_connect_signals (builder, app);
+  g_object_unref (builder);
+  
+  window = gtk_application_get_window (app);
+  gtk_container_add (GTK_CONTAINER (window), gtk_label_new ("Hello world"));
+  gtk_widget_show_all (GTK_WIDGET (window));
+ 
+  gtk_application_run (app);
+
+  return 0;
+}



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