[mutter] Load one copy of plugins early



commit b77b0a3d817ac75fb13f9f17829c17d238a72a02
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Apr 12 17:42:46 2010 -0400

    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

 src/compositor/compositor.c            |   14 +++++++--
 src/compositor/mutter-plugin-manager.c |   51 +++++++++++++++++++++++++++++++-
 src/compositor/mutter-plugin-manager.h |    4 ++-
 src/core/main.c                        |    2 +-
 src/core/prefs.c                       |   21 +++++++++----
 5 files changed, 80 insertions(+), 12 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 5b8563f..cee250b 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -488,9 +488,17 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
   clutter_actor_hide (info->hidden_group);
 
   info->plugin_mgr =
-    mutter_plugin_manager_new (screen);
-  if (!mutter_plugin_manager_load (info->plugin_mgr))
-    g_critical ("failed to load plugins");
+    mutter_plugin_manager_get (screen);
+
+  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))
     g_critical ("failed to initialize plugins");
 
diff --git a/src/compositor/mutter-plugin-manager.c b/src/compositor/mutter-plugin-manager.c
index 712c701..725c549 100644
--- a/src/compositor/mutter-plugin-manager.c
+++ b/src/compositor/mutter-plugin-manager.c
@@ -39,6 +39,15 @@
  */
 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);
 
 struct MutterPluginManager
@@ -334,7 +343,7 @@ mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
   return mutter_plugin_manager_load (plugin_mgr);
 }
 
-MutterPluginManager *
+static MutterPluginManager *
 mutter_plugin_manager_new (MetaScreen *screen)
 {
   MutterPluginManager *plugin_mgr;
@@ -349,9 +358,49 @@ mutter_plugin_manager_new (MetaScreen *screen)
 
   plugin_mgr->screen        = screen;
 
+  if (screen)
+    g_object_set_data (G_OBJECT (screen), "mutter-plugin-manager", 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
 mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
                                    MutterWindow        *actor,
diff --git a/src/compositor/mutter-plugin-manager.h b/src/compositor/mutter-plugin-manager.h
index e7b75de..d691e23 100644
--- a/src/compositor/mutter-plugin-manager.h
+++ b/src/compositor/mutter-plugin-manager.h
@@ -33,7 +33,9 @@
 
 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_initialize (MutterPluginManager *plugin_mgr);
 gboolean mutter_plugin_manager_event_simple (MutterPluginManager *mgr,
diff --git a/src/core/main.c b/src/core/main.c
index 0672a0f..8eae74f 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -586,7 +586,7 @@ main (int argc, char **argv)
            * is initialized at this point, and we don't plan to run any real
            * plugin code.
            */
-          MutterPluginManager *mgr = mutter_plugin_manager_new (NULL);
+          MutterPluginManager *mgr = mutter_plugin_manager_get_default ();
           if (!mutter_plugin_manager_load (mgr))
             g_critical ("failed to load plugins");
         }
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 99274d8..8ca11c8 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -27,6 +27,7 @@
 #include "prefs.h"
 #include "ui.h"
 #include "util.h"
+#include "compositor/mutter-plugin-manager.h"
 #ifdef HAVE_GCONF
 #include <gconf/gconf-client.h>
 #endif
@@ -1043,6 +1044,7 @@ meta_prefs_init (void)
 #ifdef HAVE_GCONF
   GError *err = NULL;
   gchar **gconf_dir_cursor;
+  MutterPluginManager *plugin_manager;
   
   if (default_client != NULL)
     return;
@@ -1061,12 +1063,7 @@ meta_prefs_init (void)
       cleanup_error (&err);
     }
 
-  /* Pick up initial values. */
-
-  handle_preference_init_enum ();
-  handle_preference_init_bool ();
-  handle_preference_init_string ();
-  handle_preference_init_int ();
+  /* The plugin list is special and needs to be handled first */
 
   if (!clutter_plugins_overridden)
     clutter_plugins = gconf_client_get_list (default_client, KEY_CLUTTER_PLUGINS,
@@ -1074,6 +1071,18 @@ meta_prefs_init (void)
 
   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? */
   for (gconf_dir_cursor=gconf_dirs_we_are_interested_in;
        *gconf_dir_cursor!=NULL;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]