Load one copy of plugins early

Although multi-screen support has not been tested and probably
doesn't fully work, the basic setup for multi-screen is that
we have the same list of plugins for all screens, but a different
instance of the plugins for each screen.

To allow plugins to do setup that is screen independent and needs
to occur early in the setup process, we identify a "default plugin
manager" and load (but not start) that plugin manager's plugins
immediately after we know our list of plugins.

That plugin manager is then reused for the first screen we open
and the plugins are started at that time. Separate plugin managers
are loaded and started for any other screens we open.

(A plugin could keep track of whether the screen-independent
setup has been done in a static variable, or it could do everything
in a way that is safe to do repeatedly.)

https://bugzilla.gnome.org/show_bug.cgi?id=615586
This commit is contained in:
Owen W. Taylor 2010-04-12 17:42:46 -04:00
parent 95b260f3a9
commit b77b0a3d81
5 changed files with 80 additions and 12 deletions

View File

@ -488,9 +488,17 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
clutter_actor_hide (info->hidden_group); clutter_actor_hide (info->hidden_group);
info->plugin_mgr = info->plugin_mgr =
mutter_plugin_manager_new (screen); mutter_plugin_manager_get (screen);
if (!mutter_plugin_manager_load (info->plugin_mgr))
g_critical ("failed to load plugins"); if (info->plugin_mgr != mutter_plugin_manager_get_default ())
{
/* The default plugin manager has been initialized during
* global preferences load.
*/
if (!mutter_plugin_manager_load (info->plugin_mgr))
g_critical ("failed to load plugins");
}
if (!mutter_plugin_manager_initialize (info->plugin_mgr)) if (!mutter_plugin_manager_initialize (info->plugin_mgr))
g_critical ("failed to initialize plugins"); g_critical ("failed to initialize plugins");

View File

@ -39,6 +39,15 @@
*/ */
static GHashTable *plugin_modules = NULL; static GHashTable *plugin_modules = NULL;
/*
* We have one "default plugin manager" that acts for the first screen,
* but also can be used before we open any screens, and additional
* plugin managers for each screen. (This is ugly. Probably we should
* have one plugin manager and only make the plugins per-screen.)
*/
static MutterPluginManager *default_plugin_manager;
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr); static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
struct MutterPluginManager struct MutterPluginManager
@ -334,7 +343,7 @@ mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
return mutter_plugin_manager_load (plugin_mgr); return mutter_plugin_manager_load (plugin_mgr);
} }
MutterPluginManager * static MutterPluginManager *
mutter_plugin_manager_new (MetaScreen *screen) mutter_plugin_manager_new (MetaScreen *screen)
{ {
MutterPluginManager *plugin_mgr; MutterPluginManager *plugin_mgr;
@ -349,9 +358,49 @@ mutter_plugin_manager_new (MetaScreen *screen)
plugin_mgr->screen = screen; plugin_mgr->screen = screen;
if (screen)
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", plugin_mgr);
return plugin_mgr; return plugin_mgr;
} }
MutterPluginManager *
mutter_plugin_manager_get_default (void)
{
if (!default_plugin_manager)
{
default_plugin_manager = mutter_plugin_manager_new (NULL);
}
return default_plugin_manager;
}
MutterPluginManager *
mutter_plugin_manager_get (MetaScreen *screen)
{
MutterPluginManager *plugin_mgr;
plugin_mgr = g_object_get_data (G_OBJECT (screen), "mutter-plugin-manager");
if (plugin_mgr)
return plugin_mgr;
if (!default_plugin_manager)
mutter_plugin_manager_get_default ();
if (!default_plugin_manager->screen)
{
/* The default plugin manager is so far unused, we can recycle it */
default_plugin_manager->screen = screen;
g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", default_plugin_manager);
return default_plugin_manager;
}
else
{
return mutter_plugin_manager_new (screen);
}
}
static void static void
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr, mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
MutterWindow *actor, MutterWindow *actor,

View File

@ -33,7 +33,9 @@
typedef struct MutterPluginManager MutterPluginManager; typedef struct MutterPluginManager MutterPluginManager;
MutterPluginManager * mutter_plugin_manager_new (MetaScreen *screen); MutterPluginManager * mutter_plugin_manager_get (MetaScreen *screen);
MutterPluginManager * mutter_plugin_manager_get_default (void);
gboolean mutter_plugin_manager_load (MutterPluginManager *mgr); gboolean mutter_plugin_manager_load (MutterPluginManager *mgr);
gboolean mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr); gboolean mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr);
gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr, gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr,

View File

@ -586,7 +586,7 @@ main (int argc, char **argv)
* is initialized at this point, and we don't plan to run any real * is initialized at this point, and we don't plan to run any real
* plugin code. * plugin code.
*/ */
MutterPluginManager *mgr = mutter_plugin_manager_new (NULL); MutterPluginManager *mgr = mutter_plugin_manager_get_default ();
if (!mutter_plugin_manager_load (mgr)) if (!mutter_plugin_manager_load (mgr))
g_critical ("failed to load plugins"); g_critical ("failed to load plugins");
} }

View File

@ -27,6 +27,7 @@
#include "prefs.h" #include "prefs.h"
#include "ui.h" #include "ui.h"
#include "util.h" #include "util.h"
#include "compositor/mutter-plugin-manager.h"
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
#include <gconf/gconf-client.h> #include <gconf/gconf-client.h>
#endif #endif
@ -1043,6 +1044,7 @@ meta_prefs_init (void)
#ifdef HAVE_GCONF #ifdef HAVE_GCONF
GError *err = NULL; GError *err = NULL;
gchar **gconf_dir_cursor; gchar **gconf_dir_cursor;
MutterPluginManager *plugin_manager;
if (default_client != NULL) if (default_client != NULL)
return; return;
@ -1061,12 +1063,7 @@ meta_prefs_init (void)
cleanup_error (&err); cleanup_error (&err);
} }
/* Pick up initial values. */ /* The plugin list is special and needs to be handled first */
handle_preference_init_enum ();
handle_preference_init_bool ();
handle_preference_init_string ();
handle_preference_init_int ();
if (!clutter_plugins_overridden) if (!clutter_plugins_overridden)
clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS, clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
@ -1074,6 +1071,18 @@ meta_prefs_init (void)
cleanup_error (&err); cleanup_error (&err);
/* We now initialize plugins so that they can override any preference locations */
plugin_manager = mutter_plugin_manager_get_default ();
mutter_plugin_manager_load (plugin_manager);
/* Pick up initial values. */
handle_preference_init_enum ();
handle_preference_init_bool ();
handle_preference_init_string ();
handle_preference_init_int ();
/* @@@ Is there any reason we don't do the add_dir here? */ /* @@@ Is there any reason we don't do the add_dir here? */
for (gconf_dir_cursor=gconf_dirs_we_are_interested_in; for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
*gconf_dir_cursor!=NULL; *gconf_dir_cursor!=NULL;