[gnome-shell/wip/wayland] Avoid calling clutter_x11_get_stage_window on Wayland



commit ce80d55568e8f261a5466642d4e9c1d04c0d759f
Author: Neil Roberts <neil linux intel com>
Date:   Mon May 28 13:55:02 2012 +0100

    Avoid calling clutter_x11_get_stage_window on Wayland
    
    This adds some hacks around places that are calling
    clutter_x11_get_stage_window so that it will be avoided when Clutter
    is not running on a X11-based backend. The backend is detected at
    run-time by querying the Cogl context. The X11 backend should not be
    affected.
    
    The hacks either just avoid doing whatever needed the window or use
    the root window instead.

 src/gnome-shell-plugin.c    |    3 +-
 src/shell-embedded-window.c |    6 +++-
 src/shell-global.c          |   33 ++++++++++++++++++++++++++-
 src/shell-global.h          |    2 +
 src/shell-tray-manager.c    |   50 ++++++++++++++++++++++++-------------------
 src/shell-xfixes-cursor.c   |   25 +++++++++++++--------
 src/st/st-im-text.c         |   25 +++++++++++++++------
 src/st/st-private.c         |   28 ++++++++++++++++++++++++
 src/st/st-private.h         |    2 +
 9 files changed, 130 insertions(+), 44 deletions(-)
---
diff --git a/src/gnome-shell-plugin.c b/src/gnome-shell-plugin.c
index 4f683a3..196823c 100644
--- a/src/gnome-shell-plugin.c
+++ b/src/gnome-shell-plugin.c
@@ -339,7 +339,8 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
     }
 #endif
 
-  if ((xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
+  if (shell_global_is_x11 (shell_plugin->global)
+      && (xev->xany.type == EnterNotify || xev->xany.type == LeaveNotify)
       && xev->xcrossing.window == clutter_x11_get_stage_window (stage))
     {
       /* If the pointer enters a child of the stage window (eg, a
diff --git a/src/shell-embedded-window.c b/src/shell-embedded-window.c
index abc29ac..52aae86 100644
--- a/src/shell-embedded-window.c
+++ b/src/shell-embedded-window.c
@@ -6,6 +6,7 @@
 #include <clutter/x11/clutter-x11.h>
 
 #include "shell-embedded-window-private.h"
+#include "shell-global.h"
 
 /* This type is a subclass of GtkWindow that ties the window to a
  * ShellGtkEmbed; the window is reparented into the stage
@@ -148,8 +149,9 @@ shell_embedded_window_set_property (GObject         *object,
   switch (prop_id)
     {
     case PROP_STAGE:
-      window->priv->stage_xwindow =
-        clutter_x11_get_stage_window (g_value_get_object (value));
+      if (shell_global_is_x11 (shell_global_get ()))
+        window->priv->stage_xwindow =
+          clutter_x11_get_stage_window (g_value_get_object (value));
       break;
 
     default:
diff --git a/src/shell-global.c b/src/shell-global.c
index 10fb0b3..c60ba3a 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -2,6 +2,9 @@
 
 #include "config.h"
 
+#define COGL_ENABLE_EXPERIMENTAL_API
+#define CLUTTER_ENABLE_EXPERIMENTAL_API
+
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -92,6 +95,10 @@ struct _ShellGlobal {
   guint32 xdnd_timestamp;
 
   gint64 last_gc_end_time;
+
+  /* TRUE if Cogl/Clutter is running on an X11-based backend (ie, not
+   * Wayland) */
+  gboolean is_x11;
 };
 
 enum {
@@ -236,6 +243,10 @@ shell_global_init (ShellGlobal *global)
   const char *datadir = g_getenv ("GNOME_SHELL_DATADIR");
   const char *shell_js = g_getenv("GNOME_SHELL_JS");
   char *imagedir, **search_path;
+  CoglContext *context;
+  CoglDisplay *display;
+  CoglRenderer *renderer;
+  CoglWinsysID winsys_id;
 
   if (!datadir)
     datadir = GNOME_SHELL_DATADIR;
@@ -280,6 +291,14 @@ shell_global_init (ShellGlobal *global)
                                      NULL);
   g_signal_connect (global->js_context, "gc", G_CALLBACK (shell_global_on_gc), global);
 
+
+  context = clutter_backend_get_cogl_context (clutter_get_default_backend ());
+  display = cogl_context_get_display (context);
+  renderer = cogl_display_get_renderer (display);
+  winsys_id = cogl_renderer_get_winsys_id (renderer);
+  global->is_x11 = (winsys_id == COGL_WINSYS_ID_EGL_XLIB ||
+                    winsys_id == COGL_WINSYS_ID_GLX);
+
   g_strfreev (search_path);
 }
 
@@ -871,7 +890,8 @@ 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)
+  if (shell_global_is_x11 (shell_global_get ()) &&
+      (event_gdk->type == GDK_KEY_PRESS || event_gdk->type == GDK_KEY_RELEASE))
     {
       ClutterActor *stage;
       Window stage_xwindow;
@@ -931,7 +951,8 @@ _shell_global_set_plugin (ShellGlobal *global,
                                                meta_screen_get_screen_number (global->meta_screen));
 
   global->stage = CLUTTER_STAGE (meta_get_stage_for_screen (global->meta_screen));
-  global->stage_xwindow = clutter_x11_get_stage_window (global->stage);
+  if (shell_global_is_x11 (shell_global_get ()))
+    global->stage_xwindow = clutter_x11_get_stage_window (global->stage);
   global->stage_gdk_window = gdk_x11_window_foreign_new_for_display (global->gdk_display,
                                                                      global->stage_xwindow);
 
@@ -1783,3 +1804,11 @@ shell_global_get_session_mode (ShellGlobal *global)
 
   return global->session_mode;
 }
+
+gboolean
+shell_global_is_x11 (ShellGlobal *global)
+{
+  g_return_val_if_fail (SHELL_IS_GLOBAL (global), FALSE);
+
+  return global->is_x11;
+}
diff --git a/src/shell-global.h b/src/shell-global.h
index 4d92995..1a1f467 100644
--- a/src/shell-global.h
+++ b/src/shell-global.h
@@ -143,6 +143,8 @@ void     shell_global_launch_calendar_server    (ShellGlobal  *global);
 
 const char *     shell_global_get_session_mode  (ShellGlobal  *global);
 
+gboolean         shell_global_is_x11            (ShellGlobal *global);
+
 G_END_DECLS
 
 #endif /* __SHELL_GLOBAL_H__ */
diff --git a/src/shell-tray-manager.c b/src/shell-tray-manager.c
index d5674c9..f16bafc 100644
--- a/src/shell-tray-manager.c
+++ b/src/shell-tray-manager.c
@@ -223,8 +223,6 @@ shell_tray_manager_manage_stage (ShellTrayManager *manager,
                                  ClutterStage     *stage,
                                  StWidget         *theme_widget)
 {
-  Window stage_xwindow;
-  GdkWindow *stage_window;
   GdkDisplay *display;
   GdkScreen *screen;
 
@@ -232,27 +230,35 @@ shell_tray_manager_manage_stage (ShellTrayManager *manager,
 
   manager->priv->stage = g_object_ref (stage);
 
-  stage_xwindow = clutter_x11_get_stage_window (stage);
-
-  /* This is a pretty ugly way to get the GdkScreen for the stage; it
-   *  will normally go through the foreign_new() case with a
-   *  round-trip to the X server, it might be nicer to pass the screen
-   *  in in some way. (The Clutter/Mutter combo is currently incapable
-   *  of multi-screen operation, so alternatively we could just assume
-   *  that clutter_x11_get_default_screen() gives us the right
-   *  screen.) We assume, in any case, that we are using the default
-   *  GDK display.
-   */
-  display = gdk_display_get_default();
-  stage_window = gdk_x11_window_lookup_for_display (display, stage_xwindow);
-  if (stage_window)
-    g_object_ref (stage_window);
+  if (shell_global_is_x11 (shell_global_get ()))
+    {
+      Window stage_xwindow;
+      GdkWindow *stage_window;
+      stage_xwindow = clutter_x11_get_stage_window (stage);
+
+      /* This is a pretty ugly way to get the GdkScreen for the stage; it
+       *  will normally go through the foreign_new() case with a
+       *  round-trip to the X server, it might be nicer to pass the screen
+       *  in in some way. (The Clutter/Mutter combo is currently incapable
+       *  of multi-screen operation, so alternatively we could just assume
+       *  that clutter_x11_get_default_screen() gives us the right
+       *  screen.) We assume, in any case, that we are using the default
+       *  GDK display.
+       */
+      display = gdk_display_get_default();
+      stage_window = gdk_x11_window_lookup_for_display (display, stage_xwindow);
+      if (stage_window)
+        g_object_ref (stage_window);
+      else
+        stage_window = gdk_x11_window_foreign_new_for_display (display,
+                                                               stage_xwindow);
+
+      screen = gdk_window_get_screen (stage_window);
+
+      g_object_unref (stage_window);
+    }
   else
-    stage_window = gdk_x11_window_foreign_new_for_display (display, stage_xwindow);
-
-  screen = gdk_window_get_screen (stage_window);
-
-  g_object_unref (stage_window);
+    screen = gdk_screen_get_default ();
 
   na_tray_manager_manage_screen (manager->priv->na_manager, screen);
 
diff --git a/src/shell-xfixes-cursor.c b/src/shell-xfixes-cursor.c
index 828925f..e8b2ec4 100644
--- a/src/shell-xfixes-cursor.c
+++ b/src/shell-xfixes-cursor.c
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 
 #include "shell-xfixes-cursor.h"
+#include "shell-global.h"
 
 #include <clutter/x11/clutter-x11.h>
 #include <X11/extensions/Xfixes.h>
@@ -119,7 +120,8 @@ xfixes_cursor_set_stage (ShellXFixesCursor *xfixes_cursor,
                                             (void *)xfixes_cursor_on_stage_destroy,
                                             xfixes_cursor);
 
-      clutter_x11_remove_filter (xfixes_cursor_event_filter, xfixes_cursor);
+      if (shell_global_is_x11 (shell_global_get ()))
+        clutter_x11_remove_filter (xfixes_cursor_event_filter, xfixes_cursor);
     }
   xfixes_cursor->stage = stage;
   if (xfixes_cursor->stage)
@@ -130,17 +132,20 @@ xfixes_cursor_set_stage (ShellXFixesCursor *xfixes_cursor,
       g_signal_connect (xfixes_cursor->stage, "destroy",
                         G_CALLBACK (xfixes_cursor_on_stage_destroy), xfixes_cursor);
 
-      clutter_x11_add_filter (xfixes_cursor_event_filter, xfixes_cursor);
+      if (shell_global_is_x11 (shell_global_get ()))
+        {
+          clutter_x11_add_filter (xfixes_cursor_event_filter, xfixes_cursor);
 
-      xfixes_cursor->have_xfixes = XFixesQueryExtension (clutter_x11_get_default_display (),
-                                                         &xfixes_cursor->xfixes_event_base,
-                                                         &error_base);
-      if (xfixes_cursor->have_xfixes)
-        XFixesSelectCursorInput (clutter_x11_get_default_display (),
-                                 clutter_x11_get_stage_window (stage),
-                                 XFixesDisplayCursorNotifyMask);
+          xfixes_cursor->have_xfixes = XFixesQueryExtension (clutter_x11_get_default_display (),
+                                                             &xfixes_cursor->xfixes_event_base,
+                                                             &error_base);
+          if (xfixes_cursor->have_xfixes)
+            XFixesSelectCursorInput (clutter_x11_get_default_display (),
+                                     clutter_x11_get_stage_window (stage),
+                                     XFixesDisplayCursorNotifyMask);
 
-      xfixes_cursor_reset_image (xfixes_cursor);
+          xfixes_cursor_reset_image (xfixes_cursor);
+        }
     }
 }
 
diff --git a/src/st/st-im-text.c b/src/st/st-im-text.c
index a3ff24d..e1520f4 100644
--- a/src/st/st-im-text.c
+++ b/src/st/st-im-text.c
@@ -65,6 +65,7 @@
 #include <X11/extensions/XKB.h>
 
 #include "st-im-text.h"
+#include "st-private.h"
 
 #define ST_IM_TEXT_GET_PRIVATE(obj)    \
         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ST_TYPE_IM_TEXT, StIMTextPrivate))
@@ -182,14 +183,24 @@ window_for_actor (ClutterActor *actor)
   Window xwindow;
   GdkWindow *window;
 
-  stage = clutter_actor_get_stage (actor);
-  xwindow = clutter_x11_get_stage_window ((ClutterStage *)stage);
-
-  window = gdk_x11_window_lookup_for_display (display, xwindow);
-  if (window)
-    g_object_ref (window);
+  /* If St is using Wayland then the clutter actor doesn't relate to a
+     GdkWindow so we'll just return the root window */
+  if (_st_is_x11 ())
+    {
+      stage = clutter_actor_get_stage (actor);
+      xwindow = clutter_x11_get_stage_window ((ClutterStage *)stage);
+
+      window = gdk_x11_window_lookup_for_display (display, xwindow);
+      if (window)
+        g_object_ref (window);
+      else
+        window = gdk_x11_window_foreign_new_for_display (display, xwindow);
+    }
   else
-    window = gdk_x11_window_foreign_new_for_display (display, xwindow);
+    {
+      GdkScreen *screen = gdk_display_get_default_screen (display);
+      window = g_object_ref (gdk_screen_get_root_window (screen));
+    }
 
   return window;
 }
diff --git a/src/st/st-private.c b/src/st/st-private.c
index bab1d3c..52d7a18 100644
--- a/src/st/st-private.c
+++ b/src/st/st-private.c
@@ -19,6 +19,9 @@
  * You should have received a copy of the GNU Lesser General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
+
+#define CLUTTER_ENABLE_EXPERIMENTAL_API
+#define COGL_ENABLE_EXPERIMENTAL_API
 #include <math.h>
 #include <string.h>
 
@@ -691,3 +694,28 @@ _st_paint_shadow_with_opacity (StShadow        *shadow_spec,
                                       shadow_box.x2, shadow_box.y2,
                                       0, 0, 1, 1);
 }
+
+gboolean
+_st_is_x11 (void)
+{
+  CoglContext *context;
+  CoglDisplay *display;
+  CoglRenderer *renderer;
+
+  /* Determines if Clutter/Cogl is running on an X11-based backend */
+
+  context =
+    clutter_backend_get_cogl_context (clutter_get_default_backend ());
+  display = cogl_context_get_display (context);
+  renderer = cogl_display_get_renderer (display);
+
+  switch (cogl_renderer_get_winsys_id (renderer))
+    {
+    case COGL_WINSYS_ID_EGL_XLIB:
+    case COGL_WINSYS_ID_GLX:
+      return TRUE;
+
+    default:
+      return FALSE;
+    }
+}
diff --git a/src/st/st-private.h b/src/st/st-private.h
index c8ee495..0f51266 100644
--- a/src/st/st-private.h
+++ b/src/st/st-private.h
@@ -79,4 +79,6 @@ void _st_paint_shadow_with_opacity (StShadow        *shadow_spec,
                                     ClutterActorBox *box,
                                     guint8           paint_opacity);
 
+gboolean _st_is_x11 (void);
+
 #endif /* __ST_PRIVATE_H__ */



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