Commit 4f357dbf authored by Emmanuele Bassi's avatar Emmanuele Bassi

application: Allow sub-classes to override the Window creation

Sub-classes of GtkApplication might want to override the way an
application window is created - for instance, to hook into GtkBuilder
or to set up some basic UI or state.

A new GtkApplication::create_window() virtual function is added to the
GtkApplicationClass vtable, which returns the newly created GtkWindow.
The gtk_application_create_window() function calls the vfunc and adds
the returned window to the list of windows managed by the application
instance.

Calling gtk_application_add_window() will also set the default window,
if one is not already set.

This commit also removes a spurious g_object_ref_sink() on the newly
created GtkWindow.
parent b74fb44c
......@@ -262,6 +262,7 @@ gtk_alignment_set_padding
gtk_application_get_type G_GNUC_CONST
gtk_application_new
gtk_application_set_action_group
gtk_application_create_window
gtk_application_get_window
gtk_application_add_window
gtk_application_run
......
......@@ -171,7 +171,13 @@ gtk_application_default_action (GtkApplication *application,
gtk_action_activate (action);
}
}
static GtkWindow *
gtk_application_default_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,
......@@ -363,7 +369,12 @@ static gchar *default_title;
* behaviour is to call gtk_application_quit().
*
* If your application uses only a single toplevel window, you can
* use gtk_application_get_window().
* 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
*/
......@@ -371,13 +382,27 @@ void
gtk_application_add_window (GtkApplication *app,
GtkWindow *window)
{
app->priv->windows = g_slist_prepend (app->priv->windows, window);
GtkApplicationPrivate *priv;
g_return_if_fail (GTK_IS_APPLICATION (app));
g_return_if_fail (GTK_IS_WINDOW (window));
priv = app->priv;
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);
G_CALLBACK (gtk_application_on_window_destroy),
app);
}
/**
......@@ -396,7 +421,8 @@ gtk_application_add_window (GtkApplication *app,
* 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_add_window() instead.
* #GtkBuilder), use gtk_application_create_window() or
* gtk_application_add_window() instead.
*
* Returns: (transfer none): The default #GtkWindow for this application
*
......@@ -405,15 +431,45 @@ gtk_application_add_window (GtkApplication *app,
GtkWindow *
gtk_application_get_window (GtkApplication *app)
{
if (app->priv->default_window != NULL)
return app->priv->default_window;
GtkApplicationPrivate *priv;
GtkWindow *window;
g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL);
priv = app->priv;
if (priv->default_window != NULL)
return priv->default_window;
return gtk_application_create_window (app);
}
/**
* 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)
{
GtkWindow *window;
app->priv->default_window = GTK_WINDOW (gtk_window_new (GTK_WINDOW_TOPLEVEL));
g_object_ref_sink (app->priv->default_window);
g_return_val_if_fail (GTK_IS_APPLICATION (app), NULL);
gtk_application_add_window (app, app->priv->default_window);
window = GTK_APPLICATION_GET_CLASS (app)->create_window (app);
gtk_application_add_window (app, window);
return app->priv->default_window;
return window;
}
/**
......@@ -578,6 +634,7 @@ gtk_application_class_init (GtkApplicationClass *klass)
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;
......
......@@ -66,11 +66,12 @@ struct _GtkApplicationClass
GApplicationClass parent_class;
/*< vfuncs >*/
void (* activated) (GtkApplication *application,
GVariant *args);
void (* action) (GtkApplication *application,
const gchar *action_name);
gboolean (* quit) (GtkApplication *application);
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 */
......@@ -92,6 +93,7 @@ GtkApplication* gtk_application_new (const gchar *appid,
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);
void gtk_application_add_window (GtkApplication *app,
GtkWindow *window);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment