[mutter] Move screen size and cursor setting to MetaDisplay



commit cd8f4259be62e85e6062e77237975a80af1402a3
Author: Armin Krezović <krezovic armin gmail com>
Date:   Sat Aug 26 18:37:29 2017 +0200

    Move screen size and cursor setting to MetaDisplay
    
    Split X11 specific parts into MetaX11Display. This also required
    changing MetaScreen to stop listening to any signals by itself, but
    instead relying on MetaDisplay forwarding them. This was to ensure the
    ordering. MetaDisplay listens to both the internal and external
    monitors-changed signal so that it can pass the external one via the
    redundant MetaDisplay(prev MetaScreen)::monitors-changed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=759538

 src/compositor/compositor.c        |   4 +-
 src/compositor/meta-background.c   |  33 +++--
 src/compositor/meta-window-group.c |   3 +-
 src/compositor/plugins/default.c   |  22 ++-
 src/core/display-private.h         |  14 +-
 src/core/display.c                 | 277 ++++++++++++++++++++++++++++++++-----
 src/core/edge-resistance.c         |   2 +-
 src/core/screen-private.h          |  15 +-
 src/core/screen.c                  | 243 ++------------------------------
 src/core/startup-notification.c    |   6 +-
 src/core/window.c                  |  14 +-
 src/core/workspace.c               |  14 +-
 src/meta/display.h                 |   7 +
 src/meta/screen.h                  |   7 -
 src/x11/meta-x11-display-private.h |   2 +
 src/x11/meta-x11-display.c         |  51 ++++++-
 src/x11/window-x11.c               |   4 +-
 17 files changed, 390 insertions(+), 328 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index df3cd76f5..26fb3ae9c 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -619,7 +619,7 @@ meta_shape_cow_for_window (MetaCompositor *compositor,
       window_bounds.width = rect.width;
       window_bounds.height = rect.height;
 
-      meta_screen_get_size (display->screen, &width, &height);
+      meta_display_get_size (display, &width, &height);
       screen_rect.x = 0;
       screen_rect.y = 0;
       screen_rect.width = width;
@@ -951,7 +951,7 @@ get_top_visible_window_actor (MetaCompositor *compositor)
 
       meta_window_get_buffer_rect (window, &buffer_rect);
 
-      if (meta_rectangle_overlap (&compositor->display->screen->rect,
+      if (meta_rectangle_overlap (&compositor->display->rect,
                                   &buffer_rect))
         return window_actor;
     }
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
index 61dd12095..321f406a6 100644
--- a/src/compositor/meta-background.c
+++ b/src/compositor/meta-background.c
@@ -17,6 +17,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <meta/display.h>
 #include <meta/util.h>
 #include <meta/meta-background.h>
 #include <meta/meta-background-image.h>
@@ -25,6 +26,10 @@
 
 #include <string.h>
 
+// XXX: Remove this once transition to MetaDisplay has been completed
+#include "core/display-private.h"
+#include "core/screen-private.h"
+
 enum
 {
   CHANGED,
@@ -128,8 +133,7 @@ free_wallpaper_texture (MetaBackground *self)
 }
 
 static void
-on_monitors_changed (MetaScreen     *screen,
-                     MetaBackground *self)
+invalidate_monitor_backgrounds (MetaBackground *self)
 {
   MetaBackgroundPrivate *priv = self->priv;
 
@@ -142,7 +146,7 @@ on_monitors_changed (MetaScreen     *screen,
     {
       int i;
 
-      priv->n_monitors = meta_screen_get_n_monitors (screen);
+      priv->n_monitors = meta_screen_get_n_monitors (priv->screen);
       priv->monitors = g_new0 (MetaBackgroundMonitor, priv->n_monitors);
 
       for (i = 0; i < priv->n_monitors; i++)
@@ -150,28 +154,35 @@ on_monitors_changed (MetaScreen     *screen,
     }
 }
 
+static void
+on_monitors_changed (MetaDisplay    *display,
+                     MetaBackground *self)
+{
+  invalidate_monitor_backgrounds (self);
+}
+
 static void
 set_screen (MetaBackground *self,
             MetaScreen     *screen)
 {
   MetaBackgroundPrivate *priv = self->priv;
 
-  if (priv->screen != NULL)
+  if (priv->screen != NULL && priv->screen->display != NULL)
     {
-      g_signal_handlers_disconnect_by_func (priv->screen,
+      g_signal_handlers_disconnect_by_func (priv->screen->display,
                                             (gpointer)on_monitors_changed,
                                             self);
     }
 
   g_set_object (&priv->screen, screen);
 
-  if (priv->screen != NULL)
+  if (priv->screen != NULL && priv->screen->display != NULL)
     {
-      g_signal_connect (priv->screen, "monitors-changed",
+      g_signal_connect (priv->screen->display, "monitors-changed",
                         G_CALLBACK (on_monitors_changed), self);
     }
 
-  on_monitors_changed (priv->screen, self);
+  invalidate_monitor_backgrounds (self);
 }
 
 static void
@@ -388,6 +399,7 @@ get_texture_area (MetaBackground          *self,
                   CoglTexture             *texture,
                   cairo_rectangle_int_t   *texture_area)
 {
+  MetaDisplay *display;
   MetaBackgroundPrivate *priv = self->priv;
   cairo_rectangle_int_t image_area;
   int screen_width, screen_height;
@@ -396,6 +408,7 @@ get_texture_area (MetaBackground          *self,
 
   texture_width = cogl_texture_get_width (texture);
   texture_height = cogl_texture_get_height (texture);
+  display = meta_screen_get_display (priv->screen);
 
   switch (priv->style)
     {
@@ -407,7 +420,7 @@ get_texture_area (MetaBackground          *self,
       set_texture_area_from_monitor_area (monitor_rect, texture_area);
       break;
     case G_DESKTOP_BACKGROUND_STYLE_WALLPAPER:
-      meta_screen_get_size (priv->screen, &screen_width, &screen_height);
+      meta_display_get_size (display, &screen_width, &screen_height);
 
       /* Start off by centering a tile in the middle of the
        * total screen area.
@@ -476,7 +489,7 @@ get_texture_area (MetaBackground          *self,
         /* paint region is the union of all monitors, with the origin
          * of the region set to align with monitor associated with the background.
          */
-        meta_screen_get_size (priv->screen, &screen_width, &screen_height);
+        meta_display_get_size (display, &screen_width, &screen_height);
 
         /* unclipped texture area is whole screen */
         image_area.width = screen_width;
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
index 665adee77..41b08e9fa 100644
--- a/src/compositor/meta-window-group.c
+++ b/src/compositor/meta-window-group.c
@@ -13,6 +13,7 @@
 #include "meta-window-group-private.h"
 #include "window-private.h"
 #include "meta-cullable.h"
+#include "display-private.h"
 
 struct _MetaWindowGroupClass
 {
@@ -64,7 +65,7 @@ meta_window_group_paint (ClutterActor *actor)
   MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
   ClutterActor *stage = clutter_actor_get_stage (actor);
 
-  meta_screen_get_size (window_group->screen, &screen_width, &screen_height);
+  meta_display_get_size (window_group->screen->display, &screen_width, &screen_height);
 
   /* Normally we expect an actor to be drawn at it's position on the screen.
    * However, if we're inside the paint of a ClutterClone, that won't be the
diff --git a/src/compositor/plugins/default.c b/src/compositor/plugins/default.c
index 7670b6387..5e7273611 100644
--- a/src/compositor/plugins/default.c
+++ b/src/compositor/plugins/default.c
@@ -21,6 +21,7 @@
 
 #include <config.h>
 
+#include <meta/display.h>
 #include <meta/meta-plugin.h>
 #include <meta/window.h>
 #include <meta/meta-background-group.h>
@@ -32,6 +33,9 @@
 #include <gmodule.h>
 #include <string.h>
 
+// XXX: Remove this once transition to MetaDisplay has been completed
+#include "core/display-private.h"
+
 #define DESTROY_TIMEOUT   100
 #define MINIMIZE_TIMEOUT  250
 #define MAP_TIMEOUT       250
@@ -318,9 +322,10 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
 }
 
 static void
-on_monitors_changed (MetaScreen *screen,
-                     MetaPlugin *plugin)
+on_monitors_changed (MetaDisplay *display,
+                     MetaPlugin  *plugin)
 {
+  MetaScreen *screen = display->screen;
   MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
   int i, n;
   GRand *rand = g_rand_new_with_seed (123456);
@@ -373,14 +378,15 @@ start (MetaPlugin *plugin)
 {
   MetaDefaultPlugin *self = META_DEFAULT_PLUGIN (plugin);
   MetaScreen *screen = meta_plugin_get_screen (plugin);
+  MetaDisplay *display = meta_screen_get_display (screen);
 
   self->priv->background_group = meta_background_group_new ();
   clutter_actor_insert_child_below (meta_get_window_group_for_screen (screen),
                                     self->priv->background_group, NULL);
 
-  g_signal_connect (screen, "monitors-changed",
+  g_signal_connect (display, "monitors-changed",
                     G_CALLBACK (on_monitors_changed), plugin);
-  on_monitors_changed (screen, plugin);
+  on_monitors_changed (display, plugin);
 
   clutter_actor_show (meta_get_stage_for_screen (screen));
 }
@@ -391,6 +397,7 @@ switch_workspace (MetaPlugin *plugin,
                   MetaMotionDirection direction)
 {
   MetaScreen *screen;
+  MetaDisplay *display;
   MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
   GList        *l;
   ClutterActor *workspace0  = clutter_actor_new ();
@@ -399,11 +406,12 @@ switch_workspace (MetaPlugin *plugin,
   int           screen_width, screen_height;
 
   screen = meta_plugin_get_screen (plugin);
+  display = meta_screen_get_display (screen);
   stage = meta_get_stage_for_screen (screen);
 
-  meta_screen_get_size (screen,
-                        &screen_width,
-                        &screen_height);
+  meta_display_get_size (display,
+                         &screen_width,
+                         &screen_height);
 
   clutter_actor_set_pivot_point (workspace1, 1.0, 1.0);
   clutter_actor_set_position (workspace1,
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 73da74890..9a52c4af9 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -106,6 +106,9 @@ typedef gboolean (*MetaAlarmFilter) (MetaDisplay           *display,
                                      XSyncAlarmNotifyEvent *event,
                                      gpointer               data);
 
+typedef void (* MetaDisplayWindowFunc) (MetaWindow *window,
+                                        gpointer    user_data);
+
 struct _MetaDisplay
 {
   GObject parent_instance;
@@ -260,6 +263,9 @@ struct _MetaDisplay
   ClutterActor *current_pad_osd;
 
   MetaStartupNotification *startup_notification;
+
+  MetaRectangle rect;  /* Size of screen; rect.x & rect.y are always 0 */
+  MetaCursor current_cursor;
 };
 
 struct _MetaDisplayClass
@@ -350,7 +356,8 @@ GSList*     meta_display_list_windows        (MetaDisplay          *display,
 MetaDisplay* meta_display_for_x_display  (Display     *xdisplay);
 MetaDisplay* meta_get_display            (void);
 
-void     meta_display_update_cursor (MetaDisplay *display);
+void meta_display_reload_cursor (MetaDisplay *display);
+void meta_display_update_cursor (MetaDisplay *display);
 
 void    meta_display_check_threshold_reached (MetaDisplay *display,
                                               int          x,
@@ -465,4 +472,9 @@ void meta_display_notify_pad_group_switch (MetaDisplay        *display,
                                            guint               n_mode,
                                            guint               n_modes);
 
+void meta_display_foreach_window (MetaDisplay           *display,
+                                  MetaListWindowsFlags   flags,
+                                  MetaDisplayWindowFunc  func,
+                                  gpointer               data);
+
 #endif
diff --git a/src/core/display.c b/src/core/display.c
index 03b10dc62..b8ecafbf7 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -37,6 +37,7 @@
 #include <meta/main.h>
 #include "screen-private.h"
 #include "window-private.h"
+#include "boxes-private.h"
 #include "frame.h"
 #include <meta/errors.h>
 #include "keybindings-private.h"
@@ -118,6 +119,7 @@ G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
 /* Signals */
 enum
 {
+  CURSOR_UPDATED,
   X11_DISPLAY_OPENED,
   X11_DISPLAY_CLOSING,
   OVERLAY_KEY,
@@ -136,6 +138,7 @@ enum
   SHOW_PAD_OSD,
   SHOW_OSD,
   PAD_MODE_SWITCH,
+  MONITORS_CHANGED,
   LAST_SIGNAL
 };
 
@@ -159,7 +162,11 @@ static MetaDisplay *the_display = NULL;
 static const char *gnome_wm_keybindings = "Mutter";
 static const char *net_wm_name = "Mutter";
 
-static void update_cursor_theme (void);
+static void on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
+                                          MetaDisplay        *display);
+
+static void on_monitors_changed (MetaMonitorManager *monitor_manager,
+                                 MetaDisplay        *display);
 
 static void    prefs_changed_callback    (MetaPreference pref,
                                           void          *data);
@@ -208,6 +215,14 @@ meta_display_class_init (MetaDisplayClass *klass)
   object_class->get_property = meta_display_get_property;
   object_class->set_property = meta_display_set_property;
 
+  display_signals[CURSOR_UPDATED] =
+    g_signal_new ("cursor-updated",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
   display_signals[X11_DISPLAY_OPENED] =
     g_signal_new ("x11-display-opened",
                   G_TYPE_FROM_CLASS (klass),
@@ -413,6 +428,13 @@ meta_display_class_init (MetaDisplayClass *klass)
                   G_TYPE_NONE, 3, CLUTTER_TYPE_INPUT_DEVICE,
                   G_TYPE_UINT, G_TYPE_UINT);
 
+  display_signals[MONITORS_CHANGED] =
+    g_signal_new ("monitors-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
   g_object_class_install_property (object_class,
                                    PROP_FOCUS_WINDOW,
                                    g_param_spec_object ("focus-window",
@@ -615,6 +637,8 @@ meta_display_open (void)
   int i;
   guint32 timestamp;
   Window old_active_xwindow = None;
+  MetaBackend *backend = meta_get_backend ();
+  MetaMonitorManager *monitor_manager;
 
   g_assert (the_display == NULL);
   display = the_display = g_object_new (META_TYPE_DISPLAY, NULL);
@@ -629,6 +653,9 @@ meta_display_open (void)
   display->screen = NULL;
   display->x11_display = NULL;
 
+  display->rect.x = display->rect.y = 0;
+  display->current_cursor = -1; /* invalid/unset */
+
   display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
   display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
                                                   terminal has the focus */
@@ -665,6 +692,18 @@ meta_display_open (void)
                                       g_int64_equal);
   display->wayland_windows = g_hash_table_new (NULL, NULL);
 
+  monitor_manager = meta_backend_get_monitor_manager (backend);
+  g_signal_connect (monitor_manager, "monitors-changed-internal",
+                    G_CALLBACK (on_monitors_changed_internal), display);
+  g_signal_connect (monitor_manager, "monitors-changed",
+                    G_CALLBACK (on_monitors_changed), display);
+
+  meta_monitor_manager_get_screen_size (monitor_manager,
+                                        &display->rect.width,
+                                        &display->rect.height);
+
+  meta_display_set_cursor (display, META_CURSOR_DEFAULT);
+
   x11_display = meta_x11_display_new (display, &error);
   g_assert (x11_display != NULL); /* Required, for now */
   display->x11_display = x11_display;
@@ -696,8 +735,6 @@ meta_display_open (void)
   display->xids = g_hash_table_new (meta_unsigned_long_hash,
                                         meta_unsigned_long_equal);
 
-  update_cursor_theme ();
-
   /* Create the leader window here. Set its properties and
    * use the timestamp from one of the PropertyNotify events
    * that will follow.
@@ -1623,10 +1660,126 @@ meta_cursor_for_grab_op (MetaGrabOp op)
   return META_CURSOR_DEFAULT;
 }
 
+static int
+find_highest_logical_monitor_scale (MetaBackend      *backend,
+                                    MetaCursorSprite *cursor_sprite)
+{
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
+  MetaCursorRenderer *cursor_renderer =
+    meta_backend_get_cursor_renderer (backend);
+  ClutterRect cursor_rect;
+  GList *logical_monitors;
+  GList *l;
+  int highest_scale = 0.0;
+
+  cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
+                                                     cursor_sprite);
+
+  logical_monitors =
+    meta_monitor_manager_get_logical_monitors (monitor_manager);
+  for (l = logical_monitors; l; l = l->next)
+    {
+      MetaLogicalMonitor *logical_monitor = l->data;
+      ClutterRect logical_monitor_rect =
+        meta_rectangle_to_clutter_rect (&logical_monitor->rect);
+
+      if (!clutter_rect_intersection (&cursor_rect,
+                                      &logical_monitor_rect,
+                                      NULL))
+        continue;
+
+      highest_scale = MAX (highest_scale, logical_monitor->scale);
+    }
+
+  return highest_scale;
+}
+
+static void
+root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
+                        int                      x,
+                        int                      y,
+                        MetaDisplay             *display)
+{
+  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
+  MetaBackend *backend = meta_get_backend ();
+
+  if (meta_is_stage_views_scaled ())
+    {
+      int scale;
+
+      scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
+      if (scale != 0.0)
+        {
+          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, scale);
+          meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
+        }
+    }
+  else
+    {
+      MetaMonitorManager *monitor_manager =
+        meta_backend_get_monitor_manager (backend);
+      MetaLogicalMonitor *logical_monitor;
+
+      logical_monitor =
+        meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
+
+      /* Reload the cursor texture if the scale has changed. */
+      if (logical_monitor)
+        {
+          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
+                                                      logical_monitor->scale);
+          meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
+        }
+    }
+}
+
+static void
+manage_root_cursor_sprite_scale (MetaDisplay             *display,
+                                 MetaCursorSpriteXcursor *sprite_xcursor)
+{
+  g_signal_connect_object (sprite_xcursor,
+                           "prepare-at",
+                           G_CALLBACK (root_cursor_prepare_at),
+                           display,
+                           0);
+}
+
+void
+meta_display_reload_cursor (MetaDisplay *display)
+{
+  MetaCursor cursor = display->current_cursor;
+  MetaCursorSpriteXcursor *sprite_xcursor;
+  MetaBackend *backend = meta_get_backend ();
+  MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
+
+  sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor);
+
+  if (meta_is_wayland_compositor ())
+    manage_root_cursor_sprite_scale (display, sprite_xcursor);
+
+  meta_cursor_tracker_set_root_cursor (cursor_tracker,
+                                       META_CURSOR_SPRITE (sprite_xcursor));
+  g_object_unref (sprite_xcursor);
+
+  g_signal_emit (display, display_signals[CURSOR_UPDATED], 0, display);
+}
+
+void
+meta_display_set_cursor (MetaDisplay *display,
+                         MetaCursor   cursor)
+{
+  if (cursor == display->current_cursor)
+    return;
+
+  display->current_cursor = cursor;
+  meta_display_reload_cursor (display);
+}
+
 void
 meta_display_update_cursor (MetaDisplay *display)
 {
-  meta_screen_set_cursor (display->screen, meta_cursor_for_grab_op (display->grab_op));
+  meta_display_set_cursor (display, meta_cursor_for_grab_op (display->grab_op));
 }
 
 static MetaWindow *
@@ -1974,34 +2127,6 @@ meta_display_retheme_all (void)
   meta_display_queue_retheme_all_windows (meta_get_display ());
 }
 
-static void
-set_cursor_theme (Display *xdisplay)
-{
-  XcursorSetTheme (xdisplay, meta_prefs_get_cursor_theme ());
-  XcursorSetDefaultSize (xdisplay, meta_prefs_get_cursor_size ());
-}
-
-static void
-update_cursor_theme (void)
-{
-  {
-    MetaDisplay *display = meta_get_display ();
-    set_cursor_theme (display->x11_display->xdisplay);
-
-    if (display->screen)
-      meta_screen_update_cursor (display->screen);
-  }
-
-  {
-    MetaBackend *backend = meta_get_backend ();
-    if (META_IS_BACKEND_X11 (backend))
-      {
-        Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
-        set_cursor_theme (xdisplay);
-      }
-  }
-}
-
 /*
  * Stores whether syncing is currently enabled.
  */
@@ -2589,7 +2714,7 @@ prefs_changed_callback (MetaPreference pref,
   else if (pref == META_PREF_CURSOR_THEME ||
            pref == META_PREF_CURSOR_SIZE)
     {
-      update_cursor_theme ();
+      meta_display_reload_cursor (display);
     }
 }
 
@@ -2798,6 +2923,26 @@ meta_display_get_x11_display (MetaDisplay *display)
   return display->x11_display;
 }
 
+/**
+ * meta_display_get_size:
+ * @display: A #MetaDisplay
+ * @width: (out): The width of the screen
+ * @height: (out): The height of the screen
+ *
+ * Retrieve the size of the display.
+ */
+void
+meta_display_get_size (MetaDisplay *display,
+                       int         *width,
+                       int         *height)
+{
+  if (width != NULL)
+    *width = display->rect.width;
+
+  if (height != NULL)
+    *height = display->rect.height;
+}
+
 /**
  * meta_display_get_focus_window:
  * @display: a #MetaDisplay
@@ -3077,3 +3222,69 @@ meta_display_notify_pad_group_switch (MetaDisplay        *display,
 
   g_string_free (message, TRUE);
 }
+
+void
+meta_display_foreach_window (MetaDisplay           *display,
+                             MetaListWindowsFlags   flags,
+                             MetaDisplayWindowFunc  func,
+                             gpointer               data)
+{
+  GSList *windows;
+
+  /* If we end up doing this often, just keeping a list
+   * of windows might be sensible.
+   */
+
+  windows = meta_display_list_windows (display, flags);
+
+  g_slist_foreach (windows, (GFunc) func, data);
+
+  g_slist_free (windows);
+}
+
+static void
+meta_display_resize_func (MetaWindow *window,
+                          gpointer    user_data)
+{
+  if (window->struts)
+    {
+      meta_window_update_struts (window);
+    }
+  meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
+
+  meta_window_recalc_features (window);
+}
+
+static void
+on_monitors_changed_internal (MetaMonitorManager *monitor_manager,
+                              MetaDisplay        *display)
+{
+  MetaBackend *backend;
+  MetaCursorRenderer *cursor_renderer;
+
+  meta_screen_on_monitors_changed (display->screen);
+
+  meta_monitor_manager_get_screen_size (monitor_manager,
+                                        &display->rect.width,
+                                        &display->rect.height);
+
+  /* Fix up monitor for all windows on this display */
+  meta_display_foreach_window (display, META_LIST_INCLUDE_OVERRIDE_REDIRECT,
+                               (MetaDisplayWindowFunc)
+                               meta_window_update_for_monitors_changed, 0);
+
+  /* Queue a resize on all the windows */
+  meta_display_foreach_window (display, META_LIST_DEFAULT,
+                               meta_display_resize_func, 0);
+
+  backend = meta_get_backend ();
+  cursor_renderer = meta_backend_get_cursor_renderer (backend);
+  meta_cursor_renderer_force_update (cursor_renderer);
+}
+
+static void
+on_monitors_changed (MetaMonitorManager *monitor_manager,
+                     MetaDisplay        *display)
+{
+  g_signal_emit (display, display_signals[MONITORS_CHANGED], 0);
+}
diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c
index d3636e08c..56a667842 100644
--- a/src/core/edge-resistance.c
+++ b/src/core/edge-resistance.c
@@ -1071,7 +1071,7 @@ compute_resistance_and_snapping_edges (MetaDisplay *display)
            * by other windows or DOCKS, but that's handled below).
            */
           meta_rectangle_intersect (&cur_rect,
-                                    &display->screen->rect,
+                                    &display->rect,
                                     &reduced);
 
           new_edges = NULL;
diff --git a/src/core/screen-private.h b/src/core/screen-private.h
index 99680b731..4c853f2da 100644
--- a/src/core/screen-private.h
+++ b/src/core/screen-private.h
@@ -38,9 +38,6 @@
 #include "ui.h"
 #include "meta-monitor-manager-private.h"
 
-typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
-                                       gpointer    user_data);
-
 #define META_WIREFRAME_XOR_LINE_WIDTH 2
 
 struct _MetaScreen
@@ -48,7 +45,6 @@ struct _MetaScreen
   GObject parent_instance;
 
   MetaDisplay *display;
-  MetaRectangle rect;  /* Size of screen; rect.x & rect.y are always 0 */
   MetaUI *ui;
 
   guint tile_preview_timeout_id;
@@ -66,8 +62,6 @@ struct _MetaScreen
   MetaStack *stack;
   MetaStackTracker *stack_tracker;
 
-  MetaCursor current_cursor;
-
   Window wm_sn_selection_window;
   Atom wm_sn_atom;
   guint32 wm_sn_timestamp;
@@ -104,7 +98,6 @@ struct _MetaScreenClass
 
   void (*restacked)         (MetaScreen *);
   void (*workareas_changed) (MetaScreen *);
-  void (*monitors_changed)  (MetaScreen *);
 };
 
 MetaScreen*   meta_screen_new                 (MetaDisplay                *display,
@@ -113,12 +106,6 @@ void          meta_screen_free                (MetaScreen                 *scree
                                                guint32                     timestamp);
 void          meta_screen_init_workspaces     (MetaScreen                 *screen);
 void          meta_screen_manage_all_windows  (MetaScreen                 *screen);
-void          meta_screen_foreach_window      (MetaScreen                 *screen,
-                                               MetaListWindowsFlags        flags,
-                                               MetaScreenWindowFunc        func,
-                                               gpointer                    data);
-
-void          meta_screen_update_cursor       (MetaScreen                 *screen);
 
 void          meta_screen_update_tile_preview          (MetaScreen    *screen,
                                                         gboolean       delay);
@@ -183,4 +170,6 @@ MetaLogicalMonitor * meta_screen_xinerama_index_to_logical_monitor (MetaScreen *
 int meta_screen_logical_monitor_to_xinerama_index (MetaScreen         *screen,
                                                    MetaLogicalMonitor *logical_monitor);
 
+void meta_screen_on_monitors_changed (MetaScreen *screen);
+
 #endif
diff --git a/src/core/screen.c b/src/core/screen.c
index e6ef78700..e32dfe7cc 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -72,11 +72,6 @@ static void prefs_changed_callback (MetaPreference pref,
 static void set_desktop_geometry_hint (MetaScreen *screen);
 static void set_desktop_viewport_hint (MetaScreen *screen);
 
-static void on_monitors_changed_internal (MetaMonitorManager *manager,
-                                          MetaScreen         *screen);
-static void on_monitors_changed          (MetaMonitorManager *manager,
-                                          MetaScreen         *screen);
-
 enum
 {
   PROP_N_WORKSPACES = 1,
@@ -92,7 +87,6 @@ enum
   WINDOW_LEFT_MONITOR,
   STARTUP_SEQUENCE_CHANGED,
   WORKAREAS_CHANGED,
-  MONITORS_CHANGED,
   IN_FULLSCREEN_CHANGED,
 
   LAST_SIGNAL
@@ -244,14 +238,6 @@ meta_screen_class_init (MetaScreenClass *klass)
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
-  screen_signals[MONITORS_CHANGED] =
-    g_signal_new ("monitors-changed",
-                 G_TYPE_FROM_CLASS (object_class),
-                 G_SIGNAL_RUN_LAST,
-                 G_STRUCT_OFFSET (MetaScreenClass, monitors_changed),
-          NULL, NULL, NULL,
-                 G_TYPE_NONE, 0);
-
   screen_signals[IN_FULLSCREEN_CHANGED] =
     g_signal_new ("in-fullscreen-changed",
                  G_TYPE_FROM_CLASS (object_class),
@@ -521,8 +507,8 @@ create_guard_window (Display *xdisplay, MetaScreen *screen)
                    x11_display->xroot,
                   0, /* x */
                   0, /* y */
-                  screen->rect.width,
-                  screen->rect.height,
+                   screen->display->rect.width,
+                   screen->display->rect.height,
                   0, /* border width */
                   0, /* depth */
                   InputOnly, /* class */
@@ -651,7 +637,6 @@ meta_screen_new (MetaDisplay *display,
   gboolean replace_current_wm;
   Atom wm_sn_atom;
   char buf[128];
-  MetaMonitorManager *manager;
 
   replace_current_wm = meta_get_replace_current_wm ();
 
@@ -697,19 +682,6 @@ meta_screen_new (MetaDisplay *display,
   screen->closing = 0;
 
   screen->display = display;
-  screen->rect.x = screen->rect.y = 0;
-
-  manager = meta_monitor_manager_get ();
-  g_signal_connect (manager, "monitors-changed-internal",
-                    G_CALLBACK (on_monitors_changed_internal), screen);
-  g_signal_connect (manager, "monitors-changed",
-                    G_CALLBACK (on_monitors_changed), screen);
-
-  meta_monitor_manager_get_screen_size (manager,
-                                        &screen->rect.width,
-                                        &screen->rect.height);
-
-  screen->current_cursor = -1; /* invalid/unset */
 
   screen->wm_sn_selection_window = new_wm_sn_owner;
   screen->wm_sn_atom = wm_sn_atom;
@@ -736,8 +708,6 @@ meta_screen_new (MetaDisplay *display,
 
   reload_logical_monitors (screen);
 
-  meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
-
   /* Handle creating a no_focus_window for this screen */
   screen->no_focus_window =
     meta_x11_display_create_offscreen_window (display->x11_display,
@@ -912,25 +882,6 @@ prefs_changed_callback (MetaPreference pref,
     }
 }
 
-void
-meta_screen_foreach_window (MetaScreen           *screen,
-                            MetaListWindowsFlags  flags,
-                            MetaScreenWindowFunc  func,
-                            gpointer              data)
-{
-  GSList *windows;
-
-  /* If we end up doing this often, just keeping a list
-   * of windows might be sensible.
-   */
-
-  windows = meta_display_list_windows (screen->display, flags);
-
-  g_slist_foreach (windows, (GFunc) func, data);
-
-  g_slist_free (windows);
-}
-
 int
 meta_screen_get_n_workspaces (MetaScreen *screen)
 {
@@ -988,8 +939,8 @@ set_desktop_geometry_hint (MetaScreen *screen)
   if (screen->closing > 0)
     return;
 
-  data[0] = screen->rect.width;
-  data[1] = screen->rect.height;
+  data[0] = screen->display->rect.width;
+  data[1] = screen->display->rect.height;
 
   meta_verbose ("Setting _NET_DESKTOP_GEOMETRY to %lu, %lu\n", data[0], data[1]);
 
@@ -1245,130 +1196,6 @@ update_num_workspaces (MetaScreen *screen,
   g_object_notify (G_OBJECT (screen), "n-workspaces");
 }
 
-static int
-find_highest_logical_monitor_scale (MetaBackend      *backend,
-                                    MetaCursorSprite *cursor_sprite)
-{
-  MetaMonitorManager *monitor_manager =
-    meta_backend_get_monitor_manager (backend);
-  MetaCursorRenderer *cursor_renderer =
-    meta_backend_get_cursor_renderer (backend);
-  ClutterRect cursor_rect;
-  GList *logical_monitors;
-  GList *l;
-  int highest_scale = 0.0;
-
-  cursor_rect = meta_cursor_renderer_calculate_rect (cursor_renderer,
-                                                    cursor_sprite);
-
-  logical_monitors =
-    meta_monitor_manager_get_logical_monitors (monitor_manager);
-  for (l = logical_monitors; l; l = l->next)
-    {
-      MetaLogicalMonitor *logical_monitor = l->data;
-      ClutterRect logical_monitor_rect =
-             meta_rectangle_to_clutter_rect (&logical_monitor->rect);
-
-      if (!clutter_rect_intersection (&cursor_rect,
-                                     &logical_monitor_rect,
-                                     NULL))
-        continue;
-
-      highest_scale = MAX (highest_scale, logical_monitor->scale);
-    }
-
-  return highest_scale;
-}
-
-static void
-root_cursor_prepare_at (MetaCursorSpriteXcursor *sprite_xcursor,
-                        int                      x,
-                        int                      y,
-                        MetaScreen              *screen)
-{
-  MetaBackend *backend = meta_get_backend ();
-  MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
-
-  if (meta_is_stage_views_scaled ())
-    {
-      int scale;
-
-      scale = find_highest_logical_monitor_scale (backend, cursor_sprite);
-      if (scale != 0.0)
-        {
-          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor, scale);
-          meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0 / scale);
-        }
-    }
-  else
-    {
-      MetaMonitorManager *monitor_manager =
-        meta_backend_get_monitor_manager (backend);
-      MetaLogicalMonitor *logical_monitor;
-
-      logical_monitor =
-        meta_monitor_manager_get_logical_monitor_at (monitor_manager, x, y);
-
-      /* Reload the cursor texture if the scale has changed. */
-      if (logical_monitor)
-        {
-          meta_cursor_sprite_xcursor_set_theme_scale (sprite_xcursor,
-                                                      logical_monitor->scale);
-          meta_cursor_sprite_set_texture_scale (cursor_sprite, 1.0);
-        }
-    }
-}
-
-static void
-manage_root_cursor_sprite_scale (MetaScreen              *screen,
-                                 MetaCursorSpriteXcursor *sprite_xcursor)
-{
-  g_signal_connect_object (sprite_xcursor,
-                           "prepare-at",
-                           G_CALLBACK (root_cursor_prepare_at),
-                           screen,
-                           0);
-}
-
-void
-meta_screen_update_cursor (MetaScreen *screen)
-{
-  MetaDisplay *display = screen->display;
-  MetaX11Display *x11_display = display->x11_display;
-  MetaCursor cursor = screen->current_cursor;
-  Cursor xcursor;
-  MetaCursorSpriteXcursor *sprite_xcursor;
-  MetaBackend *backend = meta_get_backend ();
-  MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
-
-  sprite_xcursor = meta_cursor_sprite_xcursor_new (cursor);
-
-  if (meta_is_wayland_compositor ())
-    manage_root_cursor_sprite_scale (screen, sprite_xcursor);
-
-  meta_cursor_tracker_set_root_cursor (cursor_tracker,
-                                       META_CURSOR_SPRITE (sprite_xcursor));
-  g_object_unref (sprite_xcursor);
-
-  /* Set a cursor for X11 applications that don't specify their own */
-  xcursor = meta_x11_display_create_x_cursor (x11_display, cursor);
-
-  XDefineCursor (x11_display->xdisplay, x11_display->xroot, xcursor);
-  XFlush (x11_display->xdisplay);
-  XFreeCursor (x11_display->xdisplay, xcursor);
-}
-
-void
-meta_screen_set_cursor (MetaScreen *screen,
-                        MetaCursor  cursor)
-{
-  if (cursor == screen->current_cursor)
-    return;
-
-  screen->current_cursor = cursor;
-  meta_screen_update_cursor (screen);
-}
-
 static gboolean
 meta_screen_update_tile_preview_timeout (gpointer data)
 {
@@ -2197,26 +2024,10 @@ meta_screen_free_workspace_layout (MetaWorkspaceLayout *layout)
   g_free (layout->grid);
 }
 
-static void
-meta_screen_resize_func (MetaWindow *window,
-                         gpointer    user_data)
-{
-  if (window->struts)
-    {
-      meta_window_update_struts (window);
-    }
-  meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
-
-  meta_window_recalc_features (window);
-}
-
-static void
-on_monitors_changed_internal (MetaMonitorManager *manager,
-                              MetaScreen         *screen)
+void
+meta_screen_on_monitors_changed (MetaScreen *screen)
 {
-  meta_monitor_manager_get_screen_size (manager,
-                                        &screen->rect.width,
-                                        &screen->rect.height);
+  MetaDisplay *display = screen->display;
 
   reload_logical_monitors (screen);
   set_desktop_geometry_hint (screen);
@@ -2228,32 +2039,18 @@ on_monitors_changed_internal (MetaMonitorManager *manager,
 
       changes.x = 0;
       changes.y = 0;
-      changes.width = screen->rect.width;
-      changes.height = screen->rect.height;
+      changes.width = display->rect.width;
+      changes.height = display->rect.height;
 
-      XConfigureWindow(screen->display->x11_display->xdisplay,
+      XConfigureWindow(display->x11_display->xdisplay,
                        screen->guard_window,
                        CWX | CWY | CWWidth | CWHeight,
                        &changes);
     }
 
-  /* Fix up monitor for all windows on this screen */
-  meta_screen_foreach_window (screen, META_LIST_INCLUDE_OVERRIDE_REDIRECT, (MetaScreenWindowFunc) 
meta_window_update_for_monitors_changed, 0);
-
-  /* Queue a resize on all the windows */
-  meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
-
   meta_screen_queue_check_fullscreen (screen);
 }
 
-static void
-on_monitors_changed (MetaMonitorManager *manager,
-                     MetaScreen         *screen)
-{
-  /* Inform the external world about what has happened */
-  g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);
-}
-
 void
 meta_screen_update_showing_desktop_hint (MetaScreen *screen)
 {
@@ -2511,26 +2308,6 @@ meta_screen_get_display (MetaScreen *screen)
   return screen->display;
 }
 
-/**
- * meta_screen_get_size:
- * @screen: A #MetaScreen
- * @width: (out): The width of the screen
- * @height: (out): The height of the screen
- *
- * Retrieve the size of the screen.
- */
-void
-meta_screen_get_size (MetaScreen *screen,
-                      int        *width,
-                      int        *height)
-{
-  if (width != NULL)
-    *width = screen->rect.width;
-
-  if (height != NULL)
-    *height = screen->rect.height;
-}
-
 void
 meta_screen_set_cm_selection (MetaScreen *screen)
 {
diff --git a/src/core/startup-notification.c b/src/core/startup-notification.c
index 4c386bba0..a6077938b 100644
--- a/src/core/startup-notification.c
+++ b/src/core/startup-notification.c
@@ -144,19 +144,19 @@ static void meta_startup_notification_ensure_timeout  (MetaStartupNotification *
 static void
 meta_startup_notification_update_feedback (MetaStartupNotification *sn)
 {
-  MetaScreen *screen = sn->display->screen;
+  MetaDisplay *display = sn->display;
 
   if (sn->startup_sequences != NULL)
     {
       meta_topic (META_DEBUG_STARTUP,
                   "Setting busy cursor\n");
-      meta_screen_set_cursor (screen, META_CURSOR_BUSY);
+      meta_display_set_cursor (display, META_CURSOR_BUSY);
     }
   else
     {
       meta_topic (META_DEBUG_STARTUP,
                   "Setting default cursor\n");
-      meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
+      meta_display_set_cursor (display, META_CURSOR_DEFAULT);
     }
 }
 
diff --git a/src/core/window.c b/src/core/window.c
index 7a46971eb..e1bac2ae8 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -2914,7 +2914,7 @@ meta_window_is_screen_sized (MetaWindow *window)
   MetaRectangle window_rect;
   int screen_width, screen_height;
 
-  meta_screen_get_size (window->screen, &screen_width, &screen_height);
+  meta_display_get_size (window->display, &screen_width, &screen_height);
   meta_window_get_frame_rect (window, &window_rect);
 
   if (window_rect.x == 0 && window_rect.y == 0 &&
@@ -5632,8 +5632,8 @@ meta_window_recalc_features (MetaWindow *window)
        * is entire screen size (kind of broken, because we
        * actually fullscreen to monitor size not screen size)
        */
-      if (window->size_hints.min_width == window->screen->rect.width &&
-          window->size_hints.min_height == window->screen->rect.height)
+      if (window->size_hints.min_width == window->display->rect.width &&
+          window->size_hints.min_height == window->display->rect.height)
         ; /* leave fullscreen available */
       else
         window->has_fullscreen_func = FALSE;
@@ -6522,8 +6522,8 @@ meta_window_get_work_area_all_monitors (MetaWindow    *window,
 {
   GList *tmp;
 
-  /* Initialize to the whole screen */
-  *area = window->screen->rect;
+  /* Initialize to the whole display */
+  *area = window->display->rect;
 
   tmp = meta_window_get_workspaces (window);
   while (tmp != NULL)
@@ -6769,8 +6769,8 @@ warp_grab_pointer (MetaWindow          *window,
   *y += rect.y;
 
   /* Avoid weird bouncing at the screen edge; see bug 154706 */
-  *x = CLAMP (*x, 0, window->screen->rect.width-1);
-  *y = CLAMP (*y, 0, window->screen->rect.height-1);
+  *x = CLAMP (*x, 0, window->display->rect.width-1);
+  *y = CLAMP (*y, 0, window->display->rect.height-1);
 
   meta_error_trap_push (display->x11_display);
 
diff --git a/src/core/workspace.c b/src/core/workspace.c
index a964e6603..24a9f92d3 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -849,13 +849,13 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
 
   workspace->screen_region =
     meta_rectangle_get_minimal_spanning_set_for_region (
-      &workspace->screen->rect,
+      &workspace->screen->display->rect,
       workspace->all_struts);
 
   /* STEP 3: Get the work areas (region-to-maximize-to) for the screen and
    *         monitors.
    */
-  work_area = workspace->screen->rect;  /* start with the screen */
+  work_area = workspace->screen->display->rect;  /* start with the screen */
   if (workspace->screen_region == NULL)
     work_area = meta_rect (0, 0, -1, -1);
   else
@@ -872,7 +872,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
                     work_area.width, MIN_SANE_AREA);
       if (work_area.width < 1)
         {
-          work_area.x = (workspace->screen->rect.width - MIN_SANE_AREA)/2;
+          work_area.x = (workspace->screen->display->rect.width - MIN_SANE_AREA)/2;
           work_area.width = MIN_SANE_AREA;
         }
       else
@@ -889,7 +889,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
                     work_area.height, MIN_SANE_AREA);
       if (work_area.height < 1)
         {
-          work_area.y = (workspace->screen->rect.height - MIN_SANE_AREA)/2;
+          work_area.y = (workspace->screen->display->rect.height - MIN_SANE_AREA)/2;
           work_area.height = MIN_SANE_AREA;
         }
       else
@@ -956,7 +956,7 @@ ensure_work_areas_validated (MetaWorkspace *workspace)
   g_assert (workspace->screen_edges    == NULL);
   g_assert (workspace->monitor_edges  == NULL);
   workspace->screen_edges =
-    meta_rectangle_find_onscreen_edges (&workspace->screen->rect,
+    meta_rectangle_find_onscreen_edges (&workspace->screen->display->rect,
                                         workspace->all_struts);
   tmp = NULL;
   for (l = logical_monitors; l; l = l->next)
@@ -1036,7 +1036,7 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
                                                                  META_SCREEN_DOWN))
             continue;
 
-          strut->rect.height = screen->rect.height - strut->rect.y;
+          strut->rect.height = screen->display->rect.height - strut->rect.y;
           break;
         case META_SIDE_LEFT:
           if (meta_monitor_manager_get_logical_monitor_neighbor (monitor_manager,
@@ -1053,7 +1053,7 @@ meta_workspace_set_builtin_struts (MetaWorkspace *workspace,
                                                                  META_SCREEN_RIGHT))
             continue;
 
-          strut->rect.width = screen->rect.width - strut->rect.x;
+          strut->rect.width = screen->display->rect.width - strut->rect.x;
           break;
         }
     }
diff --git a/src/meta/display.h b/src/meta/display.h
index fa11c259c..1a7805685 100644
--- a/src/meta/display.h
+++ b/src/meta/display.h
@@ -191,4 +191,11 @@ gchar * meta_display_get_pad_action_label (MetaDisplay        *display,
                                            MetaPadActionType   action_type,
                                            guint               action_number);
 
+void meta_display_get_size (MetaDisplay *display,
+                            int         *width,
+                            int         *height);
+
+void meta_display_set_cursor (MetaDisplay *display,
+                              MetaCursor   cursor);
+
 #endif
diff --git a/src/meta/screen.h b/src/meta/screen.h
index 42ff69700..b056be5ca 100644
--- a/src/meta/screen.h
+++ b/src/meta/screen.h
@@ -38,10 +38,6 @@ GType meta_screen_get_type (void);
 
 MetaDisplay *meta_screen_get_display (MetaScreen *screen);
 
-void meta_screen_get_size (MetaScreen *screen,
-                           int        *width,
-                           int        *height);
-
 void meta_screen_set_cm_selection (MetaScreen *screen);
 
 GSList *meta_screen_get_startup_sequences (MetaScreen *screen);
@@ -120,7 +116,4 @@ void meta_screen_override_workspace_layout (MetaScreen      *screen,
                                             int              n_rows,
                                             int              n_columns);
 
-void          meta_screen_set_cursor          (MetaScreen                 *screen,
-                                               MetaCursor                  cursor);
-
 #endif
diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h
index 731375d4a..a4d29590b 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -94,4 +94,6 @@ Window meta_x11_display_create_offscreen_window (MetaX11Display *x11_display,
 Cursor meta_x11_display_create_x_cursor (MetaX11Display *x11_display,
                                          MetaCursor      cursor);
 
+void meta_x11_display_reload_cursor (MetaX11Display *x11_display);
+
 #endif /* META_X11_DISPLAY_PRIVATE_H */
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index d05535c3c..613766022 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -47,7 +47,8 @@
 #include <X11/extensions/Xdamage.h>
 #include <X11/extensions/Xfixes.h>
 
-
+#include "backends/meta-backend-private.h"
+#include "backends/x11/meta-backend-x11.h"
 #include "core/util-private.h"
 #include "meta/errors.h"
 
@@ -60,6 +61,8 @@ G_DEFINE_TYPE (MetaX11Display, meta_x11_display, G_TYPE_OBJECT)
 static char *get_screen_name (Display *xdisplay,
                               int      number);
 
+static void update_cursor_theme (MetaX11Display *x11_display);
+
 static void
 meta_x11_display_dispose (GObject *object)
 {
@@ -386,6 +389,14 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
   query_xfixes_extension (x11_display);
   query_xi_extension (x11_display);
 
+  g_signal_connect_object (display,
+                           "cursor-updated",
+                           G_CALLBACK (update_cursor_theme),
+                           x11_display,
+                           G_CONNECT_SWAPPED);
+
+  update_cursor_theme (x11_display);
+
   return x11_display;
 }
 
@@ -507,3 +518,41 @@ get_screen_name (Display *xdisplay,
 
   return scr;
 }
+
+void
+meta_x11_display_reload_cursor (MetaX11Display *x11_display)
+{
+  Cursor xcursor;
+  MetaCursor cursor = x11_display->display->current_cursor;
+
+  /* Set a cursor for X11 applications that don't specify their own */
+  xcursor = meta_x11_display_create_x_cursor (x11_display, cursor);
+
+  XDefineCursor (x11_display->xdisplay, x11_display->xroot, xcursor);
+  XFlush (x11_display->xdisplay);
+  XFreeCursor (x11_display->xdisplay, xcursor);
+}
+
+static void
+set_cursor_theme (Display *xdisplay)
+{
+  XcursorSetTheme (xdisplay, meta_prefs_get_cursor_theme ());
+  XcursorSetDefaultSize (xdisplay, meta_prefs_get_cursor_size ());
+}
+
+static void
+update_cursor_theme (MetaX11Display *x11_display)
+{
+  MetaBackend *backend = meta_get_backend ();
+
+  set_cursor_theme (x11_display->xdisplay);
+  meta_x11_display_reload_cursor (x11_display);
+
+  if (META_IS_BACKEND_X11 (backend))
+    {
+      MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
+      Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
+
+      set_cursor_theme (xdisplay);
+    }
+}
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index d7910a1a8..e27f78f27 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -1344,7 +1344,7 @@ meta_window_x11_update_struts (MetaWindow *window)
 
               temp = g_new (MetaStrut, 1);
               temp->side = 1 << i; /* See MetaSide def.  Matches nicely, eh? */
-              temp->rect = window->screen->rect;
+              temp->rect = window->display->rect;
               switch (temp->side)
                 {
                 case META_SIDE_RIGHT:
@@ -1407,7 +1407,7 @@ meta_window_x11_update_struts (MetaWindow *window)
 
               temp = g_new (MetaStrut, 1);
               temp->side = 1 << i;
-              temp->rect = window->screen->rect;
+              temp->rect = window->display->rect;
               switch (temp->side)
                 {
                 case META_SIDE_RIGHT:


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