diff --git a/src/wayland/meta-wayland-cursor-surface.c b/src/wayland/meta-wayland-cursor-surface.c index 18a20e905..c5e05e3ad 100644 --- a/src/wayland/meta-wayland-cursor-surface.c +++ b/src/wayland/meta-wayland-cursor-surface.c @@ -313,6 +313,34 @@ meta_wayland_cursor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *role, return graphene_rect_contains_point (&logical_monitor_rect, &point); } +static MetaLogicalMonitor * +meta_wayland_cursor_surface_get_preferred_scale_monitor (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandCursorSurface *cursor_surface = + META_WAYLAND_CURSOR_SURFACE (surface_role); + MetaWaylandCursorSurfacePrivate *priv = + meta_wayland_cursor_surface_get_instance_private (cursor_surface); + MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); + MetaContext *context = + meta_wayland_compositor_get_context (surface->compositor); + MetaBackend *backend = meta_context_get_backend (context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + ClutterInputDevice *device; + graphene_point_t point; + + if (!priv->cursor_renderer) + return FALSE; + + device = meta_cursor_renderer_get_input_device (priv->cursor_renderer); + clutter_seat_query_state (clutter_input_device_get_seat (device), + device, NULL, &point, NULL); + + return meta_monitor_manager_get_logical_monitor_at (monitor_manager, + point.x, + point.y); +} + static void meta_wayland_cursor_surface_dispose (GObject *object) { @@ -407,6 +435,8 @@ meta_wayland_cursor_surface_class_init (MetaWaylandCursorSurfaceClass *klass) surface_role_class->apply_state = meta_wayland_cursor_surface_apply_state; surface_role_class->is_on_logical_monitor = meta_wayland_cursor_surface_is_on_logical_monitor; + surface_role_class->get_preferred_scale_monitor = + meta_wayland_cursor_surface_get_preferred_scale_monitor; object_class->constructed = meta_wayland_cursor_surface_constructed; object_class->dispose = meta_wayland_cursor_surface_dispose; diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c index 4d5a0283a..c1393b48f 100644 --- a/src/wayland/meta-wayland-dnd-surface.c +++ b/src/wayland/meta-wayland-dnd-surface.c @@ -129,6 +129,32 @@ dnd_surface_apply_state (MetaWaylandSurfaceRole *surface_role, surface_role_class->apply_state (surface_role, pending); } +static MetaLogicalMonitor * +dnd_surface_get_preferred_scale_monitor (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandActorSurface *actor_surface = + META_WAYLAND_ACTOR_SURFACE (surface_role); + MetaSurfaceActor *surface_actor = + meta_wayland_actor_surface_get_actor (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaContext *context = + meta_wayland_compositor_get_context (surface->compositor); + MetaBackend *backend = meta_context_get_backend (context); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + graphene_rect_t extentsf = GRAPHENE_RECT_INIT_ZERO; + MtkRectangle extents; + + clutter_actor_get_transformed_extents (CLUTTER_ACTOR (surface_actor), + &extentsf); + mtk_rectangle_from_graphene_rect (&extentsf, + MTK_ROUNDING_STRATEGY_GROW, + &extents); + return meta_monitor_manager_get_highest_scale_monitor_from_rect (monitor_manager, + &extents); +} + static MetaLogicalMonitor * dnd_surface_find_logical_monitor (MetaWaylandActorSurface *actor_surface) { @@ -226,6 +252,8 @@ meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass) surface_role_class->assigned = dnd_surface_assigned; surface_role_class->apply_state = dnd_surface_apply_state; + surface_role_class->get_preferred_scale_monitor = + dnd_surface_get_preferred_scale_monitor; actor_surface_class->get_geometry_scale = dnd_subsurface_get_geometry_scale; actor_surface_class->sync_actor_state = dnd_subsurface_sync_actor_state; diff --git a/src/wayland/meta-wayland-fractional-scale.c b/src/wayland/meta-wayland-fractional-scale.c index 395af5ec3..d0037023f 100644 --- a/src/wayland/meta-wayland-fractional-scale.c +++ b/src/wayland/meta-wayland-fractional-scale.c @@ -77,7 +77,7 @@ wp_fractional_scale_manager_get_fractional_scale (struct wl_client *client, { MetaWaylandSurface *surface; struct wl_resource *fractional_scale_resource; - double scale; + MetaLogicalMonitor *logical_monitor; surface = wl_resource_get_user_data (surface_resource); if (surface->fractional_scale.resource) @@ -104,8 +104,14 @@ wp_fractional_scale_manager_get_fractional_scale (struct wl_client *client, G_CALLBACK (on_surface_destroyed), NULL); - scale = meta_wayland_surface_get_highest_output_scale (surface); - meta_wayland_fractional_scale_maybe_send_preferred_scale (surface, scale); + logical_monitor = meta_wayland_surface_get_preferred_scale_monitor (surface); + if (logical_monitor) + { + double scale; + + scale = meta_logical_monitor_get_scale (logical_monitor); + meta_wayland_fractional_scale_maybe_send_preferred_scale (surface, scale); + } } static const struct wp_fractional_scale_manager_v1_interface meta_wayland_fractional_scale_manager_interface = { diff --git a/src/wayland/meta-wayland-shell-surface.c b/src/wayland/meta-wayland-shell-surface.c index 768e22f73..02f6d51ff 100644 --- a/src/wayland/meta-wayland-shell-surface.c +++ b/src/wayland/meta-wayland-shell-surface.c @@ -247,6 +247,20 @@ meta_wayland_shell_surface_get_window (MetaWaylandSurfaceRole *surface_role) return priv->window; } +static MetaLogicalMonitor * +meta_wayland_shell_surface_get_preferred_scale_monitor (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return NULL; + + return meta_window_get_highest_scale_monitor (window); +} + static void meta_wayland_shell_surface_notify_subsurface_state_changed (MetaWaylandSurfaceRole *surface_role) { @@ -354,6 +368,8 @@ meta_wayland_shell_surface_class_init (MetaWaylandShellSurfaceClass *klass) surface_role_class->notify_subsurface_state_changed = meta_wayland_shell_surface_notify_subsurface_state_changed; surface_role_class->get_window = meta_wayland_shell_surface_get_window; + surface_role_class->get_preferred_scale_monitor = + meta_wayland_shell_surface_get_preferred_scale_monitor; actor_surface_class->get_geometry_scale = meta_wayland_shell_surface_get_geometry_scale; diff --git a/src/wayland/meta-wayland-subsurface.c b/src/wayland/meta-wayland-subsurface.c index 230c25a8f..ae6667738 100644 --- a/src/wayland/meta-wayland-subsurface.c +++ b/src/wayland/meta-wayland-subsurface.c @@ -211,6 +211,20 @@ meta_wayland_subsurface_notify_subsurface_state_changed (MetaWaylandSurfaceRole return meta_wayland_surface_notify_subsurface_state_changed (parent); } +static MetaLogicalMonitor * +meta_wayland_subsurface_get_preferred_scale_monitor (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *parent; + + parent = surface->committed_state.parent; + if (!parent) + return NULL; + + return meta_wayland_surface_get_preferred_scale_monitor (parent); +} + static int meta_wayland_subsurface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) { @@ -269,6 +283,8 @@ meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass) surface_role_class->is_synchronized = meta_wayland_subsurface_is_synchronized; surface_role_class->notify_subsurface_state_changed = meta_wayland_subsurface_notify_subsurface_state_changed; + surface_role_class->get_preferred_scale_monitor = + meta_wayland_subsurface_get_preferred_scale_monitor; actor_surface_class->get_geometry_scale = meta_wayland_subsurface_get_geometry_scale; diff --git a/src/wayland/meta-wayland-surface-private.h b/src/wayland/meta-wayland-surface-private.h index f78f116b8..dd7acb434 100644 --- a/src/wayland/meta-wayland-surface-private.h +++ b/src/wayland/meta-wayland-surface-private.h @@ -67,6 +67,7 @@ struct _MetaWaylandSurfaceRoleClass float *out_sx, float *out_sy); MetaWindow * (*get_window) (MetaWaylandSurfaceRole *surface_role); + MetaLogicalMonitor * (*get_preferred_scale_monitor) (MetaWaylandSurfaceRole *surface_role); }; struct _MetaWaylandSurfaceState @@ -341,8 +342,6 @@ void meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface void meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface); void meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface); -double meta_wayland_surface_get_highest_output_scale (MetaWaylandSurface *surface); - void meta_wayland_surface_update_outputs (MetaWaylandSurface *surface); MetaWaylandSurface *meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface); @@ -436,6 +435,8 @@ void meta_wayland_surface_set_main_monitor (MetaWaylandSurface *surface, MetaLogicalMonitor * meta_wayland_surface_get_main_monitor (MetaWaylandSurface *surface); +MetaLogicalMonitor * meta_wayland_surface_get_preferred_scale_monitor (MetaWaylandSurface *surface); + static inline MetaWaylandSurfaceState * meta_wayland_surface_state_new (void) { diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 02c26356c..a1b99cedf 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -1501,27 +1501,6 @@ surface_output_disconnect_signals (gpointer key, surface); } -double -meta_wayland_surface_get_highest_output_scale (MetaWaylandSurface *surface) -{ - double scale = 0.0; - MetaWindow *window; - MetaLogicalMonitor *logical_monitor; - - window = meta_wayland_surface_get_window (surface); - if (!window) - goto out; - - logical_monitor = meta_window_get_highest_scale_monitor (window); - if (!logical_monitor) - goto out; - - scale = meta_logical_monitor_get_scale (logical_monitor); - -out: - return scale; -} - static MtkMonitorTransform meta_wayland_surface_get_output_transform (MetaWaylandSurface *surface) { @@ -2557,14 +2536,18 @@ static void committed_state_handle_preferred_scale_monitor (MetaWaylandSurface *surface) { MetaWaylandSurface *subsurface_surface; + MetaLogicalMonitor *logical_monitor; double scale; /* Nothing to do if the client already destroyed the wl_surface */ if (!surface->resource) return; - scale = meta_wayland_surface_get_highest_output_scale (surface); + logical_monitor = meta_wayland_surface_get_preferred_scale_monitor (surface); + if (!logical_monitor) + return; + scale = meta_logical_monitor_get_scale (logical_monitor); meta_wayland_fractional_scale_maybe_send_preferred_scale (surface, scale); if (wl_resource_get_version (surface->resource) >= @@ -2676,6 +2659,18 @@ meta_wayland_surface_get_main_monitor (MetaWaylandSurface *surface) return surface->main_monitor; } +MetaLogicalMonitor * +meta_wayland_surface_get_preferred_scale_monitor (MetaWaylandSurface *surface) +{ + MetaWaylandSurfaceRoleClass *surface_role_class; + + if (!surface->role) + return NULL; + + surface_role_class = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface->role); + return surface_role_class->get_preferred_scale_monitor (surface->role); +} + gboolean meta_wayland_surface_has_initial_commit (MetaWaylandSurface *surface) { diff --git a/src/wayland/meta-xwayland-surface.c b/src/wayland/meta-xwayland-surface.c index be0ec28bb..dcc9b1526 100644 --- a/src/wayland/meta-xwayland-surface.c +++ b/src/wayland/meta-xwayland-surface.c @@ -201,6 +201,20 @@ meta_xwayland_surface_get_window (MetaWaylandSurfaceRole *surface_role) return xwayland_surface->window; } +static MetaLogicalMonitor * +meta_xwayland_surface_get_preferred_scale_monitor (MetaWaylandSurfaceRole *surface_role) +{ + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *window; + + window = meta_wayland_surface_get_window (surface); + if (!window) + return NULL; + + return meta_window_get_highest_scale_monitor (window); +} + static int meta_xwayland_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) { @@ -258,6 +272,8 @@ meta_xwayland_surface_class_init (MetaXwaylandSurfaceClass *klass) meta_xwayland_surface_get_relative_coordinates; surface_role_class->get_toplevel = meta_xwayland_surface_get_toplevel; surface_role_class->get_window = meta_xwayland_surface_get_window; + surface_role_class->get_preferred_scale_monitor = + meta_xwayland_surface_get_preferred_scale_monitor; actor_surface_class->get_geometry_scale = meta_xwayland_surface_get_geometry_scale;