[gnome-shell] Do not use the default stage



commit faff0738eb04923aa70019cf748c788959073a54
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Mon Nov 21 11:56:24 2011 -0500

    Do not use the default stage
    
    https://bugzilla.gnome.org/show_bug.cgi?id=664052

 js/ui/magnifier.js        |    2 +-
 src/gnome-shell-plugin.c  |    2 +-
 src/main.c                |  249 ---------------------------------------------
 src/shell-global.c        |  248 ++++++++++++++++++++++++++++++++++++++++++++
 src/shell-xfixes-cursor.c |   24 +++--
 src/shell-xfixes-cursor.h |    2 +-
 src/st/test-theme.c       |    2 +-
 src/test-recorder.c       |    3 +-
 8 files changed, 271 insertions(+), 261 deletions(-)
---
diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js
index daa02a7..13ac64e 100644
--- a/js/ui/magnifier.js
+++ b/js/ui/magnifier.js
@@ -44,7 +44,7 @@ const Magnifier = new Lang.Class({
         this._zoomRegions = [];
 
         // Create small clutter tree for the magnified mouse.
-        let xfixesCursor = Shell.XFixesCursor.get_default();
+        let xfixesCursor = Shell.XFixesCursor.get_for_stage(global.stage);
         this._mouseSprite = new Clutter.Texture();
         xfixesCursor.update_texture_image(this._mouseSprite);
         this._cursorRoot = new Clutter.Group();
diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c
index 4708e0a..5f3fab4 100644
--- a/src/gnome-shell-plugin.c
+++ b/src/gnome-shell-plugin.c
@@ -323,7 +323,7 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
 #endif
 
   if ((xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
-      && xev->xcrossing.window == clutter_x11_get_stage_window (CLUTTER_STAGE (clutter_stage_get_default ())))
+      && xev->xcrossing.window == clutter_x11_get_stage_window (CLUTTER_STAGE (meta_plugin_get_stage (plugin))))
     {
       /* If the pointer enters a child of the stage window (eg, a
        * trayicon), we want to consider it to still be in the stage,
diff --git a/src/main.c b/src/main.c
index 42d1446..e1e8722 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,7 +8,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include <cogl-pango/cogl-pango.h>
 #include <clutter/clutter.h>
 #include <clutter/x11/clutter-x11.h>
 #include <gdk/gdk.h>
@@ -160,157 +159,6 @@ shell_dbus_init (gboolean replace)
 }
 
 static void
-constrain_tooltip (StTooltip             *tooltip,
-                   const ClutterGeometry *geometry,
-                   ClutterGeometry       *adjusted_geometry,
-                   gpointer               data)
-{
-  const ClutterGeometry *tip_area = st_tooltip_get_tip_area (tooltip);
-  ShellGlobal *global = shell_global_get ();
-  MetaScreen *screen = shell_global_get_screen (global);
-  int n_monitors = meta_screen_get_n_monitors (screen);
-  int i;
-
-  *adjusted_geometry = *geometry;
-
-  /* A point that determines what screen we'll constrain to */
-  int x = tip_area->x + tip_area->width / 2;
-  int y = tip_area->y + tip_area->height / 2;
-
-  for (i = 0; i < n_monitors; i++)
-    {
-      MetaRectangle rect;
-      meta_screen_get_monitor_geometry (screen, i, &rect);
-      if (x >= rect.x && x < rect.x + rect.width &&
-          y >= rect.y && y < rect.y + rect.height)
-        {
-          if (adjusted_geometry->x + adjusted_geometry->width > rect.x + rect.width)
-            adjusted_geometry->x = rect.x + rect.width - adjusted_geometry->width;
-          if (adjusted_geometry->x < rect.x)
-            adjusted_geometry->x = rect.x;
-
-          if (adjusted_geometry->y + adjusted_geometry->height > rect.y + rect.height)
-            adjusted_geometry->y = rect.y + rect.height - adjusted_geometry->height;
-          if (adjusted_geometry->y < rect.y)
-            adjusted_geometry->y = rect.y;
-
-          return;
-        }
-    }
-}
-
-static void
-update_font_options (GtkSettings *settings)
-{
-  StThemeContext *context;
-  ClutterStage *stage;
-  ClutterBackend *backend;
-  gint dpi;
-  gint hinting;
-  gchar *hint_style_str;
-  cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
-  gint antialias;
-  cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
-  cairo_font_options_t *options;
-
-  g_object_get (settings,
-                "gtk-xft-dpi", &dpi,
-                "gtk-xft-antialias", &antialias,
-                "gtk-xft-hinting", &hinting,
-                "gtk-xft-hintstyle", &hint_style_str,
-                NULL);
-
-  stage = CLUTTER_STAGE (clutter_stage_get_default ());
-  context = st_theme_context_get_for_stage (stage);
-
-  if (dpi != -1)
-    /* GTK stores resolution as 1024 * dots/inch */
-    st_theme_context_set_resolution (context, dpi / 1024);
-  else
-    st_theme_context_set_default_resolution (context);
-
-  st_tooltip_set_constrain_func (stage, constrain_tooltip, NULL, NULL);
-
-  /* Clutter (as of 0.9) passes comprehensively wrong font options
-   * override whatever set_font_flags() did above.
-   *
-   * http://bugzilla.openedhand.com/show_bug.cgi?id=1456
-   */
-  backend = clutter_get_default_backend ();
-  options = cairo_font_options_create ();
-
-  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
-
-  if (hinting >= 0 && !hinting)
-    {
-      hint_style = CAIRO_HINT_STYLE_NONE;
-    }
-  else if (hint_style_str)
-    {
-      if (strcmp (hint_style_str, "hintnone") == 0)
-        hint_style = CAIRO_HINT_STYLE_NONE;
-      else if (strcmp (hint_style_str, "hintslight") == 0)
-        hint_style = CAIRO_HINT_STYLE_SLIGHT;
-      else if (strcmp (hint_style_str, "hintmedium") == 0)
-        hint_style = CAIRO_HINT_STYLE_MEDIUM;
-      else if (strcmp (hint_style_str, "hintfull") == 0)
-        hint_style = CAIRO_HINT_STYLE_FULL;
-    }
-
-  g_free (hint_style_str);
-
-  cairo_font_options_set_hint_style (options, hint_style);
-
-  /* We don't want to turn on subpixel anti-aliasing; since Clutter
-   * doesn't currently have the code to support ARGB masks,
-   * generating them then squashing them back to A8 is pointless.
-   */
-  antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
-                                                : CAIRO_ANTIALIAS_NONE;
-
-  cairo_font_options_set_antialias (options, antialias_mode);
-
-  clutter_backend_set_font_options (backend, options);
-  cairo_font_options_destroy (options);
-}
-
-static void
-settings_notify_cb (GtkSettings *settings,
-                    GParamSpec  *pspec,
-                    gpointer     data)
-{
-  update_font_options (settings);
-}
-
-static void
-shell_fonts_init (void)
-{
-  GtkSettings *settings;
-  CoglPangoFontMap *fontmap;
-
-  /* Disable text mipmapping; it causes problems on pre-GEM Intel
-   * drivers and we should just be rendering text at the right
-   * size rather than scaling it. If we do effects where we dynamically
-   * zoom labels, then we might want to reconsider.
-   */
-  fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
-  cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
-
-  settings = gtk_settings_get_default ();
-  g_object_connect (settings,
-                    "signal::notify::gtk-xft-dpi",
-                    G_CALLBACK (settings_notify_cb), NULL,
-                    "signal::notify::gtk-xft-antialias",
-                    G_CALLBACK (settings_notify_cb), NULL,
-                    "signal::notify::gtk-xft-hinting",
-                    G_CALLBACK (settings_notify_cb), NULL,
-                    "signal::notify::gtk-xft-hintstyle",
-                    G_CALLBACK (settings_notify_cb), NULL,
-                    NULL);
-  update_font_options (settings);
-}
-
-static void
 shell_prefs_init (void)
 {
   meta_prefs_override_preference_schema ("attach-modal-dialogs",
@@ -323,100 +171,6 @@ shell_prefs_init (void)
                                          OVERRIDES_SCHEMA);
 }
 
-/* This is an IBus workaround. The flow of events with IBus is that every time
- * it gets gets a key event, it:
- *
- *  Sends it to the daemon via D-Bus asynchronously
- *  When it gets an reply, synthesizes a new GdkEvent and puts it into the
- *   GDK event queue with gdk_event_put(), including
- *   IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop.
- *
- * (Normally, IBus uses the GTK+ key snooper mechanism to get the key
- * events early, but since our key events aren't visible to GTK+ key snoopers,
- * IBus will instead get the events via the standard
- * GtkIMContext.filter_keypress() mechanism.)
- *
- * There are a number of potential problems here; probably the worst
- * problem is that IBus doesn't forward the timestamp with the event
- * so that every key event that gets delivered ends up with
- * GDK_CURRENT_TIME.  This creates some very subtle bugs; for example
- * if you have IBus running and a keystroke is used to trigger
- * launching an application, focus stealing prevention won't work
- * right. http://code.google.com/p/ibus/issues/detail?id=1184
- *
- * In any case, our normal flow of key events is:
- *
- *  GDK filter function => clutter_x11_handle_event => clutter actor
- *
- * So, if we see a key event that gets delivered via the GDK event handler
- * function - then we know it must be one of these synthesized events, and
- * we should push it back to clutter.
- *
- * To summarize, the full key event flow with IBus is:
- *
- *   GDK filter function
- *     => Mutter
- *     => gnome_shell_plugin_xevent_filter()
- *     => clutter_x11_handle_event()
- *     => clutter event delivery to actor
- *     => gtk_im_context_filter_event()
- *     => sent to IBus daemon
- *     => response received from IBus daemon
- *     => gdk_event_put()
- *     => GDK event handler
- *     => <this function>
- *     => clutter_event_put()
- *     => clutter event delivery to actor
- *
- * Anything else we see here we just pass on to the normal GDK event handler
- * gtk_main_do_event().
- */
-static void
-gnome_shell_gdk_event_handler (GdkEvent *event_gdk,
-                               gpointer  data)
-{
-  if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE)
-    {
-      ClutterActor *stage;
-      Window stage_xwindow;
-
-      stage = clutter_stage_get_default ();
-      stage_xwindow = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
-
-      if (GDK_WINDOW_XID (event_gdk->key.window) == stage_xwindow)
-        {
-          ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
-          ClutterInputDevice *keyboard = clutter_device_manager_get_core_device (device_manager,
-                                                                                 CLUTTER_KEYBOARD_DEVICE);
-
-          ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ?
-                                                           CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
-          event_clutter->key.time = event_gdk->key.time;
-          event_clutter->key.flags = CLUTTER_EVENT_NONE;
-          event_clutter->key.stage = CLUTTER_STAGE (stage);
-          event_clutter->key.source = NULL;
-
-          /* This depends on ClutterModifierType and GdkModifierType being
-           * identical, which they are currently. (They both match the X
-           * modifier state in the low 16-bits and have the same extensions.) */
-          event_clutter->key.modifier_state = event_gdk->key.state;
-
-          event_clutter->key.keyval = event_gdk->key.keyval;
-          event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode;
-          event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval);
-          event_clutter->key.device = keyboard;
-
-          clutter_event_put (event_clutter);
-          clutter_event_free (event_clutter);
-
-          return;
-        }
-    }
-
-  gtk_main_do_event (event_gdk);
-}
-
-
 static void
 malloc_statistics_callback (ShellPerfLog *perf_log,
                             gpointer      data)
@@ -559,12 +313,9 @@ main (int argc, char **argv)
 
   shell_dbus_init (meta_get_replace_current_wm ());
   shell_a11y_init ();
-  shell_fonts_init ();
   shell_perf_log_init ();
   shell_prefs_init ();
 
-  gdk_event_handler_set (gnome_shell_gdk_event_handler, NULL, NULL);
-
   g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
 #if HAVE_BLUETOOTH
   g_irepository_prepend_search_path (BLUETOOTH_DIR);
diff --git a/src/shell-global.c b/src/shell-global.c
index b5f2edd..bc0faf1 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -15,6 +15,7 @@
 #endif
 
 #include <X11/extensions/Xfixes.h>
+#include <cogl-pango/cogl-pango.h>
 #include <canberra.h>
 #include <clutter/glx/clutter-glx.h>
 #include <clutter/x11/clutter-x11.h>
@@ -793,6 +794,249 @@ global_stage_after_paint (ClutterStage *stage,
                         "clutter.stagePaintDone");
 }
 
+static void
+constrain_tooltip (StTooltip             *tooltip,
+                   const ClutterGeometry *geometry,
+                   ClutterGeometry       *adjusted_geometry,
+                   gpointer               data)
+{
+  const ClutterGeometry *tip_area = st_tooltip_get_tip_area (tooltip);
+  ShellGlobal *global = shell_global_get ();
+  MetaScreen *screen = shell_global_get_screen (global);
+  int n_monitors = meta_screen_get_n_monitors (screen);
+  int i;
+
+  *adjusted_geometry = *geometry;
+
+  /* A point that determines what screen we'll constrain to */
+  int x = tip_area->x + tip_area->width / 2;
+  int y = tip_area->y + tip_area->height / 2;
+
+  for (i = 0; i < n_monitors; i++)
+    {
+      MetaRectangle rect;
+      meta_screen_get_monitor_geometry (screen, i, &rect);
+      if (x >= rect.x && x < rect.x + rect.width &&
+          y >= rect.y && y < rect.y + rect.height)
+        {
+          if (adjusted_geometry->x + adjusted_geometry->width > rect.x + rect.width)
+            adjusted_geometry->x = rect.x + rect.width - adjusted_geometry->width;
+          if (adjusted_geometry->x < rect.x)
+            adjusted_geometry->x = rect.x;
+
+          if (adjusted_geometry->y + adjusted_geometry->height > rect.y + rect.height)
+            adjusted_geometry->y = rect.y + rect.height - adjusted_geometry->height;
+          if (adjusted_geometry->y < rect.y)
+            adjusted_geometry->y = rect.y;
+
+          return;
+        }
+    }
+}
+
+static void
+update_font_options (GtkSettings  *settings,
+                     ClutterStage *stage)
+{
+  StThemeContext *context;
+  ClutterBackend *backend;
+  gint dpi;
+  gint hinting;
+  gchar *hint_style_str;
+  cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_NONE;
+  gint antialias;
+  cairo_antialias_t antialias_mode = CAIRO_ANTIALIAS_NONE;
+  cairo_font_options_t *options;
+
+  g_object_get (settings,
+                "gtk-xft-dpi", &dpi,
+                "gtk-xft-antialias", &antialias,
+                "gtk-xft-hinting", &hinting,
+                "gtk-xft-hintstyle", &hint_style_str,
+                NULL);
+
+  context = st_theme_context_get_for_stage (stage);
+
+  if (dpi != -1)
+    /* GTK stores resolution as 1024 * dots/inch */
+    st_theme_context_set_resolution (context, dpi / 1024);
+  else
+    st_theme_context_set_default_resolution (context);
+
+  st_tooltip_set_constrain_func (stage, constrain_tooltip, NULL, NULL);
+
+  /* Clutter (as of 0.9) passes comprehensively wrong font options
+   * override whatever set_font_flags() did above.
+   *
+   * http://bugzilla.openedhand.com/show_bug.cgi?id=1456
+   */
+  backend = clutter_get_default_backend ();
+  options = cairo_font_options_create ();
+
+  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
+
+  if (hinting >= 0 && !hinting)
+    {
+      hint_style = CAIRO_HINT_STYLE_NONE;
+    }
+  else if (hint_style_str)
+    {
+      if (strcmp (hint_style_str, "hintnone") == 0)
+        hint_style = CAIRO_HINT_STYLE_NONE;
+      else if (strcmp (hint_style_str, "hintslight") == 0)
+        hint_style = CAIRO_HINT_STYLE_SLIGHT;
+      else if (strcmp (hint_style_str, "hintmedium") == 0)
+        hint_style = CAIRO_HINT_STYLE_MEDIUM;
+      else if (strcmp (hint_style_str, "hintfull") == 0)
+        hint_style = CAIRO_HINT_STYLE_FULL;
+    }
+
+  g_free (hint_style_str);
+
+  cairo_font_options_set_hint_style (options, hint_style);
+
+  /* We don't want to turn on subpixel anti-aliasing; since Clutter
+   * doesn't currently have the code to support ARGB masks,
+   * generating them then squashing them back to A8 is pointless.
+   */
+  antialias_mode = (antialias < 0 || antialias) ? CAIRO_ANTIALIAS_GRAY
+                                                : CAIRO_ANTIALIAS_NONE;
+
+  cairo_font_options_set_antialias (options, antialias_mode);
+
+  clutter_backend_set_font_options (backend, options);
+  cairo_font_options_destroy (options);
+}
+
+static void
+settings_notify_cb (GtkSettings *settings,
+                    GParamSpec  *pspec,
+                    gpointer     data)
+{
+  update_font_options (settings, CLUTTER_STAGE (data));
+}
+
+static void
+shell_fonts_init (ClutterStage *stage)
+{
+  GtkSettings *settings;
+  CoglPangoFontMap *fontmap;
+
+  /* Disable text mipmapping; it causes problems on pre-GEM Intel
+   * drivers and we should just be rendering text at the right
+   * size rather than scaling it. If we do effects where we dynamically
+   * zoom labels, then we might want to reconsider.
+   */
+  fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
+  cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
+
+  settings = gtk_settings_get_default ();
+  g_object_connect (settings,
+                    "signal::notify::gtk-xft-dpi",
+                    G_CALLBACK (settings_notify_cb), stage,
+                    "signal::notify::gtk-xft-antialias",
+                    G_CALLBACK (settings_notify_cb), stage,
+                    "signal::notify::gtk-xft-hinting",
+                    G_CALLBACK (settings_notify_cb), stage,
+                    "signal::notify::gtk-xft-hintstyle",
+                    G_CALLBACK (settings_notify_cb), stage,
+                    NULL);
+  update_font_options (settings, stage);
+}
+
+/* This is an IBus workaround. The flow of events with IBus is that every time
+ * it gets gets a key event, it:
+ *
+ *  Sends it to the daemon via D-Bus asynchronously
+ *  When it gets an reply, synthesizes a new GdkEvent and puts it into the
+ *   GDK event queue with gdk_event_put(), including
+ *   IBUS_FORWARD_MASK = 1 << 25 in the state to prevent a loop.
+ *
+ * (Normally, IBus uses the GTK+ key snooper mechanism to get the key
+ * events early, but since our key events aren't visible to GTK+ key snoopers,
+ * IBus will instead get the events via the standard
+ * GtkIMContext.filter_keypress() mechanism.)
+ *
+ * There are a number of potential problems here; probably the worst
+ * problem is that IBus doesn't forward the timestamp with the event
+ * so that every key event that gets delivered ends up with
+ * GDK_CURRENT_TIME.  This creates some very subtle bugs; for example
+ * if you have IBus running and a keystroke is used to trigger
+ * launching an application, focus stealing prevention won't work
+ * right. http://code.google.com/p/ibus/issues/detail?id=1184
+ *
+ * In any case, our normal flow of key events is:
+ *
+ *  GDK filter function => clutter_x11_handle_event => clutter actor
+ *
+ * So, if we see a key event that gets delivered via the GDK event handler
+ * function - then we know it must be one of these synthesized events, and
+ * we should push it back to clutter.
+ *
+ * To summarize, the full key event flow with IBus is:
+ *
+ *   GDK filter function
+ *     => Mutter
+ *     => gnome_shell_plugin_xevent_filter()
+ *     => clutter_x11_handle_event()
+ *     => clutter event delivery to actor
+ *     => gtk_im_context_filter_event()
+ *     => sent to IBus daemon
+ *     => response received from IBus daemon
+ *     => gdk_event_put()
+ *     => GDK event handler
+ *     => <this function>
+ *     => clutter_event_put()
+ *     => clutter event delivery to actor
+ *
+ * Anything else we see here we just pass on to the normal GDK event handler
+ * gtk_main_do_event().
+ */
+static void
+gnome_shell_gdk_event_handler (GdkEvent *event_gdk,
+                               gpointer  data)
+{
+  if (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE)
+    {
+      ClutterActor *stage;
+      Window stage_xwindow;
+
+      stage = CLUTTER_ACTOR (data);
+      stage_xwindow = clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
+
+      if (GDK_WINDOW_XID (event_gdk->key.window) == stage_xwindow)
+        {
+          ClutterDeviceManager *device_manager = clutter_device_manager_get_default ();
+          ClutterInputDevice *keyboard = clutter_device_manager_get_core_device (device_manager,
+                                                                                 CLUTTER_KEYBOARD_DEVICE);
+
+          ClutterEvent *event_clutter = clutter_event_new ((event_gdk->type == GDK_KEY_PRESS) ?
+                                                           CLUTTER_KEY_PRESS : CLUTTER_KEY_RELEASE);
+          event_clutter->key.time = event_gdk->key.time;
+          event_clutter->key.flags = CLUTTER_EVENT_NONE;
+          event_clutter->key.stage = CLUTTER_STAGE (stage);
+          event_clutter->key.source = NULL;
+
+          /* This depends on ClutterModifierType and GdkModifierType being
+           * identical, which they are currently. (They both match the X
+           * modifier state in the low 16-bits and have the same extensions.) */
+          event_clutter->key.modifier_state = event_gdk->key.state;
+
+          event_clutter->key.keyval = event_gdk->key.keyval;
+          event_clutter->key.hardware_keycode = event_gdk->key.hardware_keycode;
+          event_clutter->key.unicode_value = gdk_keyval_to_unicode (event_clutter->key.keyval);
+          event_clutter->key.device = keyboard;
+
+          clutter_event_put (event_clutter);
+          clutter_event_free (event_clutter);
+
+          return;
+        }
+    }
+
+  gtk_main_do_event (event_gdk);
+}
+
 void
 _shell_global_set_plugin (ShellGlobal *global,
                           MetaPlugin  *plugin)
@@ -838,6 +1082,10 @@ _shell_global_set_plugin (ShellGlobal *global,
   g_signal_connect (global->meta_display, "notify::focus-window",
                     G_CALLBACK (focus_window_changed), global);
 
+  shell_fonts_init (global->stage);
+
+  gdk_event_handler_set (gnome_shell_gdk_event_handler, global->stage, NULL);
+
   global->focus_manager = st_focus_manager_get_for_stage (global->stage);
 }
 
diff --git a/src/shell-xfixes-cursor.c b/src/shell-xfixes-cursor.c
index fd8f2e1..4f1a363 100644
--- a/src/shell-xfixes-cursor.c
+++ b/src/shell-xfixes-cursor.c
@@ -321,19 +321,29 @@ shell_xfixes_cursor_class_init (ShellXFixesCursorClass *klass)
 }
 
 /**
- * shell_xfixes_cursor_get_default:
+ * shell_xfixes_cursor_get_for_stage:
+ * @stage: (transfer none): The #ClutterStage to get the cursor for
  *
- * Return value: (transfer none): The global #ShellXFixesCursor singleton
+ * Return value: (transfer none): A #ShellXFixesCursor instance
  */
 ShellXFixesCursor *
-shell_xfixes_cursor_get_default ()
+shell_xfixes_cursor_get_for_stage (ClutterStage *stage)
 {
-  static ShellXFixesCursor *instance = NULL;
+  ShellXFixesCursor *instance;
+  static GQuark xfixes_cursor_quark;
+
+  if (G_UNLIKELY (xfixes_cursor_quark == 0))
+    xfixes_cursor_quark = g_quark_from_static_string ("gnome-shell-xfixes-cursor");
+
+  instance = g_object_get_qdata (G_OBJECT (stage), xfixes_cursor_quark);
 
   if (instance == NULL)
-    instance = g_object_new (SHELL_TYPE_XFIXES_CURSOR,
-                             "stage", clutter_stage_get_default (),
-                             NULL);
+    {
+      instance = g_object_new (SHELL_TYPE_XFIXES_CURSOR,
+                               "stage", stage,
+                               NULL);
+      g_object_set_qdata (G_OBJECT (stage), xfixes_cursor_quark, instance);
+    }
 
   return instance;
 }
diff --git a/src/shell-xfixes-cursor.h b/src/shell-xfixes-cursor.h
index 28af3d1..d84d5aa 100644
--- a/src/shell-xfixes-cursor.h
+++ b/src/shell-xfixes-cursor.h
@@ -19,7 +19,7 @@ typedef struct _ShellXFixesCursorClass   ShellXFixesCursorClass;
 
 GType               shell_xfixes_cursor_get_type     (void) G_GNUC_CONST;
 
-ShellXFixesCursor   *shell_xfixes_cursor_get_default (void);
+ShellXFixesCursor   *shell_xfixes_cursor_get_for_stage (ClutterStage *stage);
 
 void                shell_xfixes_cursor_show (ShellXFixesCursor *xfixes_cursor);
 void                shell_xfixes_cursor_hide (ShellXFixesCursor *xfixes_cursor);
diff --git a/src/st/test-theme.c b/src/st/test-theme.c
index db7f747..73dbc93 100644
--- a/src/st/test-theme.c
+++ b/src/st/test-theme.c
@@ -432,7 +432,7 @@ main (int argc, char **argv)
   theme = st_theme_new ("st/test-theme.css",
                         NULL, NULL);
 
-  stage = clutter_stage_get_default ();
+  stage = clutter_stage_new ();
   context = st_theme_context_get_for_stage (CLUTTER_STAGE (stage));
   st_theme_context_set_theme (context, theme);
   st_theme_context_set_resolution (context, 96.);
diff --git a/src/test-recorder.c b/src/test-recorder.c
index e443322..ba5aa74 100644
--- a/src/test-recorder.c
+++ b/src/test-recorder.c
@@ -36,7 +36,8 @@ int main (int argc, char **argv)
   clutter_color_from_string (&red, "red");
   clutter_color_from_string (&green, "green");
   clutter_color_from_string (&blue, "blue");
-  stage = clutter_stage_get_default ();
+  stage = clutter_stage_new ();
+  g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
 
   text = g_object_new (CLUTTER_TYPE_TEXT,
 		       "text", "Red",



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