diff options
author | Ryan Lortie <desrt@desrt.ca> | 2010-08-11 01:23:23 -0400 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2010-08-11 01:23:23 -0400 |
commit | 5ae008606d34c4675b6e487006ebe696b1d375b3 (patch) | |
tree | 0cf742cfa5db9c99ed8bd0e65022c6bb62e75e76 | |
parent | b35c2e695ac5db971e16461f2ddf80ed783e2ddb (diff) | |
download | gtk+-application.tar.gz |
GtkApplication rewriteapplication
-rw-r--r-- | gtk/gtkapplication.c | 714 | ||||
-rw-r--r-- | gtk/gtkapplication.h | 67 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 100 | ||||
-rw-r--r-- | gtk/gtkwindow.h | 5 |
4 files changed, 274 insertions, 612 deletions
diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c index a0864bdbc6..812d9c2f61 100644 --- a/gtk/gtkapplication.c +++ b/gtk/gtkapplication.c @@ -33,10 +33,8 @@ #include <unistd.h> #include "gtkapplication.h" +#include "gtkwindow.h" #include "gtkmain.h" -#include "gtkmarshalers.h" -#include "gtkintl.h" -#include "gtkprivate.h" #include <gdk/gdk.h> #ifdef GDK_WINDOWING_X11 @@ -66,668 +64,250 @@ * </programlisting> * </example> */ -enum -{ - PROP_0, - - PROP_WINDOW -}; enum { - ACTIVATED, - QUIT, - ACTION, - - LAST_SIGNAL + PROP_NONE, + PROP_ACTION_GROUP, + PROP_DEFAULT_WINDOW }; -static guint gtk_application_signals[LAST_SIGNAL] = { 0 }; - struct _GtkApplicationPrivate { - GtkActionGroup *main_actions; - + GtkActionGroup *action_group; GtkWindow *default_window; - GSList *windows; }; G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION) static void -process_timestamp_from_platform_data (GVariant *platform_data) -{ - /* TODO - extract timestamp from here, update GDK time */ -} - -static gboolean -gtk_application_default_quit (GtkApplication *application) -{ - gtk_main_quit (); - return TRUE; -} - -static gboolean -gtk_application_default_quit_with_data (GApplication *application, - GVariant *platform_data) -{ - gboolean result; - - process_timestamp_from_platform_data (platform_data); - - g_signal_emit (application, gtk_application_signals[QUIT], 0, &result); - - return result; -} - -static void -gtk_application_default_run (GApplication *application) +gtk_application_set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) { - gtk_main (); -} + GtkApplication *application = GTK_APPLICATION (object); -static void -gtk_application_default_prepare_activation (GApplication *application, - GVariant *arguments, - GVariant *platform_data) -{ - GVariantIter iter; - const gchar *key; - GVariant *value; - - g_variant_iter_init (&iter, platform_data); - while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) + switch (prop_id) { - if (strcmp (key, "startup-notification-id") == 0 && - g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) - gdk_notify_startup_complete_with_id (g_variant_get_string (value, NULL)); - g_variant_unref (value); + case PROP_ACTION_GROUP: + gtk_application_set_action_group (application, + g_value_get_object (value)); + break; + + case PROP_DEFAULT_WINDOW: + gtk_application_set_default_window (application, + g_value_get_object (value)); + break; + + default: + g_assert_not_reached (); } - - g_signal_emit (G_OBJECT (application), gtk_application_signals[ACTIVATED], 0, arguments); -} - -static void -gtk_application_default_activated (GtkApplication *application, - GVariant *arguments) -{ - GtkApplicationPrivate *priv = application->priv; - - /* TODO: should we raise the last focused window instead ? */ - if (priv->default_window != NULL) - gtk_window_present (priv->default_window); } static void -gtk_application_default_action (GtkApplication *application, - const gchar *action_name) +gtk_application_get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) { - GtkApplicationPrivate *priv = application->priv; - GtkAction *action; + GtkApplication *application = GTK_APPLICATION (object); - action = gtk_action_group_get_action (priv->main_actions, action_name); - if (action) - gtk_action_activate (action); + switch (prop_id) + { + case PROP_ACTION_GROUP: + g_value_set_object (value, + gtk_application_get_action_group (application)); + break; + + case PROP_DEFAULT_WINDOW: + g_value_set_object (value, + gtk_application_get_default_window (application)); + break; + + default: + g_assert_not_reached (); + } } static GtkWindow * -gtk_application_default_create_window (GtkApplication *application) +gtk_application_real_create_window (GtkApplication *application) { return GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL)); } static void -gtk_application_default_action_with_data (GApplication *application, - const gchar *action_name, - GVariant *platform_data) -{ - process_timestamp_from_platform_data (platform_data); - - g_signal_emit (application, gtk_application_signals[ACTION], g_quark_from_string (action_name)); -} - -static GVariant * -gtk_application_format_activation_data (void) +gtk_application_activate (GApplication *gapplication) { - const gchar *startup_id = NULL; - GdkDisplay *display = gdk_display_get_default (); - GVariantBuilder builder; + GtkApplication *application = GTK_APPLICATION (gapplication); - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + if (application->priv->default_window == NULL) + { + GtkWindow *window; - /* try and get the startup notification id from GDK, the environment - * or, if everything else failed, fake one. - */ -#ifdef GDK_WINDOWING_X11 - startup_id = gdk_x11_display_get_startup_notification_id (display); -#endif /* GDK_WINDOWING_X11 */ + window = GTK_APPLICATION_GET_CLASS (application) + ->create_window (application); - if (startup_id) - g_variant_builder_add (&builder, "{sv}", "startup-notification-id", - g_variant_new ("s", startup_id)); - return g_variant_builder_end (&builder); -} - -/** - * gtk_application_new: - * @appid: System-dependent application identifier - * @argc: (allow-none) (inout): System argument count - * @argv: (allow-none) (inout): System argument vector - * - * 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 - * - * Since: 3.0 - */ -GtkApplication* -gtk_application_new (const gchar *appid, - gint *argc, - gchar ***argv) -{ - GtkApplication *app; - gint argc_for_app; - const gchar **argv_for_app; - GVariant *argv_variant; - GError *error = NULL; - - gtk_init (argc, argv); - - if (argc) - argc_for_app = *argc; - else - argc_for_app = 0; - - if (argv) - argv_for_app = (const gchar **) *argv; - else - argv_for_app = NULL; - - argv_variant = g_variant_new_bytestring_array (argv_for_app, argc_for_app); - - app = g_initable_new (GTK_TYPE_APPLICATION, - NULL, - &error, - "application-id", appid, - "argv", argv_variant, - NULL); - if (app == NULL) - { - g_error ("%s", error->message); - g_clear_error (&error); - return NULL; + if (window != NULL) + gtk_application_set_default_window (application, window); } - return app; + if (application->priv->default_window != NULL) + gtk_window_present (application->priv->default_window); } static void -on_action_sensitive (GtkAction *action, - GParamSpec *pspec, - GtkApplication *app) +gtk_application_action (GApplication *gapplication, + const gchar *action_name, + GVariant *parameters) { - g_application_set_action_enabled (G_APPLICATION (app), - gtk_action_get_name (action), - gtk_action_get_sensitive (action)); -} + GtkApplication *application = GTK_APPLICATION (gapplication); -/** - * gtk_application_set_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. - * - * Since: 3.0 - */ -void -gtk_application_set_action_group (GtkApplication *app, - GtkActionGroup *group) -{ - GList *actions, *iter; + if (parameters == NULL && application->priv->action_group != NULL) + { + GtkAction *action; - g_return_if_fail (GTK_IS_APPLICATION (app)); - g_return_if_fail (GTK_IS_ACTION_GROUP (group)); - g_return_if_fail (app->priv->main_actions == NULL); + action = gtk_action_group_get_action (application->priv->action_group, + action_name); - 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); + if (action != NULL) + { + gtk_action_activate (action); + return; + } } - g_list_free (actions); } -static gboolean -gtk_application_on_window_destroy (GtkWidget *window, - gpointer user_data) +GtkApplication * +gtk_application_new (const gchar *application_id, + GApplicationFlags flags, + GtkActionGroup *action_group) { - GtkApplication *app = GTK_APPLICATION (user_data); + g_return_val_if_fail (g_application_id_is_valid (application_id), NULL); - app->priv->windows = g_slist_remove (app->priv->windows, window); + gtk_init (NULL, NULL); - if (app->priv->windows == NULL) - gtk_application_quit (app); - - return FALSE; + return g_object_new (GTK_TYPE_APPLICATION, + "application-id", application_id, + "flags", flags, + "action-group", action_group, + NULL); } -static gchar *default_title; - -/** - * gtk_application_add_window: - * @app: a #GtkApplication - * @window: a toplevel window to add to @app - * - * Adds a window to the #GtkApplication. - * - * If all the windows managed by #GtkApplication are closed, the - * #GtkApplication will call gtk_application_quit(), and quit - * the application. - * - * If your application uses only a single toplevel window, you can - * use gtk_application_get_window(). If you are using a sub-class - * of #GtkApplication you should call gtk_application_create_window() - * to let the #GtkApplication instance create a #GtkWindow and add - * it to the list of toplevels of the application. You should call - * this function only to add #GtkWindow<!-- -->s that you created - * directly using gtk_window_new(). - * - * Since: 3.0 - */ -void -gtk_application_add_window (GtkApplication *app, - GtkWindow *window) +GtkActionGroup * +gtk_application_get_action_group (GtkApplication *application) { - GtkApplicationPrivate *priv; - - g_return_if_fail (GTK_IS_APPLICATION (app)); - g_return_if_fail (GTK_IS_WINDOW (window)); - - priv = app->priv; + g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL); - if (g_slist_find (priv->windows, window) != NULL) - return; - - priv->windows = g_slist_prepend (priv->windows, window); - - if (priv->default_window == NULL) - priv->default_window = window; - - if (gtk_window_get_title (window) == NULL && default_title != NULL) - gtk_window_set_title (window, default_title); - - g_signal_connect (window, "destroy", - G_CALLBACK (gtk_application_on_window_destroy), - app); + return application->priv->action_group; } -/** - * gtk_application_get_window: - * @app: a #GtkApplication - * - * A simple #GtkApplication has a "default window". This window should - * act as the primary user interaction point with your application. - * The window returned by this function 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(). - * - * If your application has more than one toplevel window (e.g. an - * single-document-interface application with multiple open documents), - * or if you are constructing your toplevel windows yourself (e.g. using - * #GtkBuilder), use gtk_application_create_window() or - * gtk_application_add_window() instead. - * - * Returns: (transfer none): The default #GtkWindow for this application - * - * Since: 3.0 - */ -GtkWindow * -gtk_application_get_window (GtkApplication *app) +void +gtk_application_set_action_group (GtkApplication *application, + GtkActionGroup *action_group) { - GtkApplicationPrivate *priv; - - g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL); + g_return_if_fail (GTK_IS_APPLICATION (application)); + g_return_if_fail (action_group == NULL || GTK_IS_ACTION_GROUP (action_group)); - priv = app->priv; + if (application->priv->action_group != action_group) + { + if (application->priv->action_group) + g_object_unref (application->priv->action_group); - if (priv->default_window != NULL) - return priv->default_window; + application->priv->action_group = action_group; - return gtk_application_create_window (app); -} + if (application->priv->action_group) + g_object_ref (application->priv->action_group); -/** - * gtk_application_get_windows: - * @app: a #GtkApplication - * - * Retrieves the list of windows previously registered with - * gtk_application_create_window() or gtk_application_add_window(). - * - * Return value: (element-type GtkWindow) (transfer none): A pointer - * to the list of #GtkWindow<!-- -->s registered by this application, - * or %NULL. The returned #GSList is owned by the #GtkApplication - * and it should not be modified or freed directly. - * - * Since: 3.0 - */ -G_CONST_RETURN GSList * -gtk_application_get_windows (GtkApplication *app) -{ - g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL); + /* XXX synch the list... */ - return app->priv->windows; + g_object_notify (G_OBJECT (application), "action-group"); + } } -/** - * gtk_application_create_window: - * @app: a #GtkApplication - * - * Creates a new #GtkWindow for the application. - * - * This function calls the #GtkApplication::create_window() virtual function, - * which can be overridden by sub-classes, for instance to use #GtkBuilder to - * create the user interface. After creating a new #GtkWindow instance, it will - * be added to the list of toplevels associated to the application. - * - * Return value: (transfer none): the newly created application #GtkWindow - * - * Since: 3.0 - */ GtkWindow * -gtk_application_create_window (GtkApplication *app) +gtk_application_get_default_window (GtkApplication *application) { - GtkWindow *window; - - g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL); + g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL); - window = GTK_APPLICATION_GET_CLASS (app)->create_window (app); - gtk_application_add_window (app, window); - - return window; -} - -/** - * gtk_application_run: - * @app: a #GtkApplication - * - * Runs the main loop; see g_application_run(). - * The default implementation for #GtkApplication uses gtk_main(). - * - * Since: 3.0 - */ -void -gtk_application_run (GtkApplication *app) -{ - g_application_run (G_APPLICATION (app)); + return application->priv->default_window; } -/** - * gtk_application_quit: - * @app: a #GtkApplication - * - * Request the application exit. This function invokes - * g_application_quit_with_data(), which normally will - * in turn cause @app to emit #GtkApplication::quit. - * - * To control an application's quit behavior (for example, to ask for - * files to be saved), connect to the #GtkApplication::quit signal - * handler. - * - * Since: 3.0 - */ void -gtk_application_quit (GtkApplication *app) +gtk_application_set_default_window (GtkApplication *application, + GtkWindow *window) { - GVariantBuilder builder; - GVariant *platform_data; + g_return_if_fail (GTK_IS_APPLICATION (application)); + g_return_if_fail (window == NULL || GTK_IS_WINDOW (window)); - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&builder, "{sv}", - "timestamp", - g_variant_new ("u", gtk_get_current_event_time ())); - platform_data = g_variant_builder_end (&builder); + if (application->priv->default_window != window) + { + if (window) + gtk_window_set_application (window, application); - g_application_quit_with_data (G_APPLICATION (app), platform_data); + application->priv->default_window = window; - g_variant_unref (platform_data); + g_object_notify (G_OBJECT (application), "default-window"); + } } static void -gtk_application_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gtk_application_quit_mainloop (GApplication *application) { - 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); - } + gtk_main_quit (); } static void -gtk_application_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gtk_application_run_mainloop (GApplication *application) { - GtkApplication *app = GTK_APPLICATION (object); - - g_assert (app != NULL); - - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + gtk_main (); } static void -setup_default_window_decorations (void) +gtk_application_finalize (GObject *object) { - const gchar *pid; - const gchar *filename; - GKeyFile *keyfile; - gchar *title; - gchar *icon_name; - - pid = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE_PID"); - filename = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE"); - - keyfile = g_key_file_new (); - - if (pid != NULL && filename != NULL && atoi (pid) == getpid () && - g_key_file_load_from_file (keyfile, filename, 0, NULL)) - { - title = g_key_file_get_locale_string (keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); - icon_name = g_key_file_get_string (keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL); - - if (default_title == NULL) - default_title = title; - - if (gtk_window_get_default_icon_name () == NULL) - gtk_window_set_default_icon_name (icon_name); + GtkApplication *application = GTK_APPLICATION (object); - g_free (icon_name); - } + if (application->priv->action_group) + g_object_unref (application->priv->action_group); - g_key_file_free (keyfile); + G_OBJECT_CLASS (gtk_application_parent_class) + ->finalize (object); } static void gtk_application_init (GtkApplication *application) { - application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application, GTK_TYPE_APPLICATION, GtkApplicationPrivate); + application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application, + GTK_TYPE_APPLICATION, + GtkApplicationPrivate); +} - g_object_set (application, "platform-data", gtk_application_format_activation_data (), NULL); +static void +gtk_application_class_init (GtkApplicationClass *class) +{ + GApplicationClass *application_class = G_APPLICATION_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); - setup_default_window_decorations (); -} + object_class->set_property = gtk_application_set_property; + object_class->get_property = gtk_application_get_property; + class->create_window = gtk_application_real_create_window; -static GObject* -gtk_application_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_params) -{ - GObject *object; + application_class->quit_mainloop = gtk_application_quit_mainloop; + application_class->run_mainloop = gtk_application_run_mainloop; + application_class->activate = gtk_application_activate; + application_class->action = gtk_application_action; - /* Last ditch effort here */ - gtk_init (0, NULL); + object_class->finalize = gtk_application_finalize; - object = (* G_OBJECT_CLASS (gtk_application_parent_class)->constructor) (type, - n_construct_properties, - construct_params); + g_object_class_install_property (object_class, PROP_ACTION_GROUP, + g_param_spec_object ("action-group", "action group", + "the GtkActionGroup for the application", + GTK_TYPE_ACTION_GROUP, G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - return object; -} + g_object_class_install_property (object_class, PROP_DEFAULT_WINDOW, + g_param_spec_object ("default-window", "default window", + "the default window for the application", + GTK_TYPE_WINDOW, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); -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_with_data = gtk_application_default_quit_with_data; - application_class->action_with_data = gtk_application_default_action_with_data; - application_class->prepare_activation = gtk_application_default_prepare_activation; - - klass->quit = gtk_application_default_quit; - klass->action = gtk_application_default_action; - klass->create_window = gtk_application_default_create_window; - - klass->activated = gtk_application_default_activated; - - /** - * GtkApplication::activated: - * @arguments: A #GVariant with the signature "aay" - * - * This signal is emitted when a non-primary process for a given - * application is invoked while your application is running; for - * example, when a file browser launches your program to open a - * file. The raw operating system arguments are passed in the - * variant @arguments. - * - * Since: 3.0 - */ - gtk_application_signals[ACTIVATED] = - g_signal_new (g_intern_static_string ("activated"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkApplicationClass, activated), - NULL, NULL, - g_cclosure_marshal_VOID__VARIANT, - G_TYPE_NONE, 1, - G_TYPE_VARIANT); - - /** - * GtkApplication::quit: - * @application: the object on which the signal is emitted - * - * This signal is emitted when a quit is initiated. See also - * the #GApplication::quit-with-data signal which may in - * turn trigger this signal. - * - * The default handler for this signal exits the mainloop of the - * application. It is possible to override the default handler - * by simply returning %TRUE from a callback, e.g.: - * - * |[ - * static gboolean - * my_application_quit (GtkApplication *application) - * { - * /* if some_condition is TRUE, do not quit */ - * if (some_condition) - * return TRUE; - * - * /* this will cause the application to quit * - * return FALSE; - * } - * - * g_signal_connect (application, "quit", - * G_CALLBACK (my_application_quit), - * NULL); - * ]| - * - * Returns: %TRUE if the signal has been handled, %FALSE to continue - * signal emission - * - * Since: 3.0 - */ - gtk_application_signals[QUIT] = - g_signal_new (g_intern_static_string ("quit"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkApplicationClass, quit), - g_signal_accumulator_true_handled, NULL, - _gtk_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); - - /** - * GtkApplication::action: - * @application: the object on which the signal is emitted - * @name: The name of the activated action - * - * This signal is emitted when an action is activated. The action name - * is passed as the first argument, but also as signal detail, so it - * is possible to connect to this signal for individual actions. - * - * See also the #GApplication::action-with-data signal which may in - * turn trigger this signal. - * - * The signal is never emitted for disabled actions. - * - * Since: 3.0 - */ - gtk_application_signals[ACTION] = - g_signal_new (g_intern_static_string ("action"), - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (GtkApplicationClass, action), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - g_type_class_add_private (gobject_class, sizeof (GtkApplicationPrivate)); + g_type_class_add_private (object_class, sizeof (GtkApplicationPrivate)); } diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h index 929cb29323..35fe7d2030 100644 --- a/gtk/gtkapplication.h +++ b/gtk/gtkapplication.h @@ -1,5 +1,5 @@ -/* GTK - The GIMP Toolkit - * +/* + * Copyright © 2010 Codethink Limited * Copyright (C) 2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or @@ -17,14 +17,8 @@ * 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/. + * Author: Ryan Lortie <desrt@desrt.ca> + * Colin Walters <walters@verbum.org> */ #if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) @@ -34,10 +28,9 @@ #ifndef __GTK_APPLICATION_H__ #define __GTK_APPLICATION_H__ -#include <gio/gio.h> -#include <gtk/gtkaction.h> #include <gtk/gtkactiongroup.h> -#include <gtk/gtkwindow.h> +#include <gtk/gtkwidget.h> +#include <gio/gio.h> G_BEGIN_DECLS @@ -57,7 +50,6 @@ struct _GtkApplication GApplication parent; /*< private >*/ - GtkApplicationPrivate *priv; }; @@ -67,39 +59,24 @@ struct _GtkApplicationClass /*< vfuncs >*/ GtkWindow *(* create_window) (GtkApplication *application); - void (* activated) (GtkApplication *application, - GVariant *args); - void (* action) (GtkApplication *application, - const gchar *action_name); - gboolean (* quit) (GtkApplication *application); - - - /* 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); - void (*_gtk_reserved7) (void); - void (*_gtk_reserved8) (void); - void (*_gtk_reserved9) (void); - void (*_gtk_reserved10) (void); + + /*< private >*/ + gpointer padding[12]; }; -GType gtk_application_get_type (void) G_GNUC_CONST; -GtkApplication* gtk_application_new (const gchar *appid, - gint *argc, - gchar ***argv); -void gtk_application_set_action_group (GtkApplication *app, - GtkActionGroup *group); -GtkWindow * gtk_application_create_window (GtkApplication *app); -GtkWindow * gtk_application_get_window (GtkApplication *app); -G_CONST_RETURN GSList * gtk_application_get_windows (GtkApplication *app); -void gtk_application_add_window (GtkApplication *app, - GtkWindow *window); -void gtk_application_run (GtkApplication *app); -void gtk_application_quit (GtkApplication *app); +GType gtk_application_get_type (void) G_GNUC_CONST; + +GtkApplication* gtk_application_new (const gchar *appid, + GApplicationFlags flags, + GtkActionGroup *action_group); + +GtkActionGroup * gtk_application_get_action_group (GtkApplication *application); +void gtk_application_set_action_group (GtkApplication *application, + GtkActionGroup *action_group); + +GtkWindow * gtk_application_get_default_window (GtkApplication *application); +void gtk_application_set_default_window (GtkApplication *application, + GtkWindow *window); G_END_DECLS diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index a9fa7185ee..f48bb6021c 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -124,6 +124,7 @@ enum { PROP_GRAVITY, PROP_TRANSIENT_FOR, PROP_OPACITY, + PROP_APPLICATION, /* Readonly properties */ PROP_IS_ACTIVE, @@ -223,6 +224,7 @@ struct _GtkWindowPrivate guint mnemonics_visible_set : 1; GdkWindowTypeHint type_hint; + GtkApplication *application; gdouble opacity; @@ -826,6 +828,24 @@ gtk_window_class_init (GtkWindowClass *klass) 1.0, GTK_PARAM_READWRITE)); + /** + * GtkWindow:application: + * + * The #GtkApplication associated with the window. + * + * The application will be kept alive for at least as long as the + * window is open. + * + * Since: 3.0 + */ + g_object_class_install_property (gobject_class, + PROP_APPLICATION, + g_param_spec_object ("application", + P_("GtkApplication"), + P_("The GtkApplication for the window"), + GTK_TYPE_APPLICATION, + GTK_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + window_signals[SET_FOCUS] = g_signal_new (I_("set-focus"), G_TYPE_FROM_CLASS (gobject_class), @@ -1091,6 +1111,9 @@ gtk_window_set_property (GObject *object, case PROP_OPACITY: gtk_window_set_opacity (window, g_value_get_double (value)); break; + case PROP_APPLICATION: + gtk_window_set_application (window, g_value_get_object (value)); + break; case PROP_MNEMONICS_VISIBLE: gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value)); break; @@ -1203,6 +1226,9 @@ gtk_window_get_property (GObject *object, case PROP_OPACITY: g_value_set_double (value, gtk_window_get_opacity (window)); break; + case PROP_APPLICATION: + g_value_set_object (value, gtk_window_get_application (window)); + break; case PROP_MNEMONICS_VISIBLE: g_value_set_boolean (value, priv->mnemonics_visible); break; @@ -2412,6 +2438,78 @@ gtk_window_get_opacity (GtkWindow *window) } /** + * gtk_window_get_application: + * @window: a #GtkWindow + * + * Gets the #GtkApplication associated with the window (if any). + * + * Return value: a #GtkApplication, or %NULL + * + * Since: 3.0 + **/ +GtkApplication * +gtk_window_get_application (GtkWindow *window) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); + + return GTK_WINDOW_GET_PRIVATE (window)->application; +} + +static void +gtk_window_release_application (GtkWindow *window, + GtkWindowPrivate *priv) +{ + if (priv->application) + { + if (gtk_application_get_default_window (priv->application) == window) + gtk_application_set_default_window (priv->application, NULL); + + g_application_release (G_APPLICATION (priv->application)); + g_object_unref (priv->application); + + priv->application = NULL; + } +} + +/** + * gtk_window_set_application: + * @window: a #GtkWindow + * @application: a #GtkApplication, or %NULL + * + * Sets or unsets the #GtkApplication associated with the window. + * + * The application will be kept alive for at least as long as the window + * is open. + * + * Since: 3.0 + **/ +void +gtk_window_set_application (GtkWindow *window, + GtkApplication *application) +{ + GtkWindowPrivate *priv; + + g_return_if_fail (GTK_IS_WINDOW (window)); + + priv = GTK_WINDOW_GET_PRIVATE (window); + + if (priv->application != application) + { + gtk_window_release_application (window, priv); + + priv->application = application; + + if (priv->application != NULL) + { + g_application_hold (G_APPLICATION (priv->application)); + g_object_ref (priv->application); + } + + g_object_notify (G_OBJECT (window), "application"); + } +} + +/** * gtk_window_set_type_hint: * @window: a #GtkWindow * @hint: the window type @@ -4422,6 +4520,8 @@ gtk_window_finalize (GObject *object) GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window); GtkMnemonicHash *mnemonic_hash; + gtk_window_release_application (window, priv); + g_free (window->title); g_free (window->wmclass_name); g_free (window->wmclass_class); diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h index 0a95b1864e..38e0101ae9 100644 --- a/gtk/gtkwindow.h +++ b/gtk/gtkwindow.h @@ -32,6 +32,7 @@ #define __GTK_WINDOW_H__ +#include <gtk/gtkapplication.h> #include <gtk/gtkaccelgroup.h> #include <gtk/gtkbin.h> @@ -399,6 +400,10 @@ GList * gtk_window_group_list_windows (GtkWindowGroup *window_grou GtkWidget * gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group, GdkDevice *device); +GtkApplication *gtk_window_get_application (GtkWindow *window); +void gtk_window_set_application (GtkWindow *window, + GtkApplication *application); + /* --- internal functions --- */ void _gtk_window_internal_set_focus (GtkWindow *window, |