From 52fd78ddfcbe35507aee9122fed0f18c99407c89 Mon Sep 17 00:00:00 2001 From: monsta Date: Thu, 1 Dec 2016 21:42:01 +0300 Subject: port plugin system to libpeas backported from gedit with a few changes upstream commits for reference: https://git.gnome.org/browse/gedit/commit/?id=dbc98da7fda69981e61c5764af50c72b756eb2cc https://git.gnome.org/browse/gedit/commit/?id=2ae732a53ef08145c06909dc675134573c8c2e6d https://git.gnome.org/browse/gedit/commit/?id=6cd4936fb3aa6ca44a7c85888c6aad6c02b0f983 https://git.gnome.org/browse/gedit/commit/?id=041399d3d09389f951af8db4f5b83d142a9ebe55 https://git.gnome.org/browse/gedit/commit/?id=da46f5d6cd9b727e23ec0ae79bb0a78419bb1363 https://git.gnome.org/browse/gedit/commit/?id=1d56b827f14096891bb03dbd5e8211fdad1331ad https://git.gnome.org/browse/gedit/commit/?id=e63de5a2396a56eeba46479a54628843538da29e --- configure.ac | 2 + data/pluma.pc.in | 2 +- pluma/Makefile.am | 11 - pluma/dialogs/pluma-preferences-dialog.c | 4 +- pluma/pluma-dirs.c | 14 +- pluma/pluma-dirs.h | 3 +- pluma/pluma-plugins-engine.c | 808 ++----------------------------- pluma/pluma-plugins-engine.h | 45 +- pluma/pluma-prefs-manager-app.c | 26 - pluma/pluma-window-private.h | 3 + pluma/pluma-window.c | 76 ++- 11 files changed, 122 insertions(+), 872 deletions(-) diff --git a/configure.ac b/configure.ac index 6757c498..08f83a5a 100644 --- a/configure.ac +++ b/configure.ac @@ -160,6 +160,8 @@ PKG_CHECK_MODULES(PLUMA, [ gio-2.0 >= 2.26.0 gtk+-3.0 >= $GTK_REQUIRED gtksourceview-3.0 >= $GTKSOURCEVIEW_REQUIRED + libpeas-1.0 >= 1.2.0 + libpeas-gtk-1.0 >= 1.2.0 ]) PKG_CHECK_MODULES(X11, [x11]) diff --git a/data/pluma.pc.in b/data/pluma.pc.in index b79400c7..68d60a02 100644 --- a/data/pluma.pc.in +++ b/data/pluma.pc.in @@ -6,7 +6,7 @@ pluginsdir=@libdir@/pluma/plugins Name: pluma Description: pluma -Requires: gtksourceview-3.0 +Requires: gtksourceview-3.0 libpeas-1.0 libpeas-gtk-1.0 Version: @VERSION@ Cflags: -I${includedir}/pluma Libs: -L${libdir} diff --git a/pluma/Makefile.am b/pluma/Makefile.am index 1173ca7a..8e57c84b 100644 --- a/pluma/Makefile.am +++ b/pluma/Makefile.am @@ -52,11 +52,6 @@ NOINST_H_FILES = \ pluma-history-entry.h \ pluma-io-error-message-area.h \ pluma-language-manager.h \ - pluma-object-module.h \ - pluma-plugin-info.h \ - pluma-plugin-info-priv.h \ - pluma-plugin-loader.h \ - pluma-plugin-manager.h \ pluma-plugins-engine.h \ pluma-prefs-manager-private.h \ pluma-print-job.h \ @@ -83,7 +78,6 @@ INST_H_FILES = \ pluma-message.h \ pluma-notebook.h \ pluma-panel.h \ - pluma-plugin.h \ pluma-prefs-manager-app.h \ pluma-prefs-manager.h \ pluma-progress-message-area.h \ @@ -133,13 +127,8 @@ libpluma_c_files = \ pluma-message-bus.c \ pluma-message-type.c \ pluma-message.c \ - pluma-object-module.c \ pluma-notebook.c \ pluma-panel.c \ - pluma-plugin-info.c \ - pluma-plugin.c \ - pluma-plugin-loader.c \ - pluma-plugin-manager.c \ pluma-plugins-engine.c \ pluma-prefs-manager-app.c \ pluma-prefs-manager.c \ diff --git a/pluma/dialogs/pluma-preferences-dialog.c b/pluma/dialogs/pluma-preferences-dialog.c index 3bacd273..be13d59d 100755 --- a/pluma/dialogs/pluma-preferences-dialog.c +++ b/pluma/dialogs/pluma-preferences-dialog.c @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -47,7 +48,6 @@ #include "pluma-debug.h" #include "pluma-document.h" #include "pluma-style-scheme-manager.h" -#include "pluma-plugin-manager.h" #include "pluma-help.h" #include "pluma-dirs.h" @@ -1047,7 +1047,7 @@ setup_plugins_page (PlumaPreferencesDialog *dlg) pluma_debug (DEBUG_PREFS); - page_content = pluma_plugin_manager_new (); + page_content = peas_gtk_plugin_manager_new (NULL); g_return_if_fail (page_content != NULL); gtk_box_pack_start (GTK_BOX (dlg->priv->plugin_manager_place_holder), diff --git a/pluma/pluma-dirs.c b/pluma/pluma-dirs.c index 929b8bd2..aebf5150 100644 --- a/pluma/pluma-dirs.c +++ b/pluma/pluma-dirs.c @@ -95,17 +95,17 @@ gchar* pluma_dirs_get_pluma_plugins_dir(void) return plugin_dir; } -gchar* pluma_dirs_get_pluma_plugin_loaders_dir(void) +gchar* pluma_dirs_get_pluma_plugins_data_dir(void) { - gchar* lib_dir; - gchar* loader_dir; + gchar* data_dir; + gchar* plugin_data_dir; - lib_dir = pluma_dirs_get_pluma_lib_dir(); + data_dir = pluma_dirs_get_pluma_data_dir(); - loader_dir = g_build_filename(lib_dir, "plugin-loaders", NULL); - g_free(lib_dir); + plugin_data_dir = g_build_filename(data_dir, "plugins", NULL); + g_free(data_dir); - return loader_dir; + return plugin_data_dir; } gchar* pluma_dirs_get_ui_file(const gchar* file) diff --git a/pluma/pluma-dirs.h b/pluma/pluma-dirs.h index 529f18ee..a9c74d85 100644 --- a/pluma/pluma-dirs.h +++ b/pluma/pluma-dirs.h @@ -44,8 +44,7 @@ gchar *pluma_dirs_get_pluma_lib_dir (void); gchar *pluma_dirs_get_pluma_plugins_dir (void); -gchar *pluma_dirs_get_pluma_plugin_loaders_dir - (void); +gchar *pluma_dirs_get_pluma_plugins_data_dir (void); gchar *pluma_dirs_get_ui_file (const gchar *file); diff --git a/pluma/pluma-plugins-engine.c b/pluma/pluma-plugins-engine.c index 27f71dd9..e3d91b11 100644 --- a/pluma/pluma-plugins-engine.c +++ b/pluma/pluma-plugins-engine.c @@ -35,459 +35,105 @@ #include #include +#include #include "pluma-plugins-engine.h" -#include "pluma-plugin-info-priv.h" -#include "pluma-plugin.h" #include "pluma-debug.h" #include "pluma-app.h" #include "pluma-prefs-manager.h" -#include "pluma-plugin-loader.h" -#include "pluma-object-module.h" #include "pluma-dirs.h" -#define PLUMA_PLUGINS_ENGINE_BASE_KEY "/apps/pluma/plugins" -#define PLUMA_PLUGINS_ENGINE_KEY PLUMA_PLUGINS_ENGINE_BASE_KEY "/active-plugins" - -#define PLUGIN_EXT ".pluma-plugin" -#define LOADER_EXT G_MODULE_SUFFIX - -typedef struct -{ - PlumaPluginLoader *loader; - PlumaObjectModule *module; -} LoaderInfo; - -/* Signals */ -enum -{ - ACTIVATE_PLUGIN, - DEACTIVATE_PLUGIN, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE(PlumaPluginsEngine, pluma_plugins_engine, G_TYPE_OBJECT) +G_DEFINE_TYPE (PlumaPluginsEngine, pluma_plugins_engine, PEAS_TYPE_ENGINE) struct _PlumaPluginsEnginePrivate { - GList *plugin_list; - GHashTable *loaders; - - gboolean activate_from_prefs; + GSettings *plugin_settings; }; PlumaPluginsEngine *default_engine = NULL; -static void pluma_plugins_engine_activate_plugin_real (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); -static void pluma_plugins_engine_deactivate_plugin_real (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); - -typedef gboolean (*LoadDirCallback)(PlumaPluginsEngine *engine, const gchar *filename, gpointer userdata); - -static gboolean -load_dir_real (PlumaPluginsEngine *engine, - const gchar *dir, - const gchar *suffix, - LoadDirCallback callback, - gpointer userdata) +static void +pluma_plugins_engine_init (PlumaPluginsEngine *engine) { + gchar *private_path; GError *error = NULL; - GDir *d; - const gchar *dirent; - gboolean ret = TRUE; - - g_return_val_if_fail (dir != NULL, TRUE); - - pluma_debug_message (DEBUG_PLUGINS, "DIR: %s", dir); - - d = g_dir_open (dir, 0, &error); - if (!d) - { - g_warning ("%s", error->message); - g_error_free (error); - return TRUE; - } - while ((dirent = g_dir_read_name (d))) - { - gchar *filename; - - if (!g_str_has_suffix (dirent, suffix)) - continue; - - filename = g_build_filename (dir, dirent, NULL); - - ret = callback (engine, filename, userdata); - - g_free (filename); - - if (!ret) - break; - } - - g_dir_close (d); - return ret; -} - -static gboolean -load_plugin_info (PlumaPluginsEngine *engine, - const gchar *filename, - gpointer userdata) -{ - PlumaPluginInfo *info; - - info = _pluma_plugin_info_new (filename); - - if (info == NULL) - return TRUE; - - /* If a plugin with this name has already been loaded - * drop this one (user plugins override system plugins) */ - if (pluma_plugins_engine_get_plugin_info (engine, pluma_plugin_info_get_module_name (info)) != NULL) - { - pluma_debug_message (DEBUG_PLUGINS, "Two or more plugins named '%s'. " - "Only the first will be considered.\n", - pluma_plugin_info_get_module_name (info)); - - _pluma_plugin_info_unref (info); - - return TRUE; - } + pluma_debug (DEBUG_PLUGINS); - engine->priv->plugin_list = g_list_prepend (engine->priv->plugin_list, info); + engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, + PLUMA_TYPE_PLUGINS_ENGINE, + PlumaPluginsEnginePrivate); - pluma_debug_message (DEBUG_PLUGINS, "Plugin %s loaded", info->name); - return TRUE; -} + engine->priv->plugin_settings = g_settings_new (PLUMA_SCHEMA); -static void -load_all_plugins (PlumaPluginsEngine *engine) -{ - gchar *plugin_dir; - const gchar *pdirs_env = NULL; - - /* load user plugins */ - plugin_dir = pluma_dirs_get_user_plugins_dir (); - if (g_file_test (plugin_dir, G_FILE_TEST_IS_DIR)) + /* This should be moved to libpeas */ + if (!g_irepository_require (g_irepository_get_default (), + "Peas", "1.0", 0, &error)) { - load_dir_real (engine, - plugin_dir, - PLUGIN_EXT, - load_plugin_info, - NULL); - + g_warning ("Could not load Peas repository: %s", error->message); + g_error_free (error); + error = NULL; } - g_free (plugin_dir); - - /* load system plugins */ - pdirs_env = g_getenv ("PLUMA_PLUGINS_PATH"); - pluma_debug_message (DEBUG_PLUGINS, "PLUMA_PLUGINS_PATH=%s", pdirs_env); - - if (pdirs_env != NULL) + if (!g_irepository_require (g_irepository_get_default (), + "PeasGtk", "1.0", 0, &error)) { - gchar **pdirs; - gint i; - - pdirs = g_strsplit (pdirs_env, G_SEARCHPATH_SEPARATOR_S, 0); - - for (i = 0; pdirs[i] != NULL; i++) - { - if (!load_dir_real (engine, - pdirs[i], - PLUGIN_EXT, - load_plugin_info, - NULL)) - { - break; - } - } - - g_strfreev (pdirs); - } - else - { - plugin_dir = pluma_dirs_get_pluma_plugins_dir (); - - load_dir_real (engine, - plugin_dir, - PLUGIN_EXT, - load_plugin_info, - NULL); - - g_free (plugin_dir); + g_warning ("Could not load PeasGtk repository: %s", error->message); + g_error_free (error); + error = NULL; } -} - -static guint -hash_lowercase (gconstpointer data) -{ - gchar *lowercase; - guint ret; - - lowercase = g_ascii_strdown ((const gchar *)data, -1); - ret = g_str_hash (lowercase); - g_free (lowercase); - - return ret; -} - -static gboolean -equal_lowercase (gconstpointer a, gconstpointer b) -{ - return g_ascii_strcasecmp ((const gchar *)a, (const gchar *)b) == 0; -} - -static void -loader_destroy (LoaderInfo *info) -{ - if (!info) - return; - - if (info->loader) - g_object_unref (info->loader); - - g_free (info); -} - -static void -add_loader (PlumaPluginsEngine *engine, - const gchar *loader_id, - PlumaObjectModule *module) -{ - LoaderInfo *info; - info = g_new (LoaderInfo, 1); - info->loader = NULL; - info->module = module; + private_path = g_build_filename (LIBDIR, "girepository-1.0", NULL); - g_hash_table_insert (engine->priv->loaders, g_strdup (loader_id), info); -} - -static void -pluma_plugins_engine_init (PlumaPluginsEngine *engine) -{ - pluma_debug (DEBUG_PLUGINS); - - if (!g_module_supported ()) + if (!g_irepository_require_private (g_irepository_get_default (), + private_path, "Pluma", "1.0", 0, &error)) { - g_warning ("pluma is not able to initialize the plugins engine."); - return; + g_warning ("Could not load Pluma repository: %s", error->message); + g_error_free (error); + error = NULL; } - engine->priv = G_TYPE_INSTANCE_GET_PRIVATE (engine, - PLUMA_TYPE_PLUGINS_ENGINE, - PlumaPluginsEnginePrivate); + g_free (private_path); - load_all_plugins (engine); + peas_engine_add_search_path (PEAS_ENGINE (engine), + pluma_dirs_get_user_plugins_dir (), + pluma_dirs_get_user_plugins_dir ()); - /* make sure that the first reactivation will read active plugins - from the prefs */ - engine->priv->activate_from_prefs = TRUE; + peas_engine_add_search_path (PEAS_ENGINE (engine), + pluma_dirs_get_pluma_plugins_dir (), + pluma_dirs_get_pluma_plugins_data_dir ()); - /* mapping from loadername -> loader object */ - engine->priv->loaders = g_hash_table_new_full (hash_lowercase, - equal_lowercase, - (GDestroyNotify)g_free, - (GDestroyNotify)loader_destroy); + g_settings_bind (engine->priv->plugin_settings, + GPM_ACTIVE_PLUGINS, + engine, + "loaded-plugins", + G_SETTINGS_BIND_DEFAULT); } static void -loader_garbage_collect (const char *id, LoaderInfo *info) -{ - if (info->loader) - pluma_plugin_loader_garbage_collect (info->loader); -} - -void -pluma_plugins_engine_garbage_collect (PlumaPluginsEngine *engine) -{ - g_hash_table_foreach (engine->priv->loaders, - (GHFunc) loader_garbage_collect, - NULL); -} - -static void -pluma_plugins_engine_finalize (GObject *object) +pluma_plugins_engine_dispose (GObject *object) { PlumaPluginsEngine *engine = PLUMA_PLUGINS_ENGINE (object); - GList *item; - - pluma_debug (DEBUG_PLUGINS); - /* Firs deactivate all plugins */ - for (item = engine->priv->plugin_list; item; item = item->next) + if (engine->priv->plugin_settings != NULL) { - PlumaPluginInfo *info = PLUMA_PLUGIN_INFO (item->data); - - if (pluma_plugin_info_is_active (info)) - pluma_plugins_engine_deactivate_plugin_real (engine, info); + g_object_unref (engine->priv->plugin_settings); + engine->priv->plugin_settings = NULL; } - /* unref the loaders */ - g_hash_table_destroy (engine->priv->loaders); - - /* and finally free the infos */ - for (item = engine->priv->plugin_list; item; item = item->next) - { - PlumaPluginInfo *info = PLUMA_PLUGIN_INFO (item->data); - - _pluma_plugin_info_unref (info); - } - - g_list_free (engine->priv->plugin_list); - - G_OBJECT_CLASS (pluma_plugins_engine_parent_class)->finalize (object); + G_OBJECT_CLASS (pluma_plugins_engine_parent_class)->dispose (object); } static void pluma_plugins_engine_class_init (PlumaPluginsEngineClass *klass) { - GType the_type = G_TYPE_FROM_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = pluma_plugins_engine_finalize; - klass->activate_plugin = pluma_plugins_engine_activate_plugin_real; - klass->deactivate_plugin = pluma_plugins_engine_deactivate_plugin_real; - - signals[ACTIVATE_PLUGIN] = - g_signal_new ("activate-plugin", - the_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PlumaPluginsEngineClass, activate_plugin), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - PLUMA_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE); - - signals[DEACTIVATE_PLUGIN] = - g_signal_new ("deactivate-plugin", - the_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (PlumaPluginsEngineClass, deactivate_plugin), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - 1, - PLUMA_TYPE_PLUGIN_INFO | G_SIGNAL_TYPE_STATIC_SCOPE); + object_class->dispose = pluma_plugins_engine_dispose; g_type_class_add_private (klass, sizeof (PlumaPluginsEnginePrivate)); } -static gboolean -load_loader (PlumaPluginsEngine *engine, - const gchar *filename, - gpointer data) -{ - PlumaObjectModule *module; - gchar *base; - gchar *path; - const gchar *id; - GType type; - - /* try to load in the module */ - path = g_path_get_dirname (filename); - base = g_path_get_basename (filename); - - /* for now they are all resident */ - module = pluma_object_module_new (base, - path, - "register_pluma_plugin_loader", - TRUE); - - g_free (base); - g_free (path); - - /* make sure to load the type definition */ - if (!g_type_module_use (G_TYPE_MODULE (module))) - { - g_object_unref (module); - g_warning ("Plugin loader module `%s' could not be loaded", filename); - - return TRUE; - } - - /* get the exported type and check the name as exported by the - * loader interface */ - type = pluma_object_module_get_object_type (module); - id = pluma_plugin_loader_type_get_id (type); - - add_loader (engine, id, module); - g_type_module_unuse (G_TYPE_MODULE (module)); - - return TRUE; -} - -static void -ensure_loader (LoaderInfo *info) -{ - if (info->loader == NULL && info->module != NULL) - { - /* create a new loader object */ - PlumaPluginLoader *loader; - loader = (PlumaPluginLoader *)pluma_object_module_new_object (info->module, NULL); - - if (loader == NULL || !PLUMA_IS_PLUGIN_LOADER (loader)) - { - g_warning ("Loader object is not a valid PlumaPluginLoader instance"); - - if (loader != NULL && G_IS_OBJECT (loader)) - g_object_unref (loader); - } - else - { - info->loader = loader; - } - } -} - -static PlumaPluginLoader * -get_plugin_loader (PlumaPluginsEngine *engine, PlumaPluginInfo *info) -{ - const gchar *loader_id; - LoaderInfo *loader_info; - - loader_id = info->loader; - - loader_info = (LoaderInfo *)g_hash_table_lookup ( - engine->priv->loaders, - loader_id); - - if (loader_info == NULL) - { - gchar *loader_dir; - - loader_dir = pluma_dirs_get_pluma_plugin_loaders_dir (); - - /* loader could not be found in the hash, try to find it by - scanning */ - load_dir_real (engine, - loader_dir, - LOADER_EXT, - (LoadDirCallback)load_loader, - NULL); - g_free (loader_dir); - - loader_info = (LoaderInfo *)g_hash_table_lookup ( - engine->priv->loaders, - loader_id); - } - - if (loader_info == NULL) - { - /* cache non-existent so we don't scan again */ - add_loader (engine, loader_id, NULL); - return NULL; - } - - ensure_loader (loader_info); - return loader_info->loader; -} - PlumaPluginsEngine * pluma_plugins_engine_get_default (void) { @@ -496,366 +142,8 @@ pluma_plugins_engine_get_default (void) default_engine = PLUMA_PLUGINS_ENGINE (g_object_new (PLUMA_TYPE_PLUGINS_ENGINE, NULL)); g_object_add_weak_pointer (G_OBJECT (default_engine), - (gpointer) &default_engine); - return default_engine; -} - -const GList * -pluma_plugins_engine_get_plugin_list (PlumaPluginsEngine *engine) -{ - pluma_debug (DEBUG_PLUGINS); - - return engine->priv->plugin_list; -} - -static gint -compare_plugin_info_and_name (PlumaPluginInfo *info, - const gchar *module_name) -{ - return strcmp (pluma_plugin_info_get_module_name (info), module_name); -} + (gpointer) &default_engine); -PlumaPluginInfo * -pluma_plugins_engine_get_plugin_info (PlumaPluginsEngine *engine, - const gchar *name) -{ - GList *l = g_list_find_custom (engine->priv->plugin_list, - name, - (GCompareFunc) compare_plugin_info_and_name); - - return l == NULL ? NULL : (PlumaPluginInfo *) l->data; -} - -static void -save_active_plugin_list (PlumaPluginsEngine *engine) -{ - GSList *active_plugins = NULL; - GList *l; - - for (l = engine->priv->plugin_list; l != NULL; l = l->next) - { - PlumaPluginInfo *info = (PlumaPluginInfo *) l->data; - - if (pluma_plugin_info_is_active (info)) - { - active_plugins = g_slist_prepend (active_plugins, - (gpointer)pluma_plugin_info_get_module_name (info)); - } - } - - pluma_prefs_manager_set_active_plugins (active_plugins); - - g_slist_free (active_plugins); -} - -static gboolean -load_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info) -{ - PlumaPluginLoader *loader; - gchar *path; - - if (pluma_plugin_info_is_active (info)) - return TRUE; - - if (!pluma_plugin_info_is_available (info)) - return FALSE; - - loader = get_plugin_loader (engine, info); - - if (loader == NULL) - { - g_warning ("Could not find loader `%s' for plugin `%s'", info->loader, info->name); - info->available = FALSE; - return FALSE; - } - - path = g_path_get_dirname (info->file); - g_return_val_if_fail (path != NULL, FALSE); - - info->plugin = pluma_plugin_loader_load (loader, info, path); - - g_free (path); - - if (info->plugin == NULL) - { - g_warning ("Error loading plugin '%s'", info->name); - info->available = FALSE; - return FALSE; - } - - return TRUE; -} - -static void -pluma_plugins_engine_activate_plugin_real (PlumaPluginsEngine *engine, - PlumaPluginInfo *info) -{ - const GList *wins; - - if (!load_plugin (engine, info)) - return; - - for (wins = pluma_app_get_windows (pluma_app_get_default ()); - wins != NULL; - wins = wins->next) - { - pluma_plugin_activate (info->plugin, PLUMA_WINDOW (wins->data)); - } -} - -gboolean -pluma_plugins_engine_activate_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info) -{ - pluma_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (info != NULL, FALSE); - - if (!pluma_plugin_info_is_available (info)) - return FALSE; - - if (pluma_plugin_info_is_active (info)) - return TRUE; - - g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info); - - if (pluma_plugin_info_is_active (info)) - save_active_plugin_list (engine); - - return pluma_plugin_info_is_active (info); -} - -static void -call_plugin_deactivate (PlumaPlugin *plugin, - PlumaWindow *window) -{ - pluma_plugin_deactivate (plugin, window); - - /* ensure update of ui manager, because we suspect it does something - with expected static strings in the type module (when unloaded the - strings don't exist anymore, and ui manager updates in an idle - func) */ - gtk_ui_manager_ensure_update (pluma_window_get_ui_manager (window)); -} - -static void -pluma_plugins_engine_deactivate_plugin_real (PlumaPluginsEngine *engine, - PlumaPluginInfo *info) -{ - const GList *wins; - PlumaPluginLoader *loader; - - if (!pluma_plugin_info_is_active (info) || - !pluma_plugin_info_is_available (info)) - return; - - for (wins = pluma_app_get_windows (pluma_app_get_default ()); - wins != NULL; - wins = wins->next) - { - call_plugin_deactivate (info->plugin, PLUMA_WINDOW (wins->data)); - } - - /* first unref the plugin (the loader still has one) */ - g_object_unref (info->plugin); - - /* find the loader and tell it to gc and unload the plugin */ - loader = get_plugin_loader (engine, info); - - pluma_plugin_loader_garbage_collect (loader); - pluma_plugin_loader_unload (loader, info); - - info->plugin = NULL; -} - -gboolean -pluma_plugins_engine_deactivate_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info) -{ - pluma_debug (DEBUG_PLUGINS); - - g_return_val_if_fail (info != NULL, FALSE); - - if (!pluma_plugin_info_is_active (info)) - return TRUE; - - g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info); - if (!pluma_plugin_info_is_active (info)) - save_active_plugin_list (engine); - - return !pluma_plugin_info_is_active (info); -} - -void -pluma_plugins_engine_activate_plugins (PlumaPluginsEngine *engine, - PlumaWindow *window) -{ - GSList *active_plugins = NULL; - GList *pl; - - pluma_debug (DEBUG_PLUGINS); - - g_return_if_fail (PLUMA_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (PLUMA_IS_WINDOW (window)); - - /* the first time, we get the 'active' plugins from GSettings */ - if (engine->priv->activate_from_prefs) - { - active_plugins = pluma_prefs_manager_get_active_plugins (); - } - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - PlumaPluginInfo *info = (PlumaPluginInfo*)pl->data; - - if (engine->priv->activate_from_prefs && - g_slist_find_custom (active_plugins, - pluma_plugin_info_get_module_name (info), - (GCompareFunc)strcmp) == NULL) - continue; - - /* If plugin is not active, don't try to activate/load it */ - if (!engine->priv->activate_from_prefs && - !pluma_plugin_info_is_active (info)) - continue; - - if (load_plugin (engine, info)) - pluma_plugin_activate (info->plugin, - window); - } - - if (engine->priv->activate_from_prefs) - { - g_slist_foreach (active_plugins, (GFunc) g_free, NULL); - g_slist_free (active_plugins); - engine->priv->activate_from_prefs = FALSE; - } - - pluma_debug_message (DEBUG_PLUGINS, "End"); - - /* also call update_ui after activation */ - pluma_plugins_engine_update_plugins_ui (engine, window); -} - -void -pluma_plugins_engine_deactivate_plugins (PlumaPluginsEngine *engine, - PlumaWindow *window) -{ - GList *pl; - - pluma_debug (DEBUG_PLUGINS); - - g_return_if_fail (PLUMA_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (PLUMA_IS_WINDOW (window)); - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - PlumaPluginInfo *info = (PlumaPluginInfo*)pl->data; - - /* check if the plugin is actually active */ - if (!pluma_plugin_info_is_active (info)) - continue; - - /* call deactivate for the plugin for this window */ - pluma_plugin_deactivate (info->plugin, window); - } - - pluma_debug_message (DEBUG_PLUGINS, "End"); -} - -void -pluma_plugins_engine_update_plugins_ui (PlumaPluginsEngine *engine, - PlumaWindow *window) -{ - GList *pl; - - pluma_debug (DEBUG_PLUGINS); - - g_return_if_fail (PLUMA_IS_PLUGINS_ENGINE (engine)); - g_return_if_fail (PLUMA_IS_WINDOW (window)); - - /* call update_ui for all active plugins */ - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - PlumaPluginInfo *info = (PlumaPluginInfo*)pl->data; - - if (!pluma_plugin_info_is_active (info)) - continue; - - pluma_debug_message (DEBUG_PLUGINS, "Updating UI of %s", info->name); - pluma_plugin_update_ui (info->plugin, window); - } -} - -void -pluma_plugins_engine_configure_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info, - GtkWindow *parent) -{ - GtkWidget *conf_dlg; - - GtkWindowGroup *wg; - - pluma_debug (DEBUG_PLUGINS); - - g_return_if_fail (info != NULL); - - conf_dlg = pluma_plugin_create_configure_dialog (info->plugin); - g_return_if_fail (conf_dlg != NULL); - gtk_window_set_transient_for (GTK_WINDOW (conf_dlg), - parent); - - wg = gtk_window_get_group (parent); - if (wg == NULL) - { - wg = gtk_window_group_new (); - gtk_window_group_add_window (wg, parent); - } - - gtk_window_group_add_window (wg, - GTK_WINDOW (conf_dlg)); - - gtk_window_set_modal (GTK_WINDOW (conf_dlg), TRUE); - gtk_widget_show (conf_dlg); -} - -void -pluma_plugins_engine_active_plugins_changed (PlumaPluginsEngine *engine) -{ - gboolean to_activate; - GSList *active_plugins; - GList *pl; - - pluma_debug (DEBUG_PLUGINS); - - active_plugins = pluma_prefs_manager_get_active_plugins (); - - for (pl = engine->priv->plugin_list; pl; pl = pl->next) - { - PlumaPluginInfo *info = (PlumaPluginInfo*)pl->data; - - if (!pluma_plugin_info_is_available (info)) - continue; - - to_activate = (g_slist_find_custom (active_plugins, - pluma_plugin_info_get_module_name (info), - (GCompareFunc)strcmp) != NULL); - - if (!pluma_plugin_info_is_active (info) && to_activate) - g_signal_emit (engine, signals[ACTIVATE_PLUGIN], 0, info); - else if (pluma_plugin_info_is_active (info) && !to_activate) - g_signal_emit (engine, signals[DEACTIVATE_PLUGIN], 0, info); - } - - g_slist_foreach (active_plugins, (GFunc) g_free, NULL); - g_slist_free (active_plugins); + return default_engine; } -void -pluma_plugins_engine_rescan_plugins (PlumaPluginsEngine *engine) -{ - pluma_debug (DEBUG_PLUGINS); - - load_all_plugins (engine); -} diff --git a/pluma/pluma-plugins-engine.h b/pluma/pluma-plugins-engine.h index 6a58f213..2cf20004 100644 --- a/pluma/pluma-plugins-engine.h +++ b/pluma/pluma-plugins-engine.h @@ -32,9 +32,7 @@ #define __PLUMA_PLUGINS_ENGINE_H__ #include -#include "pluma-window.h" -#include "pluma-plugin-info.h" -#include "pluma-plugin.h" +#include G_BEGIN_DECLS @@ -50,7 +48,7 @@ typedef struct _PlumaPluginsEnginePrivate PlumaPluginsEnginePrivate; struct _PlumaPluginsEngine { - GObject parent; + PeasEngine parent; PlumaPluginsEnginePrivate *priv; }; @@ -58,50 +56,13 @@ typedef struct _PlumaPluginsEngineClass PlumaPluginsEngineClass; struct _PlumaPluginsEngineClass { - GObjectClass parent_class; - - void (* activate_plugin) (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); - - void (* deactivate_plugin) (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); + PeasEngineClass parent_class; }; GType pluma_plugins_engine_get_type (void) G_GNUC_CONST; PlumaPluginsEngine *pluma_plugins_engine_get_default (void); -void pluma_plugins_engine_garbage_collect (PlumaPluginsEngine *engine); - -const GList *pluma_plugins_engine_get_plugin_list (PlumaPluginsEngine *engine); - -PlumaPluginInfo *pluma_plugins_engine_get_plugin_info (PlumaPluginsEngine *engine, - const gchar *name); - -/* plugin load and unloading (overall, for all windows) */ -gboolean pluma_plugins_engine_activate_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); -gboolean pluma_plugins_engine_deactivate_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info); - -void pluma_plugins_engine_configure_plugin (PlumaPluginsEngine *engine, - PlumaPluginInfo *info, - GtkWindow *parent); - -/* plugin activation/deactivation per window, private to PlumaWindow */ -void pluma_plugins_engine_activate_plugins (PlumaPluginsEngine *engine, - PlumaWindow *window); -void pluma_plugins_engine_deactivate_plugins (PlumaPluginsEngine *engine, - PlumaWindow *window); -void pluma_plugins_engine_update_plugins_ui (PlumaPluginsEngine *engine, - PlumaWindow *window); - -/* private for GSettings notification */ -void pluma_plugins_engine_active_plugins_changed - (PlumaPluginsEngine *engine); - -void pluma_plugins_engine_rescan_plugins (PlumaPluginsEngine *engine); - G_END_DECLS #endif /* __PLUMA_PLUGINS_ENGINE_H__ */ diff --git a/pluma/pluma-prefs-manager-app.c b/pluma/pluma-prefs-manager-app.c index 34a666eb..76d3942e 100644 --- a/pluma/pluma-prefs-manager-app.c +++ b/pluma/pluma-prefs-manager-app.c @@ -112,10 +112,6 @@ static void pluma_prefs_manager_auto_save_changed (GSettings *settings, gchar *key, gpointer user_data); -static void pluma_prefs_manager_active_plugins_changed (GSettings *settings, - gchar *key, - gpointer user_data); - static void pluma_prefs_manager_lockdown_changed (GSettings *settings, gchar *key, gpointer user_data); @@ -713,11 +709,6 @@ pluma_prefs_manager_app_init (void) G_CALLBACK (pluma_prefs_manager_auto_save_changed), NULL); - g_signal_connect (pluma_prefs_manager->settings, - "changed::" GPM_ACTIVE_PLUGINS, - G_CALLBACK (pluma_prefs_manager_active_plugins_changed), - NULL); - g_signal_connect (pluma_prefs_manager->lockdown_settings, "changed", G_CALLBACK (pluma_prefs_manager_lockdown_changed), @@ -1414,23 +1405,6 @@ pluma_prefs_manager_auto_save_changed (GSettings *settings, } } -static void -pluma_prefs_manager_active_plugins_changed (GSettings *settings, - gchar *key, - gpointer user_data) -{ - pluma_debug (DEBUG_PREFS); - - if (strcmp (key, GPM_ACTIVE_PLUGINS) == 0) - { - PlumaPluginsEngine *engine; - - engine = pluma_plugins_engine_get_default (); - - pluma_plugins_engine_active_plugins_changed (engine); - } -} - static void pluma_prefs_manager_lockdown_changed (GSettings *settings, gchar *key, diff --git a/pluma/pluma-window-private.h b/pluma/pluma-window-private.h index 05eb87fa..3c36a499 100644 --- a/pluma/pluma-window-private.h +++ b/pluma/pluma-window-private.h @@ -31,6 +31,8 @@ #ifndef __PLUMA_WINDOW_PRIVATE_H__ #define __PLUMA_WINDOW_PRIVATE_H__ +#include + #include "pluma/pluma-window.h" #include "pluma-prefs-manager.h" #include "pluma-message-bus.h" @@ -53,6 +55,7 @@ struct _PlumaWindowPrivate GtkWidget *language_combo; PlumaMessageBus *message_bus; + PeasExtensionSet *extensions; /* Widgets for fullscreen mode */ GtkWidget *fullscreen_controls; diff --git a/pluma/pluma-window.c b/pluma/pluma-window.c index d9e36a3a..8bff1509 100644 --- a/pluma/pluma-window.c +++ b/pluma/pluma-window.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "pluma-ui.h" #include "pluma-window.h" @@ -175,7 +177,7 @@ pluma_window_dispose (GObject *object) /* First of all, force collection so that plugins * really drop some of the references. */ - pluma_plugins_engine_garbage_collect (pluma_plugins_engine_get_default ()); + peas_engine_garbage_collect (PEAS_ENGINE (pluma_plugins_engine_get_default ())); /* save the panes position and make sure to deactivate plugins * for this window, but only once */ @@ -183,8 +185,12 @@ pluma_window_dispose (GObject *object) { save_panes_state (window); - pluma_plugins_engine_deactivate_plugins (pluma_plugins_engine_get_default (), - window); + /* Note that unreffing the extensions will automatically remove + all extensions which in turn will deactivate the extension */ + g_object_unref (window->priv->extensions); + + peas_engine_garbage_collect (PEAS_ENGINE (pluma_plugins_engine_get_default ())); + window->priv->dispose_has_run = TRUE; } @@ -232,7 +238,7 @@ pluma_window_dispose (GObject *object) /* Now that there have broken some reference loops, * force collection again. */ - pluma_plugins_engine_garbage_collect (pluma_plugins_engine_get_default ()); + peas_engine_garbage_collect (PEAS_ENGINE (pluma_plugins_engine_get_default ())); G_OBJECT_CLASS (pluma_window_parent_class)->dispose (object); } @@ -322,7 +328,7 @@ static void pluma_window_tab_removed (PlumaWindow *window, PlumaTab *tab) { - pluma_plugins_engine_garbage_collect (pluma_plugins_engine_get_default ()); + peas_engine_garbage_collect (PEAS_ENGINE (pluma_plugins_engine_get_default ())); } static void @@ -824,8 +830,7 @@ set_sensitivity_according_to_tab (PlumaWindow *window, update_next_prev_doc_sensitivity (window, tab); - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static void @@ -2685,8 +2690,7 @@ sync_name (PlumaTab *tab, g_free (escaped_name); g_free (tip); - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static PlumaWindow * @@ -3077,8 +3081,7 @@ selection_changed (PlumaDocument *doc, editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (doc))); - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static void @@ -3087,8 +3090,7 @@ sync_languages_menu (PlumaDocument *doc, PlumaWindow *window) { update_languages_menu (window); - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static void @@ -3100,8 +3102,7 @@ readonly_changed (PlumaDocument *doc, sync_name (window->priv->active_tab, NULL, window); - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static void @@ -3109,8 +3110,7 @@ editable_changed (PlumaView *view, GParamSpec *arg1, PlumaWindow *window) { - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } static void @@ -3322,8 +3322,7 @@ notebook_tab_removed (PlumaNotebook *notebook, if (window->priv->num_tabs == 0) { - pluma_plugins_engine_update_plugins_ui (pluma_plugins_engine_get_default (), - window); + peas_extension_set_call (window->priv->extensions, "update_state", window); } update_window_state (window); @@ -3811,6 +3810,30 @@ add_notebook (PlumaWindow *window, connect_notebook_signals (window, notebook); } +static void +on_extension_added (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + PlumaWindow *window) +{ + peas_extension_call (exten, "activate", window); +} + +static void +on_extension_removed (PeasExtensionSet *extensions, + PeasPluginInfo *info, + PeasExtension *exten, + PlumaWindow *window) +{ + peas_extension_call (exten, "deactivate", window); + + /* Ensure update of ui manager, because we suspect it does something + * with expected static strings in the type module (when unloaded the + * strings don't exist anymore, and ui manager updates in an idle + * func) */ + gtk_ui_manager_ensure_update (window->priv->manager); +} + static void pluma_window_init (PlumaWindow *window) { @@ -3936,8 +3959,19 @@ pluma_window_init (PlumaWindow *window) pluma_debug_message (DEBUG_WINDOW, "Update plugins ui"); - pluma_plugins_engine_activate_plugins (pluma_plugins_engine_get_default (), - window); + window->priv->extensions = peas_extension_set_new (PEAS_ENGINE (pluma_plugins_engine_get_default ()), + PEAS_TYPE_ACTIVATABLE, "object", window, NULL); + + peas_extension_set_call (window->priv->extensions, "activate"); + + g_signal_connect (window->priv->extensions, + "extension-added", + G_CALLBACK (on_extension_added), + window); + g_signal_connect (window->priv->extensions, + "extension-removed", + G_CALLBACK (on_extension_removed), + window); /* set visibility of panes. * This needs to be done after plugins activatation */ -- cgit v1.2.1