I'm following this tutorial. I'm currently at the Building applications part. There is one thing that baffles me, and that is how application window gets created in the first place. Let me explain.
This is how the program starts:
#include <gtk/gtk.h>
#include "exampleapp.h"
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (example_app_new ()), argc, argv);
}
This is easy. The application is started using g_application_run function. The function takes three arguments: an app, argument count and argument vector. Let's see how this app is created.
#include <gtk/gtk.h>
#include "exampleapp.h"
#include "exampleappwin.h"
struct _ExampleApp
{
GtkApplication parent;
};
G_DEFINE_TYPE(ExampleApp, example_app, GTK_TYPE_APPLICATION);
static void
example_app_init (ExampleApp *app)
{
}
static void
example_app_activate (GApplication *app)
{
ExampleAppWindow *win;
win = example_app_window_new (EXAMPLE_APP (app));
gtk_window_present (GTK_WINDOW (win));
}
static void
example_app_open (GApplication *app,
GFile **files,
gint n_files,
const gchar *hint)
{
GList *windows;
ExampleAppWindow *win;
int i;
windows = gtk_application_get_windows (GTK_APPLICATION (app));
if (windows)
win = EXAMPLE_APP_WINDOW (windows->data);
else
win = example_app_window_new (EXAMPLE_APP (app));
for (i = 0; i < n_files; i++)
example_app_window_open (win, files[i]);
gtk_window_present (GTK_WINDOW (win));
}
static void
example_app_class_init (ExampleAppClass *class)
{
G_APPLICATION_CLASS (class)->activate = example_app_activate;
G_APPLICATION_CLASS (class)->open = example_app_open;
}
ExampleApp *
example_app_new (void)
{
return g_object_new (EXAMPLE_APP_TYPE,
"application-id", "org.gtk.exampleapp",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}
The line G_DEFINE_TYPE(ExampleApp, example_app, GTK_TYPE_APPLICATION); aliases ExampleApp to GtkApplication (but in a smart way, such that types, variables, etc. associated with GtkApplication are now associated with ExampleApp).
Let's now take a look at ExampleApp *example_app_new(void) function. This function actually returns GtkApplication *, since we associated ExampleApp with GtkApplication. Next, this function calls and returns a new object by calling g_object_new function. That function takes the following arguments:
EXAMPLE_APP_TYPE, which is justGTK_TYPE_APPLICATION"application-id", which tells that the next argument is the ID of an applicaton"org.gtk.exampleapp", the ID"flags", which tells that the next argument is a flag"G_APPLICATION_HANDLES_OPEN", a flagNULL, terminator
g_object_new, called like this, returns GtkApplication with the ID of "org.gtk.exampleapp" and with a flag "G_APPLICATION_HANDLES_OPEN". After the program goes back to example_app_new, it exits it and returns a new object of type ExampleApp * A.K.A. GtkApplication * to main. The new app is cast to GApplication in g_application_run using G_APPLICATION macro.
You have now seen what I understand. Now you'll see what I don't understand.
The tutorial linked at the top of this question says that this creates an empty window. In earlier parts of the tutorial (like this one) we used g_signal_connect to call a function when an app is run. For example,
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
calls the function activate when the app app is run using g_application_run. Function activate will in turn usually create a window and populate it either by itself or by calling other functions. That is what baffles me: there is no such thing in our example app program. How then a window gets created?