diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c index 6e6cd1636c..8538151103 100644 --- a/gtk/gtkapplication.c +++ b/gtk/gtkapplication.c @@ -61,19 +61,10 @@ G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION) -GtkApplication * -gtk_application_new (const gchar *application_id, - GApplicationFlags flags) +struct _GtkApplicationPrivate { - g_return_val_if_fail (g_application_id_is_valid (application_id), NULL); - - g_type_init (); - - return g_object_new (GTK_TYPE_APPLICATION, - "application-id", application_id, - "flags", flags, - NULL); -} + GList *windows; +}; static void gtk_application_startup (GApplication *application) @@ -139,6 +130,9 @@ gtk_application_after_emit (GApplication *application, static void gtk_application_init (GtkApplication *application) { + application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application, + GTK_TYPE_APPLICATION, + GtkApplicationPrivate); } static void @@ -153,4 +147,98 @@ gtk_application_class_init (GtkApplicationClass *class) application_class->quit_mainloop = gtk_application_quit_mainloop; application_class->run_mainloop = gtk_application_run_mainloop; + + g_type_class_add_private (class, sizeof (GtkApplicationPrivate)); +} + +GtkApplication * +gtk_application_new (const gchar *application_id, + GApplicationFlags flags) +{ + g_return_val_if_fail (g_application_id_is_valid (application_id), NULL); + + g_type_init (); + + return g_object_new (GTK_TYPE_APPLICATION, + "application-id", application_id, + "flags", flags, + NULL); +} + +/** + * gtk_application_remove_window: + * @application: a #GtkApplication + * @window: a #GtkWindow + * + * Adds a window from @application. + * + * This call is equivalent to setting the application + * property of @window to @application. + * + * Since: 3.0 + **/ +void +gtk_application_add_window (GtkApplication *application, + GtkWindow *window) +{ + g_return_if_fail (GTK_IS_APPLICATION (application)); + + if (!g_list_find (application->priv->windows, window)) + { + application->priv->windows = g_list_prepend (application->priv->windows, + window); + gtk_window_set_application (window, application); + g_application_hold (G_APPLICATION (application)); + } +} + +/** + * gtk_application_remove_window: + * @application: a #GtkApplication + * @window: a #GtkWindow + * + * Remove a window from @application. + * + * If @window belongs to @application then this call is equivalent to + * setting the application property of @window to + * %NULL. + * + * The application may stop running as a result of a call to this + * function. + * + * Since: 3.0 + **/ +void +gtk_application_remove_window (GtkApplication *application, + GtkWindow *window) +{ + g_return_if_fail (GTK_IS_APPLICATION (application)); + + if (g_list_find (application->priv->windows, window)) + { + application->priv->windows = g_list_remove (application->priv->windows, + window); + g_application_release (G_APPLICATION (application)); + gtk_window_set_application (window, NULL); + } +} + +/** + * gtk_application_get_windows: + * @application: a #GtkApplication + * + * Gets a list of the #GtkWindows associated with @application. + * + * The list that is returned should not be modified in any way. + * + * Returns: a #GList of #GtkWindow + * + * Since: 3.0 + **/ +GList * +gtk_application_get_windows (GtkApplication *application) +{ + g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL); + + return application->priv->windows; } diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h index a4ff6c5d0a..c9c8571a46 100644 --- a/gtk/gtkapplication.h +++ b/gtk/gtkapplication.h @@ -64,9 +64,17 @@ struct _GtkApplicationClass GType gtk_application_get_type (void) G_GNUC_CONST; -GtkApplication* gtk_application_new (const gchar *application_id, +GtkApplication * gtk_application_new (const gchar *application_id, GApplicationFlags flags); +void gtk_application_add_window (GtkApplication *application, + GtkWindow *window); + +void gtk_application_remove_window (GtkApplication *application, + GtkWindow *window); + +GList * gtk_application_get_windows (GtkApplication *application); + G_END_DECLS #endif /* __GTK_APPLICATION_H__ */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 6b8f66719b..00b4aaa397 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -2646,10 +2646,14 @@ gtk_window_release_application (GtkWindow *window) { if (window->priv->application) { - g_application_release (G_APPLICATION (window->priv->application)); - g_object_unref (window->priv->application); + GtkApplication *application; + /* steal reference into temp variable */ + application = window->priv->application; window->priv->application = NULL; + + gtk_application_remove_window (application, window); + g_object_unref (application); } } @@ -2679,8 +2683,9 @@ gtk_window_set_application (GtkWindow *window, if (window->priv->application != NULL) { - g_application_hold (G_APPLICATION (window->priv->application)); g_object_ref (window->priv->application); + + gtk_application_add_window (window->priv->application, window); } g_object_notify (G_OBJECT (window), "application");