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");