diff options
author | Adam Hooper <adamh@src.gnome.org> | 2004-09-14 05:52:00 +0800 |
---|---|---|
committer | Adam Hooper <adamh@src.gnome.org> | 2004-09-14 05:52:00 +0800 |
commit | 809f1aca44d03364d59d33780684ad8c524a0025 (patch) | |
tree | 7bef6e9dc63f82fc2b9318ad1acbaa5f915e979c | |
parent | 25a80e3d76c1c74e810271f0cf46832f7b6e127d (diff) | |
download | gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.gz gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.bz2 gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.lz gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.xz gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.tar.zst gsoc2013-epiphany-809f1aca44d03364d59d33780684ad8c524a0025.zip |
Load/unload extensions based on GConf key
/apps/epiphany/general/active_extensions.
Update documentation a bit (i.e., make sure it actually builds).
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | data/epiphany.schemas.in | 13 | ||||
-rw-r--r-- | doc/reference/Makefile.am | 2 | ||||
-rw-r--r-- | doc/reference/epiphany-docs.sgml | 1 | ||||
-rw-r--r-- | doc/reference/epiphany-sections.txt | 19 | ||||
-rw-r--r-- | doc/reference/epiphany.types | 2 | ||||
-rw-r--r-- | doc/reference/tmpl/ephy-embed-factory.sgml | 4 | ||||
-rw-r--r-- | doc/reference/tmpl/ephy-embed.sgml | 8 | ||||
-rw-r--r-- | doc/reference/tmpl/ephy-extensions-manager.sgml | 63 | ||||
-rw-r--r-- | doc/reference/tmpl/ephy-shell.sgml | 10 | ||||
-rw-r--r-- | doc/reference/tmpl/ephy-window.sgml | 1 | ||||
-rw-r--r-- | doc/reference/tmpl/epiphany-unused.sgml | 8 | ||||
-rw-r--r-- | lib/ephy-module-loader.c | 20 | ||||
-rw-r--r-- | lib/ephy-module-loader.h | 2 | ||||
-rw-r--r-- | src/ephy-extensions-manager.c | 350 | ||||
-rw-r--r-- | src/ephy-extensions-manager.h | 5 | ||||
-rw-r--r-- | src/ephy-shell.c | 6 |
17 files changed, 472 insertions, 78 deletions
@@ -1,3 +1,39 @@ +2004-09-13 Adam Hooper <adamh@cvs.gnome.org> + + * data/epiphany.schemas.in: + * doc/reference/Makefile.am: + * doc/reference/epiphany-docs.sgml: + * doc/reference/epiphany-sections.txt: + * doc/reference/epiphany.types: + * doc/reference/tmpl/ephy-embed-factory.sgml: + * doc/reference/tmpl/ephy-embed.sgml: + * doc/reference/tmpl/ephy-extensions-manager.sgml: + * doc/reference/tmpl/ephy-shell.sgml: + * doc/reference/tmpl/ephy-window.sgml: + * doc/reference/tmpl/epiphany-unused.sgml: + * lib/ephy-module-loader.c: (ephy_module_loader_new), + (ephy_module_loader_load), (ephy_module_loader_unload), + (ephy_module_loader_get_path): + * lib/ephy-module-loader.h: + * src/ephy-extensions-manager.c: (free_ext_info), + (windows_foreach), (attach_window), (detach_window), + (instantiate_extension), (real_load), + (ephy_extensions_manager_load), (real_unload), + (ephy_extensions_manager_unload), (ephy_extensions_manager_add), + (sync_one_extension), (ephy_extensions_manager_sync_gconf), + (ephy_extensions_manager_load_file), + (ephy_extensions_manager_load_dir), (active_extensions_notifier), + (ephy_extensions_manager_init), (ephy_extensions_manager_finalize), + (attach_window_to_info), (impl_attach_window), + (detach_window_from_info), (impl_detach_window): + * src/ephy-extensions-manager.h: + * src/ephy-shell.c: (ephy_shell_get_extensions_manager): + + Load/unload extensions based on GConf key + /apps/epiphany/general/active_extensions. + + Update documentation a bit (i.e., make sure it actually builds). + 2004-09-13 Christian Persch <chpe@cvs.gnome.org> * data/art/epiphany-entry.png: diff --git a/data/epiphany.schemas.in b/data/epiphany.schemas.in index 2ad9a52d4..2012d136d 100644 --- a/data/epiphany.schemas.in +++ b/data/epiphany.schemas.in @@ -191,6 +191,19 @@ </locale> </schema> <schema> + <key>/schemas/apps/epiphany/general/active_extensions</key> + <applyto>/apps/epiphany/general/active_extensions</applyto> + <owner>epiphany</owner> + <type>list</type> + <list_type>string</list_type> + <locale name="C"> + <short>Loaded extensions</short> + <long>Partial filenames of extensions to load. For example, if a desired + extension's filename is "libgesturesextension.so", add "gestures" to the + list.</long> + </locale> + </schema> + <schema> <key>/schemas/apps/epiphany/web/default_encoding</key> <applyto>/apps/epiphany/web/default_encoding</applyto> <owner>epiphany</owner> diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am index 6abd91db5..1b50546fe 100644 --- a/doc/reference/Makefile.am +++ b/doc/reference/Makefile.am @@ -52,7 +52,6 @@ IGNORE_HFILES = \ ephy-thread-helpers.h \ ephy-zoom.h \ ephy-arrow-toolbutton.h \ - ephy-cell-renderer-progress.h \ ephy-label.h \ ephy-location-entry.h \ ephy-node-view.h \ @@ -123,7 +122,6 @@ IGNORE_HFILES = \ ephy-encoding-dialog.h \ ephy-encoding-menu.h \ ephy-extension.h \ - ephy-extensions-manager.h \ ephy-favicon-action.h \ ephy-favorites-menu.h \ ephy-go-action.h \ diff --git a/doc/reference/epiphany-docs.sgml b/doc/reference/epiphany-docs.sgml index 77f21f012..ba3b13b3c 100644 --- a/doc/reference/epiphany-docs.sgml +++ b/doc/reference/epiphany-docs.sgml @@ -18,6 +18,7 @@ <xi:include href="xml/ephy-embed-factory.xml"/> <xi:include href="xml/ephy-node-db.xml"/> <xi:include href="xml/ephy-glade.xml"/> + <xi:include href="xml/ephy-extensions-manager.xml"/> </chapter> <chapter> <title>Incomplete</title> diff --git a/doc/reference/epiphany-sections.txt b/doc/reference/epiphany-sections.txt index 94f6edfa3..5945524ce 100644 --- a/doc/reference/epiphany-sections.txt +++ b/doc/reference/epiphany-sections.txt @@ -235,6 +235,25 @@ EPHY_NODE_DB_GET_CLASS ephy_glade_widget_new </SECTION> +<SECTION> +<FILE>ephy-extensions-manager</FILE> +<TITLE>EphyExtensionsManager</TITLE> +ephy_extensions_manager_new +ephy_extensions_manager_load +ephy_extensions_manager_unload +ephy_extensions_manager_load_dir +ephy_extensions_manager_add +ephy_extensions_manager_list +<SUBSECTION Standard> +EPHY_EXTENSIONS_MANAGER +EPHY_IS_EXTENSIONS_MANAGER +EPHY_TYPE_EXTENSIONS_MANAGER +ephy_extensions_manager_get_type +EPHY_EXTENSIONS_MANAGER_CLASS +EPHY_IS_EXTENSIONS_MANAGER_CLASS +EPHY_EXTENSIONS_MANAGER_GET_CLASS +</SECTION> + <SECTION> diff --git a/doc/reference/epiphany.types b/doc/reference/epiphany.types index 58dd8ba78..530f82969 100644 --- a/doc/reference/epiphany.types +++ b/doc/reference/epiphany.types @@ -6,7 +6,6 @@ #include <ephy-location-entry.h> #include <ephy-zoom-action.h> #include <ephy-zoom-control.h> -#include <ephy-cell-renderer-progress.h> ephy_dialog_get_type ephy_file_chooser_get_type @@ -16,7 +15,6 @@ ephy_node_filter_get_type ephy_location_entry_get_type ephy_zoom_action_get_type ephy_zoom_control_get_type -ephy_cell_renderer_progress_get_type #include <ephy-embed.h> #include <downloader-view.h> diff --git a/doc/reference/tmpl/ephy-embed-factory.sgml b/doc/reference/tmpl/ephy-embed-factory.sgml index f80295416..556730839 100644 --- a/doc/reference/tmpl/ephy-embed-factory.sgml +++ b/doc/reference/tmpl/ephy-embed-factory.sgml @@ -25,7 +25,9 @@ To create a new instance of an #EphyEmbed, #EphyEmbedPersist or </para> -@object_id: +@type: @Returns: +<!-- # Unused Parameters # --> +@object_id: diff --git a/doc/reference/tmpl/ephy-embed.sgml b/doc/reference/tmpl/ephy-embed.sgml index 8688721b1..da9a9e933 100644 --- a/doc/reference/tmpl/ephy-embed.sgml +++ b/doc/reference/tmpl/ephy-embed.sgml @@ -146,6 +146,14 @@ be done by casting). @: @: @: +@: +@: +@: +@: +@: +@: +@: +@: @: <!-- ##### SIGNAL EphyEmbed::ge-security-change ##### --> diff --git a/doc/reference/tmpl/ephy-extensions-manager.sgml b/doc/reference/tmpl/ephy-extensions-manager.sgml new file mode 100644 index 000000000..418123132 --- /dev/null +++ b/doc/reference/tmpl/ephy-extensions-manager.sgml @@ -0,0 +1,63 @@ +<!-- ##### SECTION Title ##### --> +EphyExtensionsManager + +<!-- ##### SECTION Short_Description ##### --> + + +<!-- ##### SECTION Long_Description ##### --> +<para> + +</para> + +<!-- ##### SECTION See_Also ##### --> +<para> + +</para> + +<!-- ##### FUNCTION ephy_extensions_manager_new ##### --> +<para> + +</para> + +@Returns: + + +<!-- ##### FUNCTION ephy_extensions_manager_load ##### --> +<para> + +</para> + +@manager: +@filename: +<!-- # Unused Parameters # --> +@Returns: + + +<!-- ##### FUNCTION ephy_extensions_manager_unload ##### --> +<para> + +</para> + +@manager: +@filename: + + +<!-- ##### FUNCTION ephy_extensions_manager_load_dir ##### --> +<para> + +</para> + +@manager: +@path: + + +<!-- ##### FUNCTION ephy_extensions_manager_add ##### --> +<para> + +</para> + +@manager: +@type: +@Returns: + + diff --git a/doc/reference/tmpl/ephy-shell.sgml b/doc/reference/tmpl/ephy-shell.sgml index 6c9e8b68d..570c6a038 100644 --- a/doc/reference/tmpl/ephy-shell.sgml +++ b/doc/reference/tmpl/ephy-shell.sgml @@ -48,7 +48,6 @@ ephy-shell @EPHY_SHELL_STARTUP_SESSION: @EPHY_SHELL_STARTUP_IMPORT_BOOKMARKS: @EPHY_SHELL_STARTUP_ADD_BOOKMARK: -@EPHY_SHELL_STARTUP_SERVER: <!-- ##### ENUM EphyNewTabFlags ##### --> <para> @@ -94,15 +93,6 @@ ephy-shell @Returns: -<!-- ##### FUNCTION ephy_shell_get_active_window ##### --> -<para> - -</para> - -@shell: -@Returns: - - <!-- ##### FUNCTION ephy_shell_new_tab ##### --> <para> diff --git a/doc/reference/tmpl/ephy-window.sgml b/doc/reference/tmpl/ephy-window.sgml index b831ebbe8..218477bd6 100644 --- a/doc/reference/tmpl/ephy-window.sgml +++ b/doc/reference/tmpl/ephy-window.sgml @@ -33,7 +33,6 @@ These are restricted to ephy_window_set_zoom() and ephy_window_load_url(). </para> -@ui_merge: The #GtkUIManager this window uses to merge user interfaces <!-- ##### ARG EphyWindow:active-tab ##### --> <para> diff --git a/doc/reference/tmpl/epiphany-unused.sgml b/doc/reference/tmpl/epiphany-unused.sgml index aa9f02d89..1dfbb6967 100644 --- a/doc/reference/tmpl/epiphany-unused.sgml +++ b/doc/reference/tmpl/epiphany-unused.sgml @@ -154,6 +154,14 @@ mozilla-embed-event @path: @gs: +<!-- ##### FUNCTION ephy_shell_get_active_window ##### --> +<para> + +</para> + +@shell: +@Returns: + <!-- ##### FUNCTION ephy_tab_get_window ##### --> <para> diff --git a/lib/ephy-module-loader.c b/lib/ephy-module-loader.c index 99c452927..2cd72fd89 100644 --- a/lib/ephy-module-loader.c +++ b/lib/ephy-module-loader.c @@ -96,13 +96,6 @@ ephy_module_loader_new (const char *path) g_type_module_set_name (G_TYPE_MODULE (result), path); result->path = g_strdup (path); - if (!g_type_module_use (G_TYPE_MODULE (result))) - { - g_object_unref (result); - - return NULL; - } - return result; } @@ -110,14 +103,11 @@ static gboolean ephy_module_loader_load (GTypeModule *module) { EphyModuleLoader *loader = EPHY_MODULE_LOADER (module); - char *module_path; register_module_fn register_module; LOG ("ephy_module_loader_load %s", loader->path) - module_path = g_strdup (loader->path); - loader->library = g_module_open (module_path, 0); - g_free (module_path); + loader->library = g_module_open (loader->path, 0); if (!loader->library) { @@ -159,6 +149,14 @@ ephy_module_loader_unload (GTypeModule *module) loader->type = 0; } +const char * +ephy_module_loader_get_path (EphyModuleLoader *loader) +{ + g_return_val_if_fail (EPHY_IS_MODULE_LOADER (loader), NULL); + + return loader->path; +} + static void ephy_module_loader_class_init (EphyModuleLoaderClass *class) { diff --git a/lib/ephy-module-loader.h b/lib/ephy-module-loader.h index 6b5b29a66..fe25712a7 100644 --- a/lib/ephy-module-loader.h +++ b/lib/ephy-module-loader.h @@ -38,6 +38,8 @@ GType ephy_module_loader_get_type (void); EphyModuleLoader *ephy_module_loader_new (const char *path); +const char *ephy_module_loader_get_path (EphyModuleLoader *loader); + GObject *ephy_module_loader_factory (EphyModuleLoader *loader); G_END_DECLS diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c index f8e283e09..7b66f289e 100644 --- a/src/ephy-extensions-manager.c +++ b/src/ephy-extensions-manager.c @@ -25,20 +25,34 @@ #include "ephy-extensions-manager.h" +#include "ephy-shell.h" +#include "ephy-session.h" /* Weird (session is an extension) but it works */ #include "ephy-module-loader.h" #include "ephy-debug.h" +#include "eel-gconf-extensions.h" + #include <gmodule.h> #include <dirent.h> +#include <string.h> + +#define CONF_LOADED_EXTENSIONS "/apps/epiphany/general/active_extensions" #define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate)) struct EphyExtensionsManagerPrivate { - GSList *loaders; - GSList *extensions; + GHashTable *extensions; + GSList *internal_extensions; + guint active_extensions_notifier_id; }; +typedef struct +{ + EphyModuleLoader *loader; /* NULL if never loaded */ + EphyExtension *extension; /* NULL if unloaded */ +} ExtInfo; + static GObjectClass *parent_class = NULL; static void ephy_extensions_manager_class_init (EphyExtensionsManagerClass *klass); @@ -84,9 +98,47 @@ ephy_extensions_manager_get_type (void) return type; } +static void +free_ext_info (ExtInfo *info) +{ + if (info->extension) + { + g_object_unref (info->extension); + } + g_free (info); +} + +static void +windows_foreach (GFunc func, EphyExtension *extension) +{ + EphySession *session; + GList *windows; + + session = EPHY_SESSION (ephy_shell_get_session (ephy_shell)); + + windows = ephy_session_get_windows (session); + + g_list_foreach (windows, func, extension); + + g_list_free (windows); +} + +static void +attach_window (EphyWindow *window, + EphyExtension *extension) +{ + ephy_extension_attach_window (extension, window); +} + +static void +detach_window (EphyWindow *window, + EphyExtension *extension) +{ + ephy_extension_detach_window (extension, window); +} + static EphyExtension * -ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager, - EphyModuleLoader *loader) +instantiate_extension (EphyModuleLoader *loader) { EphyExtension *extension; @@ -94,8 +146,7 @@ ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager, if (EPHY_IS_EXTENSION (extension)) { - manager->priv->extensions = - g_slist_append (manager->priv->extensions, extension); + windows_foreach ((GFunc) attach_window, extension); return extension; } @@ -103,59 +154,116 @@ ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager, return NULL; } -EphyExtension * -ephy_extensions_manager_load (EphyExtensionsManager *manager, - const char *filename) +static void +real_load (ExtInfo *info) { - EphyExtension *extension = NULL; + if (info->extension != NULL) return; - if (g_str_has_suffix (filename, G_MODULE_SUFFIX)) + if (g_type_module_use (G_TYPE_MODULE (info->loader)) == FALSE) { - EphyModuleLoader *loader; - - loader = ephy_module_loader_new (filename); - - if (loader != NULL) - { - manager->priv->loaders = - g_slist_prepend (manager->priv->loaders, loader); + g_warning ("Could not load extension file at %s\n", + ephy_module_loader_get_path (info->loader)); + return; + } - extension = ephy_extensions_manager_instantiate_extension - (manager, loader); + info->extension = instantiate_extension (info->loader); - g_type_module_unuse (G_TYPE_MODULE (loader)); - } + if (info->extension == NULL) + { + g_warning ("Could not load extension at %s\n", + ephy_module_loader_get_path (info->loader)); } - return extension; + g_type_module_unuse (G_TYPE_MODULE (info->loader)); } +/** + * ephy_extensions_manager_load: + * @manager: an #EphyExtensionsManager + * @filename: filename of an extension to load, minus "lib" and "extension.so" + * + * Loads the @filename extension. + **/ void -ephy_extensions_manager_load_dir (EphyExtensionsManager *manager, - const char *path) +ephy_extensions_manager_load (EphyExtensionsManager *manager, + const char *filename) { - DIR *d; - struct dirent *e; + GSList *gconf_exts; - d = opendir (path); - if (d == NULL) + gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS); + + if (!g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp)) { - return; + gconf_exts = g_slist_prepend (gconf_exts, g_strdup (filename)); + + eel_gconf_set_string_list (CONF_LOADED_EXTENSIONS, gconf_exts); } - while ((e = readdir (d)) != NULL) - { - char *filename; + g_slist_foreach (gconf_exts, (GFunc) g_free, NULL); + g_slist_free (gconf_exts); +} - filename = g_build_filename (path, e->d_name, NULL); +static void +real_unload (ExtInfo *info) +{ + if (info->extension == NULL) return; /* not loaded */ - ephy_extensions_manager_load (manager, filename); + windows_foreach ((GFunc) detach_window, info->extension); - g_free (filename); + /* + * Only unref the extension in the idle loop; if the extension has its + * own functions queued in the idle loop, the functions must exist in + * memory before being called. + */ + g_idle_add ((GSourceFunc) g_object_unref, info->extension); + info->extension = NULL; +} + +/** + * ephy_extensions_manager_unload: + * @manager: an #EphyExtensionsManager + * @filename: filename of extension to unload, minus "lib" and "extension.so" + * + * Unloads the extension specified by @filename. + * + * The extension with the same filename can afterwards be reloaded. However, + * if any GTypes within the extension have changed parent types, Epiphany must + * be restarted. + **/ +void +ephy_extensions_manager_unload (EphyExtensionsManager *manager, + const char *filename) +{ + GSList *gconf_exts; + GSList *l; + + gconf_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS); + + l = g_slist_find_custom (gconf_exts, filename, (GCompareFunc) strcmp); + + if (l != NULL) + { + gconf_exts = g_slist_remove_link (gconf_exts, l); + g_free (l->data); + g_slist_free_1 (l); + + eel_gconf_set_string_list (CONF_LOADED_EXTENSIONS, gconf_exts); } - closedir (d); + + g_slist_foreach (gconf_exts, (GFunc) g_free, NULL); + g_slist_free (gconf_exts); } +/** + * ephy_extensions_manager_add: + * @manager: an #EphyExtensionsManager + * @type: GType of the extension to add + * + * Creates a new instance of @type (which must be an #EphyExtension) and adds + * it to @manager. This is only used to load internal Epiphany extensions. + * + * Return value: a new instance of @type + **/ EphyExtension * ephy_extensions_manager_add (EphyExtensionsManager *manager, GType type) @@ -172,21 +280,135 @@ ephy_extensions_manager_add (EphyExtensionsManager *manager, return NULL; } - manager->priv->extensions = - g_slist_append (manager->priv->extensions, extension); + manager->priv->internal_extensions = + g_slist_append (manager->priv->internal_extensions, extension); return extension; } static void +sync_one_extension (const char *name, + ExtInfo *info, + GSList *wanted_exts) +{ + if (g_slist_find_custom (wanted_exts, name, (GCompareFunc) strcmp)) + { + real_load (info); + } + else + { + real_unload (info); + } +} + +static void +ephy_extensions_manager_sync_gconf (EphyExtensionsManager *manager) +{ + GSList *wanted_exts; + + wanted_exts = eel_gconf_get_string_list (CONF_LOADED_EXTENSIONS); + + g_hash_table_foreach (manager->priv->extensions, + (GHFunc) sync_one_extension, + wanted_exts); + + g_slist_foreach (wanted_exts, (GFunc) g_free, NULL); + g_slist_free (wanted_exts); +} + +static void +ephy_extensions_manager_load_file (EphyExtensionsManager *manager, + const char *dir, + const char *filename) +{ + ExtInfo *info; + char *name; + char *path; + + /* Must match "libBLAHextension.so" */ + if (!g_str_has_prefix (filename, "lib") + || !g_str_has_suffix (filename, "extension." G_MODULE_SUFFIX)) + { + return; + } + + name = g_strndup (filename + 3, + strlen(filename) - 13 - strlen(G_MODULE_SUFFIX)); + + if (g_hash_table_lookup (manager->priv->extensions, name) != NULL) + { + /* We already have another version stored */ + g_free (name); + return; + } + + path = g_build_filename (dir, filename, NULL); + + info = g_new0 (ExtInfo, 1); + info->loader = ephy_module_loader_new (path); + + g_free (path); + + g_hash_table_insert (manager->priv->extensions, name, info); +} + +/** + * ephy_extensions_manager_load_dir: + * @manager: an #EphyExtensionsManager + * @path: directory to load + * + * Searches @path for all files matching the pattern + * "libEXTextension.so" and stores them in @manager, ready to be + * loaded. + **/ +void +ephy_extensions_manager_load_dir (EphyExtensionsManager *manager, + const char *path) +{ + DIR *d; + struct dirent *e; + + d = opendir (path); + if (d == NULL) + { + return; + } + while ((e = readdir (d)) != NULL) + { + ephy_extensions_manager_load_file (manager, path, e->d_name); + } + closedir (d); + + ephy_extensions_manager_sync_gconf (manager); +} + +static void +active_extensions_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyExtensionsManager *manager) +{ + ephy_extensions_manager_sync_gconf (manager); +} + +static void ephy_extensions_manager_init (EphyExtensionsManager *manager) { manager->priv = EPHY_EXTENSIONS_MANAGER_GET_PRIVATE (manager); LOG ("EphyExtensionsManager initialising") - manager->priv->loaders = NULL; - manager->priv->extensions = NULL; + manager->priv->extensions = g_hash_table_new_full + (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, (GDestroyNotify) free_ext_info); + + manager->priv->internal_extensions = NULL; + + manager->priv->active_extensions_notifier_id = + eel_gconf_notification_add (CONF_LOADED_EXTENSIONS, + (GConfClientNotifyFunc) + active_extensions_notifier, + manager); } static void @@ -196,15 +418,30 @@ ephy_extensions_manager_finalize (GObject *object) LOG ("EphyExtensionsManager finalising") - g_slist_foreach (manager->priv->extensions, (GFunc) g_object_unref, NULL); - g_slist_free (manager->priv->extensions); + g_hash_table_destroy (manager->priv->extensions); + + g_slist_foreach (manager->priv->internal_extensions, + (GFunc) g_object_unref, NULL); + g_slist_free (manager->priv->internal_extensions); - g_slist_free (manager->priv->loaders); + eel_gconf_notification_remove + (manager->priv->active_extensions_notifier_id); G_OBJECT_CLASS (parent_class)->finalize (object); } static void +attach_window_to_info (const char *key, + ExtInfo *info, + EphyWindow *window) +{ + if (info->extension) + { + ephy_extension_attach_window (info->extension, window); + } +} + +static void impl_attach_window (EphyExtension *extension, EphyWindow *window) { @@ -212,8 +449,23 @@ impl_attach_window (EphyExtension *extension, LOG ("multiplexing attach_window") - g_slist_foreach (manager->priv->extensions, + g_slist_foreach (manager->priv->internal_extensions, (GFunc) ephy_extension_attach_window, window); + + g_hash_table_foreach (manager->priv->extensions, + (GHFunc) attach_window_to_info, + window); +} + +static void +detach_window_from_info (const char *key, + ExtInfo *info, + EphyWindow *window) +{ + if (info->extension) + { + ephy_extension_detach_window (info->extension, window); + } } static void @@ -226,9 +478,13 @@ impl_detach_window (EphyExtension *extension, g_object_ref (window); - g_slist_foreach (manager->priv->extensions, + g_slist_foreach (manager->priv->internal_extensions, (GFunc) ephy_extension_detach_window, window); + g_hash_table_foreach (manager->priv->extensions, + (GHFunc) detach_window_from_info, + window); + g_object_unref (window); } diff --git a/src/ephy-extensions-manager.h b/src/ephy-extensions-manager.h index 22e956a0b..3272ff320 100644 --- a/src/ephy-extensions-manager.h +++ b/src/ephy-extensions-manager.h @@ -57,7 +57,10 @@ GType ephy_extensions_manager_get_type (void); EphyExtensionsManager *ephy_extensions_manager_new (void); -EphyExtension *ephy_extensions_manager_load (EphyExtensionsManager *manager, +void ephy_extensions_manager_load (EphyExtensionsManager *manager, + const char *filename); + +void ephy_extensions_manager_unload (EphyExtensionsManager *manager, const char *filename); void ephy_extensions_manager_load_dir (EphyExtensionsManager *manager, diff --git a/src/ephy-shell.c b/src/ephy-shell.c index 792099ddd..8b67e3d40 100644 --- a/src/ephy-shell.c +++ b/src/ephy-shell.c @@ -689,13 +689,13 @@ ephy_shell_get_extensions_manager (EphyShell *es) es->priv->extensions_manager = ephy_extensions_manager_new (); /* load the extensions */ - ephy_extensions_manager_load_dir (es->priv->extensions_manager, - EXTENSIONS_DIR); - path = g_build_filename (ephy_dot_dir (), "extensions", NULL); ephy_extensions_manager_load_dir (es->priv->extensions_manager, path); g_free (path); + + ephy_extensions_manager_load_dir (es->priv->extensions_manager, + EXTENSIONS_DIR); } return G_OBJECT (es->priv->extensions_manager); |