Optimize extension loading at startup

Only load modules in the list of active extensions and
get the remaining extensions when showing the dialog.
This commit is contained in:
Christian Dywan 2012-07-08 20:10:28 +02:00
parent 0c201ca2b8
commit 4073c14546
2 changed files with 145 additions and 110 deletions

View file

@ -255,7 +255,17 @@ settings_save_to_file (MidoriWebSettings* settings,
} }
g_free (pspecs); g_free (pspecs);
if (extensions) /* Take frozen list of active extensions until preferences reset it */
if ((_extensions = g_object_get_data (G_OBJECT (app), "extensions")))
{
i = 0;
while (_extensions[i])
{
g_key_file_set_boolean (key_file, "extensions", _extensions[i], TRUE);
i++;
}
}
else if (extensions)
{ {
KATZE_ARRAY_FOREACH_ITEM (extension, extensions) KATZE_ARRAY_FOREACH_ITEM (extension, extensions)
if (midori_extension_is_active (extension)) if (midori_extension_is_active (extension))
@ -279,16 +289,6 @@ settings_save_to_file (MidoriWebSettings* settings,
} }
g_object_unref (extensions); g_object_unref (extensions);
} }
else if ((_extensions = g_object_get_data (G_OBJECT (app), "extensions")))
{
i = 0;
while (_extensions[i])
{
g_key_file_set_boolean (key_file, "extensions", _extensions[i], TRUE);
i++;
}
}
saved = sokoke_key_file_save_to_file (key_file, filename, error); saved = sokoke_key_file_save_to_file (key_file, filename, error);
g_key_file_free (key_file); g_key_file_free (key_file);
return saved; return saved;
@ -548,15 +548,6 @@ settings_notify_cb (MidoriWebSettings* settings,
g_free (config_file); g_free (config_file);
} }
static void
extension_activate_cb (MidoriExtension* extension,
MidoriApp* app)
{
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
settings_notify_cb (settings, NULL, app);
g_object_unref (settings);
}
static void static void
accel_map_changed_cb (GtkAccelMap* accel_map, accel_map_changed_cb (GtkAccelMap* accel_map,
gchar* accel_path, gchar* accel_path,
@ -627,19 +618,51 @@ midori_trash_add_item_cb (KatzeArray* trash,
midori_trash_remove_item_cb (trash, item); midori_trash_remove_item_cb (trash, item);
} }
static void
midori_load_module (MidoriApp* app,
const gchar* extension_path,
const gchar* filename,
gboolean activate);
static void static void
midori_browser_show_preferences_cb (MidoriBrowser* browser, midori_browser_show_preferences_cb (MidoriBrowser* browser,
KatzePreferences* preferences, KatzePreferences* preferences,
MidoriApp* app) MidoriApp* app)
{ {
KatzeArray* array; KatzeArray* array;
gchar* extension_path;
GtkWidget* scrolled; GtkWidget* scrolled;
GtkWidget* addon; GtkWidget* addon;
GList* children; GList* children;
GtkWidget* page; GtkWidget* page;
/* Hide if there are no extensions at all */ if (!g_module_supported ())
return;
array = katze_object_get_object (app, "extensions"); array = katze_object_get_object (app, "extensions");
if ((extension_path = midori_app_get_lib_path (PACKAGE_NAME)))
{
GDir* extension_dir = NULL;
if ((extension_dir = g_dir_open (extension_path, 0, NULL)))
{
const gchar* filename;
while ((filename = g_dir_read_name (extension_dir)))
{
/* Ignore files which don't have the correct suffix */
if (!g_str_has_suffix (filename, G_MODULE_SUFFIX))
continue;
midori_load_module (app, extension_path, filename, FALSE);
}
g_dir_close (extension_dir);
}
g_free (extension_path);
}
/* Reset frozen list: allow active extensions to be saved */
g_object_set_data (G_OBJECT (app), "extensions", NULL);
/* Hide if there are no extensions at all */
if (!katze_array_get_nth_item (array, 0)) if (!katze_array_get_nth_item (array, 0))
{ {
g_object_unref (array); g_object_unref (array);
@ -1010,6 +1033,7 @@ static void
button_disable_extensions_clicked_cb (GtkWidget* button, button_disable_extensions_clicked_cb (GtkWidget* button,
MidoriApp* app) MidoriApp* app)
{ {
/* Reset frozen list of active extensions */
g_object_set_data (G_OBJECT (app), "extensions", NULL); g_object_set_data (G_OBJECT (app), "extensions", NULL);
gtk_widget_set_sensitive (button, FALSE); gtk_widget_set_sensitive (button, FALSE);
} }
@ -1166,49 +1190,110 @@ midori_load_soup_session_full (gpointer settings)
static void static void
midori_load_extension (MidoriApp* app, midori_load_extension (MidoriApp* app,
KatzeArray* extensions,
gchar** active_extensions,
MidoriExtension* extension, MidoriExtension* extension,
const gchar* filename) const gchar* filename)
{ {
KatzeArray* extensions = katze_object_get_object (app, "extensions");
/* Signal that we want the extension to load and save */ /* Signal that we want the extension to load and save */
g_object_set_data_full (G_OBJECT (extension), "filename", g_object_set_data_full (G_OBJECT (extension), "filename",
g_strdup (filename), g_free); g_strdup (filename), g_free);
if (midori_extension_is_prepared (extension)) if (midori_extension_is_prepared (extension))
midori_extension_get_config_dir (extension); midori_extension_get_config_dir (extension);
katze_array_add_item (extensions, extension); katze_array_add_item (extensions, extension);
if (active_extensions) g_object_unref (extensions);
}
static void
midori_load_module (MidoriApp* app,
const gchar* extension_path,
const gchar* filename,
gboolean activate)
{
gchar* fullname;
GModule* module;
typedef GObject* (*extension_init_func)(void);
extension_init_func extension_init;
GObject* extension = NULL;
static GHashTable* modules = NULL;
if (strchr (filename, '/'))
{ {
guint i = 0; gchar* clean = g_strndup (filename, strchr (filename, '/') - filename);
gchar* key; fullname = g_build_filename (extension_path, clean, NULL);
gchar* name; g_free (clean);
gchar* term;
key = katze_object_get_string (extension, "key");
if (key && *key)
term = g_strdup_printf ("%s/%s", filename, key);
else
term = g_strdup (filename);
while ((name = active_extensions[i++]))
if (!g_strcmp0 (term, name))
g_signal_emit_by_name (extension, "activate", app);
g_free (key);
g_free (term);
} }
g_signal_connect_after (extension, "activate", else
G_CALLBACK (extension_activate_cb), app); fullname = g_build_filename (extension_path, filename, NULL);
g_signal_connect_after (extension, "deactivate",
G_CALLBACK (extension_activate_cb), app); module = g_module_open (fullname, G_MODULE_BIND_LOCAL);
g_free (fullname);
/* GModule detects repeated loading but exposes no API to check it.
Skip any modules that were loaded before. */
if (modules == NULL)
modules = g_hash_table_new (g_direct_hash, g_direct_equal);
if (g_hash_table_contains (modules, module))
return;
g_hash_table_insert (modules, module, (gchar*)filename);
if (module && g_module_symbol (module, "extension_init",
(gpointer) &extension_init)
&& (extension = extension_init ()))
{
if (MIDORI_IS_EXTENSION (extension))
{
midori_load_extension (app, MIDORI_EXTENSION (extension), filename);
if (activate)
g_signal_emit_by_name (extension, "activate", app);
}
else if (KATZE_IS_ARRAY (extension))
{
MidoriExtension* extension_item;
KATZE_ARRAY_FOREACH_ITEM (extension_item, KATZE_ARRAY (extension))
if (MIDORI_IS_EXTENSION (extension_item))
{
gchar* key;
midori_load_extension (app, extension_item, filename);
if (activate)
{
key = katze_object_get_string (extension_item, "key");
if (key && strstr (filename, key))
g_signal_emit_by_name (extension_item, "activate", app);
g_free (key);
}
}
}
}
if (!extension && g_module_error () != NULL)
{
KatzeArray* extensions = katze_object_get_object (app, "extensions");
extension = g_object_new (MIDORI_TYPE_EXTENSION,
"name", filename,
"description", g_module_error (),
NULL);
g_warning ("%s", g_module_error ());
katze_array_add_item (extensions, extension);
g_object_unref (extensions);
}
g_object_unref (extension);
}
static void
extensions_update_cb (KatzeArray* extensions,
MidoriApp* app)
{
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
settings_notify_cb (settings, NULL, app);
g_object_unref (settings);
} }
static gboolean static gboolean
midori_load_extensions (gpointer data) midori_load_extensions (gpointer data)
{ {
MidoriApp* app = MIDORI_APP (data); MidoriApp* app = MIDORI_APP (data);
gchar** active_extensions = g_object_get_data (G_OBJECT (app), "extensions"); gchar** keys = g_object_get_data (G_OBJECT (app), "extensions");
KatzeArray* extensions; KatzeArray* extensions;
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
gboolean startup_timer = g_getenv ("MIDORI_STARTTIME") != NULL; gboolean startup_timer = g_getenv ("MIDORI_STARTTIME") != NULL;
@ -1217,79 +1302,21 @@ midori_load_extensions (gpointer data)
/* Load extensions */ /* Load extensions */
extensions = katze_array_new (MIDORI_TYPE_EXTENSION); extensions = katze_array_new (MIDORI_TYPE_EXTENSION);
g_signal_connect (extensions, "update", G_CALLBACK (extensions_update_cb), app);
g_object_set (app, "extensions", extensions, NULL); g_object_set (app, "extensions", extensions, NULL);
if (g_module_supported ()) if (g_module_supported ())
{ {
gchar* extension_path; gchar* extension_path;
GDir* extension_dir = NULL;
if ((extension_path = midori_app_get_lib_path (PACKAGE_NAME))) if ((extension_path = midori_app_get_lib_path (PACKAGE_NAME)))
extension_dir = g_dir_open (extension_path, 0, NULL);
if (extension_dir != NULL)
{ {
gint i = 0;
const gchar* filename; const gchar* filename;
while ((filename = keys[i++]))
while ((filename = g_dir_read_name (extension_dir))) midori_load_module (app, extension_path, filename, TRUE);
{
gchar* fullname;
GModule* module;
typedef GObject* (*extension_init_func)(void);
extension_init_func extension_init;
GObject* extension = NULL;
/* Ignore files which don't have the correct suffix */
if (!g_str_has_suffix (filename, G_MODULE_SUFFIX))
continue;
fullname = g_build_filename (extension_path, filename, NULL);
module = g_module_open (fullname, G_MODULE_BIND_LOCAL);
g_free (fullname);
if (module && g_module_symbol (module, "extension_init",
(gpointer) &extension_init))
{
extension = extension_init ();
if (extension != NULL)
{
if (MIDORI_IS_EXTENSION (extension))
midori_load_extension (app, extensions,
active_extensions,
MIDORI_EXTENSION (extension), filename);
else if (KATZE_IS_ARRAY (extension))
{
MidoriExtension* extension_item;
KATZE_ARRAY_FOREACH_ITEM (extension_item, KATZE_ARRAY (extension))
{
if (MIDORI_IS_EXTENSION (extension_item))
midori_load_extension (app, extensions,
active_extensions, extension_item,
filename);
}
}
}
}
if (!extension)
{
/* No extension, no error: not available, not shown */
if (g_module_error () == NULL)
continue;
extension = g_object_new (MIDORI_TYPE_EXTENSION,
"name", filename,
"description", g_module_error (),
NULL);
g_warning ("%s", g_module_error ());
katze_array_add_item (extensions, extension);
}
g_object_unref (extension);
}
g_dir_close (extension_dir);
} }
g_free (extension_path); g_free (extension_path);
} }
g_strfreev (active_extensions); g_strfreev (keys);
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
if (startup_timer) if (startup_timer)

View file

@ -304,13 +304,17 @@ midori_extensions_treeview_row_activated_cb (GtkTreeView* treeview,
if (gtk_tree_model_get_iter (model, &iter, path)) if (gtk_tree_model_get_iter (model, &iter, path))
{ {
MidoriExtension* extension; MidoriExtension* extension;
KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
gtk_tree_model_get (model, &iter, 0, &extension, -1); gtk_tree_model_get (model, &iter, 0, &extension, -1);
if (midori_extension_is_active (extension)) if (midori_extension_is_active (extension))
midori_extension_deactivate (extension); midori_extension_deactivate (extension);
else if (midori_extension_is_prepared (extension)) else if (midori_extension_is_prepared (extension))
g_signal_emit_by_name (extension, "activate", extensions->app); g_signal_emit_by_name (extension, "activate", extensions->app);
/* Make it easy for listeners to see that extensions changed */
katze_array_update (array);
g_object_unref (array);
g_object_unref (extension); g_object_unref (extension);
} }
} }
@ -327,13 +331,17 @@ midori_extensions_cell_renderer_toggled_cb (GtkCellRendererToggle* renderer,
if (gtk_tree_model_get_iter_from_string (model, &iter, path)) if (gtk_tree_model_get_iter_from_string (model, &iter, path))
{ {
MidoriExtension* extension; MidoriExtension* extension;
KatzeArray* array = katze_object_get_object (extensions->app, "extensions");
gtk_tree_model_get (model, &iter, 0, &extension, -1); gtk_tree_model_get (model, &iter, 0, &extension, -1);
if (midori_extension_is_active (extension)) if (midori_extension_is_active (extension))
midori_extension_deactivate (extension); midori_extension_deactivate (extension);
else if (midori_extension_is_prepared (extension)) else if (midori_extension_is_prepared (extension))
g_signal_emit_by_name (extension, "activate", extensions->app); g_signal_emit_by_name (extension, "activate", extensions->app);
/* Make it easy for listeners to see that extensions changed */
katze_array_update (array);
g_object_unref (array);
g_object_unref (extension); g_object_unref (extension);
} }
} }