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 . */ +#include #include #include #include @@ -25,6 +26,10 @@ #include +// 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 +#include #include #include #include @@ -32,6 +33,9 @@ #include #include +// 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 #include "screen-private.h" #include "window-private.h" +#include "boxes-private.h" #include "frame.h" #include #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) +void +meta_screen_on_monitors_changed (MetaScreen *screen) { - 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) -{ - 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 #include - +#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: