[mutter] meta-plugin-manager: Only allow one plugin to be loaded



commit f9454e29db8cbc27019513d6c68a3d9d08f3d4e9
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Apr 5 01:29:39 2012 -0400

    meta-plugin-manager: Only allow one plugin to be loaded
    
    The "multiple plugins loaded at once" strategy was always a big fiction:
    while it may be viable if you're super careful, it's fragile and requires
    a bit of infrastructure that we would be better off without.
    
    Note that for simplicity, we're keeping the MetaPluginManager, but it only
    manages one plugin. A possible future cleanup would be to remove it entirely.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=676855

 src/compositor/compositor.c          |    4 +-
 src/compositor/meta-plugin-manager.c |  369 ++++++++++------------------------
 src/compositor/meta-plugin-manager.h |   11 +-
 src/compositor/meta-plugin.c         |   17 --
 src/core/main.c                      |    2 +-
 src/core/mutter.c                    |    6 +-
 src/meta/meta-plugin.h               |    6 +-
 7 files changed, 114 insertions(+), 301 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index f54a22b..e0e9b71 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -557,9 +557,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 
   clutter_actor_hide (info->hidden_group);
 
-  info->plugin_mgr =
-    meta_plugin_manager_get (screen);
-  meta_plugin_manager_initialize (info->plugin_mgr);
+  info->plugin_mgr = meta_plugin_manager_new (screen);
 
   /*
    * Delay the creation of the overlay window as long as we can, to avoid
diff --git a/src/compositor/meta-plugin-manager.c b/src/compositor/meta-plugin-manager.c
index 8f03805..82cb16d 100644
--- a/src/compositor/meta-plugin-manager.c
+++ b/src/compositor/meta-plugin-manager.c
@@ -35,34 +35,32 @@
 
 #include <clutter/x11/clutter-x11.h>
 
-static GSList *plugin_types;
-
-/*
- * 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 MetaPluginManager *default_plugin_manager;
+static GType plugin_type = G_TYPE_NONE;
 
 struct MetaPluginManager
 {
-  MetaScreen   *screen;
-
-  GList /* MetaPlugin */ *plugins;  /* TODO -- maybe use hash table */
+  MetaScreen *screen;
+  MetaPlugin *plugin;
 };
 
+void
+meta_plugin_manager_set_plugin_type (GType gtype)
+{
+  if (plugin_type != G_TYPE_NONE)
+    meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
+
+  plugin_type = gtype;
+}
+
 /*
  * Loads the given plugin.
  */
 void
-meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
-                          const gchar       *plugin_name)
+meta_plugin_manager_load (const gchar       *plugin_name)
 {
   const gchar *dpath = MUTTER_PLUGIN_DIR "/";
   gchar       *path;
   MetaModule  *module;
-  GType        plugin_type;
 
   if (g_path_is_absolute (plugin_name))
     path = g_strdup (plugin_name);
@@ -81,159 +79,52 @@ meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
       exit (1);
     }
 
-  plugin_type = meta_module_get_plugin_type (module);
-  meta_plugin_manager_register (plugin_mgr, plugin_type);
+  meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
 
   g_type_module_unuse (G_TYPE_MODULE (module));
   g_free (path);
 }
 
-/*
- * Registers the given plugin type
- */
-void
-meta_plugin_manager_register (MetaPluginManager *plugin_mgr,
-                              GType              plugin_type)
-{
-  MetaPlugin  *plugin;
-
-  plugin_types = g_slist_prepend (plugin_types, GSIZE_TO_POINTER (plugin_type));
-
-  plugin = g_object_new (plugin_type, NULL);
-  plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
-}
-
-void
-meta_plugin_manager_initialize (MetaPluginManager *plugin_mgr)
-{
-  GList *iter;
-
-  if (!plugin_mgr->plugins)
-    {
-      /*
-       * If no plugins are specified, load the default plugin.
-       */
-      meta_plugin_manager_load (plugin_mgr, "default");
-    }
-
-  for (iter = plugin_mgr->plugins; iter; iter = iter->next)
-    {
-      MetaPlugin *plugin = (MetaPlugin*) iter->data;
-      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      g_object_set (plugin,
-                    "screen", plugin_mgr->screen,
-                    NULL);
-
-      if (klass->start)
-        klass->start (plugin);
-    }
-}
-
-static MetaPluginManager *
+MetaPluginManager *
 meta_plugin_manager_new (MetaScreen *screen)
 {
   MetaPluginManager *plugin_mgr;
+  MetaPlugin *plugin;
 
   plugin_mgr = g_new0 (MetaPluginManager, 1);
   plugin_mgr->screen = screen;
-
-  if (screen)
-    g_object_set_data (G_OBJECT (screen), "meta-plugin-manager", plugin_mgr);
+  plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL);
+  META_PLUGIN_GET_CLASS (plugin)->start (plugin);
 
   return plugin_mgr;
 }
 
-MetaPluginManager *
-meta_plugin_manager_get_default (void)
-{
-  if (!default_plugin_manager)
-    {
-      default_plugin_manager = meta_plugin_manager_new (NULL);
-    }
-
-  return default_plugin_manager;
-}
-
-MetaPluginManager *
-meta_plugin_manager_get (MetaScreen *screen)
-{
-  MetaPluginManager *plugin_mgr;
-
-  plugin_mgr = g_object_get_data (G_OBJECT (screen), "meta-plugin-manager");
-  if (plugin_mgr)
-    return plugin_mgr;
-
-  if (!default_plugin_manager)
-    meta_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), "meta-plugin-manager", default_plugin_manager);
-
-      return default_plugin_manager;
-    }
-  else
-    {
-      GSList *iter;
-      GType plugin_type;
-      MetaPlugin *plugin;
-
-      plugin_mgr = meta_plugin_manager_new (screen);
-
-      for (iter = plugin_types; iter; iter = iter->next)
-        {
-          plugin_type = (GType)GPOINTER_TO_SIZE (iter->data);
-          plugin = g_object_new (plugin_type, "screen", screen,  NULL);
-          plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
-        }
-
-      return plugin_mgr;
-    }
-}
-
 static void
 meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr,
                                          MetaWindowActor   *actor)
 {
-  GList *l = plugin_mgr->plugins;
-
-  while (l)
-    {
-      MetaPlugin        *plugin = l->data;
-      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      if (klass->kill_window_effects)
-        klass->kill_window_effects (plugin, actor);
+  MetaPlugin        *plugin = plugin_mgr->plugin;
+  MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 
-      l = l->next;
-    }
+  if (klass->kill_window_effects)
+    klass->kill_window_effects (plugin, actor);
 }
 
 static void
 meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
 {
-  GList *l = plugin_mgr->plugins;
-
-  while (l)
-    {
-      MetaPlugin        *plugin = l->data;
-      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      if (klass->kill_switch_workspace)
-        klass->kill_switch_workspace (plugin);
+  MetaPlugin        *plugin = plugin_mgr->plugin;
+  MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 
-      l = l->next;
-    }
+  if (klass->kill_switch_workspace)
+    klass->kill_switch_workspace (plugin);
 }
 
 /*
  * Public method that the compositor hooks into for events that require
  * no additional parameters.
  *
- * Returns TRUE if at least one of the plugins handled the event type (i.e.,
+ * Returns TRUE if the plugin handled the event type (i.e.,
  * if the return value is FALSE, there will be no subsequent call to the
  * manager completed() callback, and the compositor must ensure that any
  * appropriate post-effect cleanup is carried out.
@@ -243,55 +134,48 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
                                   MetaWindowActor   *actor,
                                   unsigned long      event)
 {
-  GList *l = plugin_mgr->plugins;
-  gboolean retval = FALSE;
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
   MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
+  gboolean retval = FALSE;
 
   if (display->display_opening)
     return FALSE;
 
-  while (l)
+  switch (event)
     {
-      MetaPlugin        *plugin = l->data;
-      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      switch (event)
+    case META_PLUGIN_MINIMIZE:
+      if (klass->minimize)
         {
-        case META_PLUGIN_MINIMIZE:
-          if (klass->minimize)
-            {
-              retval = TRUE;
-              meta_plugin_manager_kill_window_effects (plugin_mgr,
-                                                       actor);
-
-              _meta_plugin_effect_started (plugin);
-              klass->minimize (plugin, actor);
-            }
-          break;
-        case META_PLUGIN_MAP:
-          if (klass->map)
-            {
-              retval = TRUE;
-              meta_plugin_manager_kill_window_effects (plugin_mgr,
-                                                       actor);
-
-              _meta_plugin_effect_started (plugin);
-              klass->map (plugin, actor);
-            }
-          break;
-        case META_PLUGIN_DESTROY:
-          if (klass->destroy)
-            {
-              retval = TRUE;
-              _meta_plugin_effect_started (plugin);
-              klass->destroy (plugin, actor);
-            }
-          break;
-        default:
-          g_warning ("Incorrect handler called for event %lu", event);
+          retval = TRUE;
+          meta_plugin_manager_kill_window_effects (plugin_mgr,
+                                                   actor);
+
+          _meta_plugin_effect_started (plugin);
+          klass->minimize (plugin, actor);
         }
+      break;
+    case META_PLUGIN_MAP:
+      if (klass->map)
+        {
+          retval = TRUE;
+          meta_plugin_manager_kill_window_effects (plugin_mgr,
+                                                   actor);
 
-      l = l->next;
+          _meta_plugin_effect_started (plugin);
+          klass->map (plugin, actor);
+        }
+      break;
+    case META_PLUGIN_DESTROY:
+      if (klass->destroy)
+        {
+          retval = TRUE;
+          _meta_plugin_effect_started (plugin);
+          klass->destroy (plugin, actor);
+        }
+      break;
+    default:
+      g_warning ("Incorrect handler called for event %lu", event);
     }
 
   return retval;
@@ -301,7 +185,7 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
  * The public method that the compositor hooks into for maximize and unmaximize
  * events.
  *
- * Returns TRUE if at least one of the plugins handled the event type (i.e.,
+ * Returns TRUE if the plugin handled the event type (i.e.,
  * if the return value is FALSE, there will be no subsequent call to the
  * manager completed() callback, and the compositor must ensure that any
  * appropriate post-effect cleanup is carried out.
@@ -315,51 +199,44 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
                                     gint               target_width,
                                     gint               target_height)
 {
-  GList *l = plugin_mgr->plugins;
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
+  MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
   gboolean retval = FALSE;
-  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 
   if (display->display_opening)
     return FALSE;
 
-  while (l)
+  switch (event)
     {
-      MetaPlugin        *plugin = l->data;
-      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      switch (event)
+    case META_PLUGIN_MAXIMIZE:
+      if (klass->maximize)
         {
-        case META_PLUGIN_MAXIMIZE:
-          if (klass->maximize)
-            {
-              retval = TRUE;
-              meta_plugin_manager_kill_window_effects (plugin_mgr,
-                                                       actor);
-
-              _meta_plugin_effect_started (plugin);
-              klass->maximize (plugin, actor,
-                               target_x, target_y,
-                               target_width, target_height);
-            }
-          break;
-        case META_PLUGIN_UNMAXIMIZE:
-          if (klass->unmaximize)
-            {
-              retval = TRUE;
-              meta_plugin_manager_kill_window_effects (plugin_mgr,
-                                                       actor);
-
-              _meta_plugin_effect_started (plugin);
-              klass->unmaximize (plugin, actor,
-                                 target_x, target_y,
-                                 target_width, target_height);
-            }
-          break;
-        default:
-          g_warning ("Incorrect handler called for event %lu", event);
+          retval = TRUE;
+          meta_plugin_manager_kill_window_effects (plugin_mgr,
+                                                   actor);
+
+          _meta_plugin_effect_started (plugin);
+          klass->maximize (plugin, actor,
+                           target_x, target_y,
+                           target_width, target_height);
         }
+      break;
+    case META_PLUGIN_UNMAXIMIZE:
+      if (klass->unmaximize)
+        {
+          retval = TRUE;
+          meta_plugin_manager_kill_window_effects (plugin_mgr,
+                                                   actor);
 
-      l = l->next;
+          _meta_plugin_effect_started (plugin);
+          klass->unmaximize (plugin, actor,
+                             target_x, target_y,
+                             target_width, target_height);
+        }
+      break;
+    default:
+      g_warning ("Incorrect handler called for event %lu", event);
     }
 
   return retval;
@@ -368,7 +245,7 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
 /*
  * The public method that the compositor hooks into for desktop switching.
  *
- * Returns TRUE if at least one of the plugins handled the event type (i.e.,
+ * Returns TRUE if the plugin handled the event type (i.e.,
  * if the return value is FALSE, there will be no subsequent call to the
  * manager completed() callback, and the compositor must ensure that any
  * appropriate post-effect cleanup is carried out.
@@ -379,28 +256,21 @@ meta_plugin_manager_switch_workspace (MetaPluginManager   *plugin_mgr,
                                       gint                 to,
                                       MetaMotionDirection  direction)
 {
-  GList *l = plugin_mgr->plugins;
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
+  MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
   gboolean retval = FALSE;
-  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 
   if (display->display_opening)
     return FALSE;
 
-  while (l)
+  if (klass->switch_workspace)
     {
-      MetaPlugin        *plugin = l->data;
-      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      if (klass->switch_workspace)
-        {
-          retval = TRUE;
-          meta_plugin_manager_kill_switch_workspace (plugin_mgr);
-
-          _meta_plugin_effect_started (plugin);
-          klass->switch_workspace (plugin, from, to, direction);
-        }
+      retval = TRUE;
+      meta_plugin_manager_kill_switch_workspace (plugin_mgr);
 
-      l = l->next;
+      _meta_plugin_effect_started (plugin);
+      klass->switch_workspace (plugin, from, to, direction);
     }
 
   return retval;
@@ -409,7 +279,7 @@ meta_plugin_manager_switch_workspace (MetaPluginManager   *plugin_mgr,
 /*
  * The public method that the compositor hooks into for desktop switching.
  *
- * Returns TRUE if at least one of the plugins handled the event type (i.e.,
+ * Returns TRUE if the plugin handled the event type (i.e.,
  * if the return value is FALSE, there will be no subsequent call to the
  * manager completed() callback, and the compositor must ensure that any
  * appropriate post-effect cleanup is carried out.
@@ -418,49 +288,20 @@ gboolean
 meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
                                    XEvent            *xev)
 {
-  GList *l;
-  gboolean have_plugin_xevent_func;
+  MetaPlugin *plugin = plugin_mgr->plugin;
+  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 
   if (!plugin_mgr)
     return FALSE;
 
-  l = plugin_mgr->plugins;
-
   /* We need to make sure that clutter gets certain events, like
    * ConfigureNotify on the stage window. If there is a plugin that
    * provides an xevent_filter function, then it's the responsibility
    * of that plugin to pass events to Clutter. Otherwise, we send the
    * event directly to Clutter ourselves.
-   *
-   * What happens if there are two plugins with xevent_filter functions
-   * is undefined; in general, multiple competing plugins are something
-   * we don't support well or care much about.
-   *
-   * FIXME: Really, we should just always handle sending the event to
-   *  clutter if a plugin doesn't report the event as handled by
-   *  returning TRUE, but it doesn't seem worth breaking compatibility
-   *  of the plugin interface right now to achieve this; the way it is
-   *  now works fine in practice.
    */
-  have_plugin_xevent_func = FALSE;
-
-  while (l)
-    {
-      MetaPlugin      *plugin = l->data;
-      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
-
-      if (klass->xevent_filter)
-        {
-          have_plugin_xevent_func = TRUE;
-          if (klass->xevent_filter (plugin, xev) == TRUE)
-            return TRUE;
-        }
-
-      l = l->next;
-    }
-
-  if (!have_plugin_xevent_func)
+  if (klass->xevent_filter && klass->xevent_filter (plugin, xev))
+    return TRUE;
+  else
     return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
-
-  return FALSE;
 }
diff --git a/src/compositor/meta-plugin-manager.h b/src/compositor/meta-plugin-manager.h
index 0104cc8..3177fb5 100644
--- a/src/compositor/meta-plugin-manager.h
+++ b/src/compositor/meta-plugin-manager.h
@@ -46,14 +46,9 @@
  */
 typedef struct MetaPluginManager MetaPluginManager;
 
-MetaPluginManager * meta_plugin_manager_get         (MetaScreen *screen);
-MetaPluginManager * meta_plugin_manager_get_default (void);
+MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen);
 
-void     meta_plugin_manager_load         (MetaPluginManager *mgr,
-                                           const gchar       *plugin_name);
-void     meta_plugin_manager_register     (MetaPluginManager *mgr,
-                                           GType              plugin_type);
-void     meta_plugin_manager_initialize   (MetaPluginManager *mgr);
+void     meta_plugin_manager_load         (const gchar       *plugin_name);
 
 gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
                                            MetaWindowActor   *actor,
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
index fa4e6d6..8aa3f1c 100644
--- a/src/compositor/meta-plugin.c
+++ b/src/compositor/meta-plugin.c
@@ -52,7 +52,6 @@ struct _MetaPluginPrivate
   MetaScreen   *screen;
 
   gint          running;
-
   gboolean      debug    : 1;
 };
 
@@ -332,19 +331,3 @@ meta_plugin_get_screen (MetaPlugin *plugin)
 
   return priv->screen;
 }
-
-/**
- * meta_plugin_type_register:
- * @plugin_type: a #MetaPlugin type
- *
- * Register @plugin_type as a compositor plugin type to be used.
- * You must call this before calling meta_init().
- */
-void
-meta_plugin_type_register (GType plugin_type)
-{
-  MetaPluginManager *plugin_manager;
-
-  plugin_manager = meta_plugin_manager_get_default ();
-  meta_plugin_manager_register (plugin_manager, plugin_type);
-}
diff --git a/src/core/main.c b/src/core/main.c
index b6593c1..df89145 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -373,7 +373,7 @@ on_sigterm (void)
  * meta_init: (skip)
  *
  * Initialize mutter. Call this after meta_get_option_context() and
- * meta_plugin_type_register(), and before meta_run().
+ * meta_plugin_manager_set_plugin_type(), and before meta_run().
  */
 void
 meta_init (void)
diff --git a/src/core/mutter.c b/src/core/mutter.c
index 63462f9..3d94f8a 100644
--- a/src/core/mutter.c
+++ b/src/core/mutter.c
@@ -80,11 +80,7 @@ main (int argc, char **argv)
     }
 
   if (plugin)
-    {
-      MetaPluginManager *mgr;
-      mgr = meta_plugin_manager_get_default ();
-      meta_plugin_manager_load (mgr, plugin);
-    }
+    meta_plugin_manager_load (plugin);
 
   meta_init ();
   return meta_run ();
diff --git a/src/meta/meta-plugin.h b/src/meta/meta-plugin.h
index d85f71a..47b8ecb 100644
--- a/src/meta/meta-plugin.h
+++ b/src/meta/meta-plugin.h
@@ -219,9 +219,6 @@ struct _MetaPluginVersion
   }                                                                     \
 
 void
-meta_plugin_type_register (GType plugin_type);
-
-void
 meta_plugin_switch_workspace_completed (MetaPlugin *plugin);
 
 void
@@ -274,4 +271,7 @@ MetaScreen *meta_plugin_get_screen        (MetaPlugin *plugin);
 void
 _meta_plugin_effect_started (MetaPlugin *plugin);
 
+/* XXX: Putting this in here so it's in the public header. */
+void     meta_plugin_manager_set_plugin_type (GType gtype);
+
 #endif /* META_PLUGIN_H_ */



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