application: Improve order of statup
This commit makes sure that logging is set before actually logging anything. It also sychronizes the application startup with the manager startup.
This commit is contained in:
+35
-19
@@ -336,8 +336,12 @@ gcal_application_activate (GApplication *application)
|
|||||||
static void
|
static void
|
||||||
gcal_application_startup (GApplication *app)
|
gcal_application_startup (GApplication *app)
|
||||||
{
|
{
|
||||||
|
GcalApplication *self;
|
||||||
|
|
||||||
GCAL_ENTRY;
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
self = GCAL_APPLICATION (app);
|
||||||
|
|
||||||
/* add actions */
|
/* add actions */
|
||||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||||
gcal_app_entries,
|
gcal_app_entries,
|
||||||
@@ -346,6 +350,20 @@ gcal_application_startup (GApplication *app)
|
|||||||
|
|
||||||
G_APPLICATION_CLASS (gcal_application_parent_class)->startup (app);
|
G_APPLICATION_CLASS (gcal_application_parent_class)->startup (app);
|
||||||
|
|
||||||
|
self->colors_provider = gtk_css_provider_new ();
|
||||||
|
self->weather_service = gcal_weather_service_new ();
|
||||||
|
|
||||||
|
/* Time format */
|
||||||
|
self->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||||
|
g_signal_connect_swapped (self->desktop_settings,
|
||||||
|
"changed::clock-format",
|
||||||
|
G_CALLBACK (load_time_format),
|
||||||
|
self);
|
||||||
|
load_time_format (self);
|
||||||
|
|
||||||
|
/* Startup the manager */
|
||||||
|
gcal_manager_startup (self->manager);
|
||||||
|
|
||||||
/* We're assuming the application is called as a service only by the shell search system */
|
/* We're assuming the application is called as a service only by the shell search system */
|
||||||
if ((g_application_get_flags (app) & G_APPLICATION_IS_SERVICE) != 0)
|
if ((g_application_get_flags (app) & G_APPLICATION_IS_SERVICE) != 0)
|
||||||
g_application_set_inactivity_timeout (app, 3 * 60 * 1000);
|
g_application_set_inactivity_timeout (app, 3 * 60 * 1000);
|
||||||
@@ -364,18 +382,17 @@ gcal_application_command_line (GApplication *app,
|
|||||||
const gchar* uuid = NULL;
|
const gchar* uuid = NULL;
|
||||||
gsize length;
|
gsize length;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
self = GCAL_APPLICATION (app);
|
self = GCAL_APPLICATION (app);
|
||||||
options = g_application_command_line_get_options_dict (command_line);
|
options = g_application_command_line_get_options_dict (command_line);
|
||||||
|
|
||||||
if (g_variant_dict_contains (options, "quit"))
|
if (g_variant_dict_contains (options, "quit"))
|
||||||
{
|
{
|
||||||
g_application_quit (app);
|
g_application_quit (app);
|
||||||
return 0;
|
GCAL_RETURN (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_variant_dict_contains (options, "debug"))
|
|
||||||
gcal_log_init ();
|
|
||||||
|
|
||||||
if (g_variant_dict_contains (options, "uuid"))
|
if (g_variant_dict_contains (options, "uuid"))
|
||||||
{
|
{
|
||||||
option = g_variant_dict_lookup_value (options, "uuid", G_VARIANT_TYPE_STRING);
|
option = g_variant_dict_lookup_value (options, "uuid", G_VARIANT_TYPE_STRING);
|
||||||
@@ -407,13 +424,17 @@ gcal_application_command_line (GApplication *app,
|
|||||||
|
|
||||||
g_application_activate (app);
|
g_application_activate (app);
|
||||||
|
|
||||||
return 0;
|
GCAL_RETURN (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
gcal_application_handle_local_options (GApplication *app,
|
gcal_application_handle_local_options (GApplication *app,
|
||||||
GVariantDict *options)
|
GVariantDict *options)
|
||||||
{
|
{
|
||||||
|
/* Initialize logging before anything else */
|
||||||
|
if (g_variant_dict_contains (options, "debug"))
|
||||||
|
gcal_log_init ();
|
||||||
|
|
||||||
if (show_version)
|
if (show_version)
|
||||||
{
|
{
|
||||||
g_print ("gnome-calendar: Version %s\n", PACKAGE_VERSION);
|
g_print ("gnome-calendar: Version %s\n", PACKAGE_VERSION);
|
||||||
@@ -432,17 +453,19 @@ gcal_application_dbus_register (GApplication *application,
|
|||||||
GcalApplication *self;
|
GcalApplication *self;
|
||||||
g_autofree gchar *search_provider_path = NULL;
|
g_autofree gchar *search_provider_path = NULL;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
self = GCAL_APPLICATION (application);
|
self = GCAL_APPLICATION (application);
|
||||||
|
|
||||||
if (!G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_register (application, connection, object_path, error))
|
if (!G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_register (application, connection, object_path, error))
|
||||||
return FALSE;
|
GCAL_RETURN (FALSE);
|
||||||
|
|
||||||
search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL);
|
search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL);
|
||||||
|
|
||||||
if (!gcal_shell_search_provider_dbus_export (self->search_provider, connection, search_provider_path, error))
|
if (!gcal_shell_search_provider_dbus_export (self->search_provider, connection, search_provider_path, error))
|
||||||
return FALSE;
|
GCAL_RETURN (FALSE);
|
||||||
|
|
||||||
return TRUE;
|
GCAL_RETURN (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -453,12 +476,16 @@ gcal_application_dbus_unregister (GApplication *application,
|
|||||||
GcalApplication *self;
|
GcalApplication *self;
|
||||||
g_autofree gchar *search_provider_path = NULL;
|
g_autofree gchar *search_provider_path = NULL;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
self = GCAL_APPLICATION (application);
|
self = GCAL_APPLICATION (application);
|
||||||
|
|
||||||
search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL);
|
search_provider_path = g_strconcat (object_path, "/SearchProvider", NULL);
|
||||||
gcal_shell_search_provider_dbus_unexport (self->search_provider, connection, search_provider_path);
|
gcal_shell_search_provider_dbus_unexport (self->search_provider, connection, search_provider_path);
|
||||||
|
|
||||||
G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_unregister (application, connection, object_path);
|
G_APPLICATION_CLASS (gcal_application_parent_class)->dbus_unregister (application, connection, object_path);
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -506,22 +533,11 @@ gcal_application_init (GcalApplication *self)
|
|||||||
{
|
{
|
||||||
g_application_add_main_option_entries (G_APPLICATION (self), gcal_application_goptions);
|
g_application_add_main_option_entries (G_APPLICATION (self), gcal_application_goptions);
|
||||||
|
|
||||||
self->colors_provider = gtk_css_provider_new ();
|
|
||||||
|
|
||||||
self->manager = gcal_manager_new ();
|
self->manager = gcal_manager_new ();
|
||||||
g_signal_connect_swapped (self->manager, "source-added", G_CALLBACK (process_sources), self);
|
g_signal_connect_swapped (self->manager, "source-added", G_CALLBACK (process_sources), self);
|
||||||
g_signal_connect_swapped (self->manager, "source-changed", G_CALLBACK (process_sources), self);
|
g_signal_connect_swapped (self->manager, "source-changed", G_CALLBACK (process_sources), self);
|
||||||
|
|
||||||
self->weather_service = gcal_weather_service_new ();
|
|
||||||
self->search_provider = gcal_shell_search_provider_new (self->manager);
|
self->search_provider = gcal_shell_search_provider_new (self->manager);
|
||||||
|
|
||||||
/* Time format */
|
|
||||||
self->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
|
||||||
g_signal_connect_swapped (self->desktop_settings,
|
|
||||||
"changed::clock-format",
|
|
||||||
G_CALLBACK (load_time_format),
|
|
||||||
self);
|
|
||||||
load_time_format (self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
+122
-129
@@ -769,134 +769,6 @@ gcal_manager_client_ready_cb (GObject *source,
|
|||||||
GCAL_EXIT;
|
GCAL_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gcal_manager_constructed (GObject *object)
|
|
||||||
{
|
|
||||||
GcalManager *self;
|
|
||||||
|
|
||||||
GList *sources, *l;
|
|
||||||
GError *error = NULL;
|
|
||||||
ESourceCredentialsProvider *credentials_provider;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (gcal_manager_parent_class)->constructed (object);
|
|
||||||
|
|
||||||
self = GCAL_MANAGER (object);
|
|
||||||
self->system_timezone = e_cal_util_get_system_timezone ();
|
|
||||||
|
|
||||||
self->clients = g_hash_table_new_full ((GHashFunc) e_source_hash, (GEqualFunc) e_source_equal,
|
|
||||||
g_object_unref, (GDestroyNotify) free_unit_data);
|
|
||||||
|
|
||||||
/* load GOA client */
|
|
||||||
goa_client_new (NULL, /* we won't really cancel it */
|
|
||||||
(GAsyncReadyCallback) gcal_manager_client_ready_cb,
|
|
||||||
object);
|
|
||||||
|
|
||||||
/* reading sources and schedule its connecting */
|
|
||||||
self->source_registry = e_source_registry_new_sync (NULL, &error);
|
|
||||||
|
|
||||||
if (!self->source_registry)
|
|
||||||
{
|
|
||||||
g_warning ("Failed to access calendar configuration: %s", error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_bind_property (self->source_registry,
|
|
||||||
"default-calendar",
|
|
||||||
self,
|
|
||||||
"default-calendar",
|
|
||||||
G_BINDING_DEFAULT);
|
|
||||||
|
|
||||||
self->credentials_prompter = e_credentials_prompter_new (self->source_registry);
|
|
||||||
|
|
||||||
/* First disable credentials prompt for all but calendar sources... */
|
|
||||||
sources = e_source_registry_list_sources (self->source_registry, NULL);
|
|
||||||
|
|
||||||
for (l = sources; l != NULL; l = g_list_next (l))
|
|
||||||
{
|
|
||||||
ESource *source = E_SOURCE (l->data);
|
|
||||||
|
|
||||||
/* Mark for skip also currently disabled sources */
|
|
||||||
if (!e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR) &&
|
|
||||||
!e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION))
|
|
||||||
{
|
|
||||||
e_credentials_prompter_set_auto_prompt_disabled_for (self->credentials_prompter, source, TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e_source_get_last_credentials_required_arguments (source,
|
|
||||||
NULL,
|
|
||||||
source_get_last_credentials_required_arguments_cb,
|
|
||||||
object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free_full (sources, g_object_unref);
|
|
||||||
|
|
||||||
credentials_provider = e_credentials_prompter_get_provider (self->credentials_prompter);
|
|
||||||
|
|
||||||
/* ...then enable credentials prompt for credential source of the calendar sources,
|
|
||||||
which can be a collection source. */
|
|
||||||
sources = e_source_registry_list_sources (self->source_registry, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
|
|
||||||
for (l = sources; l != NULL; l = g_list_next (l))
|
|
||||||
{
|
|
||||||
ESource *source, *cred_source;
|
|
||||||
|
|
||||||
source = l->data;
|
|
||||||
cred_source = e_source_credentials_provider_ref_credentials_source (credentials_provider, source);
|
|
||||||
|
|
||||||
if (cred_source && !e_source_equal (source, cred_source))
|
|
||||||
{
|
|
||||||
e_credentials_prompter_set_auto_prompt_disabled_for (self->credentials_prompter, cred_source, FALSE);
|
|
||||||
|
|
||||||
/* Only consider SSL errors */
|
|
||||||
if (e_source_get_connection_status (cred_source) != E_SOURCE_CONNECTION_STATUS_SSL_FAILED)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
e_source_get_last_credentials_required_arguments (cred_source,
|
|
||||||
NULL,
|
|
||||||
source_get_last_credentials_required_arguments_cb,
|
|
||||||
object);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_object (&cred_source);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free_full (sources, g_object_unref);
|
|
||||||
|
|
||||||
/* The eds_credentials_prompter responses to REQUIRED and REJECTED reasons,
|
|
||||||
the SSL_FAILED should be handled elsewhere. */
|
|
||||||
g_signal_connect (self->source_registry, "credentials-required", G_CALLBACK (source_credentials_required_cb), object);
|
|
||||||
|
|
||||||
e_credentials_prompter_process_awaiting_credentials (self->credentials_prompter);
|
|
||||||
|
|
||||||
g_signal_connect_swapped (self->source_registry, "source-added", G_CALLBACK (load_source), object);
|
|
||||||
g_signal_connect_swapped (self->source_registry, "source-removed", G_CALLBACK (remove_source), object);
|
|
||||||
g_signal_connect_swapped (self->source_registry, "source-changed", G_CALLBACK (source_changed), object);
|
|
||||||
|
|
||||||
/* create data model */
|
|
||||||
self->e_data_model = e_cal_data_model_new (submit_thread_job);
|
|
||||||
self->search_data_model = e_cal_data_model_new (submit_thread_job);
|
|
||||||
|
|
||||||
e_cal_data_model_set_expand_recurrences (self->e_data_model, TRUE);
|
|
||||||
e_cal_data_model_set_timezone (self->e_data_model, self->system_timezone);
|
|
||||||
e_cal_data_model_set_expand_recurrences (self->search_data_model, TRUE);
|
|
||||||
e_cal_data_model_set_timezone (self->search_data_model, self->system_timezone);
|
|
||||||
|
|
||||||
sources = e_source_registry_list_enabled (self->source_registry, E_SOURCE_EXTENSION_CALENDAR);
|
|
||||||
self->sources_at_launch = g_list_length (sources);
|
|
||||||
|
|
||||||
for (l = sources; l != NULL; l = l->next)
|
|
||||||
load_source (GCAL_MANAGER (object), l->data);
|
|
||||||
|
|
||||||
g_list_free (sources);
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gcal_manager_finalize (GObject *object)
|
gcal_manager_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
@@ -996,7 +868,6 @@ gcal_manager_class_init (GcalManagerClass *klass)
|
|||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
object_class->finalize = gcal_manager_finalize;
|
object_class->finalize = gcal_manager_finalize;
|
||||||
object_class->constructed = gcal_manager_constructed;
|
|
||||||
object_class->set_property = gcal_manager_set_property;
|
object_class->set_property = gcal_manager_set_property;
|
||||||
object_class->get_property = gcal_manager_get_property;
|
object_class->get_property = gcal_manager_get_property;
|
||||||
|
|
||||||
@@ -1095,6 +966,7 @@ gcal_manager_init (GcalManager *self)
|
|||||||
{
|
{
|
||||||
self->clock = gcal_clock_new ();
|
self->clock = gcal_clock_new ();
|
||||||
self->settings = g_settings_new ("org.gnome.calendar");
|
self->settings = g_settings_new ("org.gnome.calendar");
|
||||||
|
self->system_timezone = e_cal_util_get_system_timezone ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Public API */
|
/* Public API */
|
||||||
@@ -2070,3 +1942,124 @@ gcal_manager_get_goa_client (GcalManager *self)
|
|||||||
|
|
||||||
GCAL_RETURN (self->goa_client);
|
GCAL_RETURN (self->goa_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gcal_manager_startup (GcalManager *self)
|
||||||
|
{
|
||||||
|
GList *sources, *l;
|
||||||
|
GError *error = NULL;
|
||||||
|
ESourceCredentialsProvider *credentials_provider;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
self->clients = g_hash_table_new_full ((GHashFunc) e_source_hash, (GEqualFunc) e_source_equal,
|
||||||
|
g_object_unref, (GDestroyNotify) free_unit_data);
|
||||||
|
|
||||||
|
/* load GOA client */
|
||||||
|
goa_client_new (NULL, /* we won't really cancel it */
|
||||||
|
(GAsyncReadyCallback) gcal_manager_client_ready_cb,
|
||||||
|
self);
|
||||||
|
|
||||||
|
/* reading sources and schedule its connecting */
|
||||||
|
self->source_registry = e_source_registry_new_sync (NULL, &error);
|
||||||
|
|
||||||
|
if (!self->source_registry)
|
||||||
|
{
|
||||||
|
g_warning ("Failed to access calendar configuration: %s", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_bind_property (self->source_registry,
|
||||||
|
"default-calendar",
|
||||||
|
self,
|
||||||
|
"default-calendar",
|
||||||
|
G_BINDING_DEFAULT);
|
||||||
|
|
||||||
|
self->credentials_prompter = e_credentials_prompter_new (self->source_registry);
|
||||||
|
|
||||||
|
/* First disable credentials prompt for all but calendar sources... */
|
||||||
|
sources = e_source_registry_list_sources (self->source_registry, NULL);
|
||||||
|
|
||||||
|
for (l = sources; l != NULL; l = g_list_next (l))
|
||||||
|
{
|
||||||
|
ESource *source = E_SOURCE (l->data);
|
||||||
|
|
||||||
|
/* Mark for skip also currently disabled sources */
|
||||||
|
if (!e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR) &&
|
||||||
|
!e_source_has_extension (source, E_SOURCE_EXTENSION_COLLECTION))
|
||||||
|
{
|
||||||
|
e_credentials_prompter_set_auto_prompt_disabled_for (self->credentials_prompter, source, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e_source_get_last_credentials_required_arguments (source,
|
||||||
|
NULL,
|
||||||
|
source_get_last_credentials_required_arguments_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free_full (sources, g_object_unref);
|
||||||
|
|
||||||
|
credentials_provider = e_credentials_prompter_get_provider (self->credentials_prompter);
|
||||||
|
|
||||||
|
/* ...then enable credentials prompt for credential source of the calendar sources,
|
||||||
|
which can be a collection source. */
|
||||||
|
sources = e_source_registry_list_sources (self->source_registry, E_SOURCE_EXTENSION_CALENDAR);
|
||||||
|
|
||||||
|
for (l = sources; l != NULL; l = g_list_next (l))
|
||||||
|
{
|
||||||
|
ESource *source, *cred_source;
|
||||||
|
|
||||||
|
source = l->data;
|
||||||
|
cred_source = e_source_credentials_provider_ref_credentials_source (credentials_provider, source);
|
||||||
|
|
||||||
|
if (cred_source && !e_source_equal (source, cred_source))
|
||||||
|
{
|
||||||
|
e_credentials_prompter_set_auto_prompt_disabled_for (self->credentials_prompter, cred_source, FALSE);
|
||||||
|
|
||||||
|
/* Only consider SSL errors */
|
||||||
|
if (e_source_get_connection_status (cred_source) != E_SOURCE_CONNECTION_STATUS_SSL_FAILED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
e_source_get_last_credentials_required_arguments (cred_source,
|
||||||
|
NULL,
|
||||||
|
source_get_last_credentials_required_arguments_cb,
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_object (&cred_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free_full (sources, g_object_unref);
|
||||||
|
|
||||||
|
/* The eds_credentials_prompter responses to REQUIRED and REJECTED reasons,
|
||||||
|
the SSL_FAILED should be handled elsewhere. */
|
||||||
|
g_signal_connect (self->source_registry, "credentials-required", G_CALLBACK (source_credentials_required_cb), self);
|
||||||
|
|
||||||
|
e_credentials_prompter_process_awaiting_credentials (self->credentials_prompter);
|
||||||
|
|
||||||
|
g_signal_connect_swapped (self->source_registry, "source-added", G_CALLBACK (load_source), self);
|
||||||
|
g_signal_connect_swapped (self->source_registry, "source-removed", G_CALLBACK (remove_source), self);
|
||||||
|
g_signal_connect_swapped (self->source_registry, "source-changed", G_CALLBACK (source_changed), self);
|
||||||
|
|
||||||
|
/* create data model */
|
||||||
|
self->e_data_model = e_cal_data_model_new (submit_thread_job);
|
||||||
|
self->search_data_model = e_cal_data_model_new (submit_thread_job);
|
||||||
|
|
||||||
|
e_cal_data_model_set_expand_recurrences (self->e_data_model, TRUE);
|
||||||
|
e_cal_data_model_set_timezone (self->e_data_model, self->system_timezone);
|
||||||
|
e_cal_data_model_set_expand_recurrences (self->search_data_model, TRUE);
|
||||||
|
e_cal_data_model_set_timezone (self->search_data_model, self->system_timezone);
|
||||||
|
|
||||||
|
sources = e_source_registry_list_enabled (self->source_registry, E_SOURCE_EXTENSION_CALENDAR);
|
||||||
|
self->sources_at_launch = g_list_length (sources);
|
||||||
|
|
||||||
|
for (l = sources; l != NULL; l = l->next)
|
||||||
|
load_source (self, l->data);
|
||||||
|
|
||||||
|
g_list_free (sources);
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -133,7 +133,7 @@ gboolean gcal_manager_shell_search_done (GcalManager
|
|||||||
|
|
||||||
GList* gcal_manager_get_shell_search_events (GcalManager *self);
|
GList* gcal_manager_get_shell_search_events (GcalManager *self);
|
||||||
|
|
||||||
|
void gcal_manager_startup (GcalManager *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user