diff --git a/cog.c b/cog.c index 3357ae44..bf3f97ce 100644 --- a/cog.c +++ b/cog.c @@ -27,6 +27,7 @@ enum webprocess_fail_action { static struct { char *home_uri; + char *config_file; gboolean version; gboolean print_appid; gboolean doc_viewer; @@ -71,6 +72,9 @@ static GOptionEntry s_cli_options[] = &s_options.on_failure.action_name, "Action on WebProcess failures: error-page (default), exit, exit-ok, restart.", "ACTION" }, + { "config", 'C', 0, G_OPTION_ARG_FILENAME, &s_options.config_file, + "Path to a configuration file", + "PATH" }, #if !COG_USE_WEBKITGTK { "platform", 'P', 0, G_OPTION_ARG_STRING, &s_options.platform_name, "Platform plug-in to use.", @@ -82,6 +86,23 @@ static GOptionEntry s_cli_options[] = }; +static gboolean +load_settings (CogShell *shell, GKeyFile *key_file, GError **error) +{ + if (g_key_file_has_group (key_file, "websettings")) { + WebKitSettings *settings = cog_shell_get_web_settings (shell); + if (!cog_webkit_settings_apply_from_key_file (settings, + key_file, + "websettings", + error)) { + return FALSE; + } + } + + return TRUE; +} + + static int string_to_webprocess_fail_action (const char *action) { @@ -201,6 +222,31 @@ on_handle_local_options (GApplication *application, s_options.home_uri = g_steal_pointer (&utf8_uri); + if (s_options.config_file) { + g_autoptr(GFile) file = + g_file_new_for_commandline_arg (s_options.config_file); + g_autofree char *config_file_path = g_file_get_path (file); + + if (!g_file_query_exists (file, NULL)) { + g_printerr ("%s: File does not exist: %s\n", + g_get_prgname (), config_file_path); + return EXIT_FAILURE; + } + + g_autoptr(GError) error = NULL; + g_autoptr(GKeyFile) key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, + config_file_path, + G_KEY_FILE_NONE, + &error) || + !load_settings (shell, key_file, &error)) + { + g_printerr ("%s: Cannot load configuration file: %s\n", + g_get_prgname (), error->message); + return EXIT_FAILURE; + } + } + return -1; /* Continue startup. */ } diff --git a/core/cog-webkit-utils.c b/core/cog-webkit-utils.c index b7a62d98..99a79981 100644 --- a/core/cog-webkit-utils.c +++ b/core/cog-webkit-utils.c @@ -305,3 +305,87 @@ cog_web_view_connect_default_progress_handlers (WebKitWebView *web_view) for (unsigned i = 0; i < G_N_ELEMENTS (handlers); i++) g_signal_connect (web_view, handlers[i].sig, handlers[i].hnd, NULL); } + + +gboolean +cog_webkit_settings_apply_from_key_file (WebKitSettings *settings, + GKeyFile *key_file, + const char *group, + GError **error) +{ + g_return_val_if_fail (WEBKIT_IS_SETTINGS (settings), FALSE); + g_return_val_if_fail (key_file != NULL, FALSE); + + GObjectClass* object_class = G_OBJECT_GET_CLASS (settings); + + unsigned n_properties = 0; + g_autofree GParamSpec* const* properties = + g_object_class_list_properties (object_class, &n_properties); + + for (unsigned i = 0; i < n_properties; i++) { + g_autoptr(GError) lookup_error = NULL; + if (!g_key_file_has_key (key_file, + group, + properties[i]->name, + &lookup_error)) { + if (lookup_error) { + g_propagate_error (error, g_steal_pointer (&lookup_error)); + return FALSE; + } + continue; // Setting missing in GKeyFile, skip it. + } + + const GType prop_type = G_PARAM_SPEC_VALUE_TYPE (properties[i]); + switch (prop_type) { + case G_TYPE_BOOLEAN: { + gboolean value = g_key_file_get_boolean (key_file, + group, + properties[i]->name, + &lookup_error); + if (!value && lookup_error) { + g_propagate_error (error, g_steal_pointer (&lookup_error)); + return FALSE; + } + g_object_set (settings, properties[i]->name, value, NULL); + break; + } + + case G_TYPE_UINT: { + guint64 value = g_key_file_get_uint64 (key_file, + group, + properties[i]->name, + &lookup_error); + if (value == 0 && lookup_error) { + g_propagate_error (error, g_steal_pointer (&lookup_error)); + return FALSE; + } else if (value > G_MAXUINT) { + g_set_error (error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + "Value for '%s' exceeds maximum integer size", + properties[i]->name); + return FALSE; + } + g_object_set (settings, properties[i]->name, (guint) value, NULL); + break; + } + + case G_TYPE_STRING: { + g_autofree char* value = + g_key_file_get_string (key_file, + group, + properties[i]->name, + &lookup_error); + if (!value) { + g_assert_nonnull (lookup_error); + g_propagate_error (error, g_steal_pointer (&lookup_error)); + return FALSE; + } + g_object_set (settings, properties[i]->name, value, NULL); + break; + } + } + } + + return TRUE; +} diff --git a/core/cog-webkit-utils.h b/core/cog-webkit-utils.h index d7448c50..1a0c23fa 100644 --- a/core/cog-webkit-utils.h +++ b/core/cog-webkit-utils.h @@ -76,4 +76,9 @@ void cog_handle_web_view_load_changed (WebKitWebView *web_view, void cog_web_view_connect_default_progress_handlers (WebKitWebView *web_view); +gboolean cog_webkit_settings_apply_from_key_file (WebKitSettings *settings, + GKeyFile *key_file, + const char *group, + GError **error); + G_END_DECLS