From 784a774d9cfcba39a1dc33e7af32ff7f8efed31b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 22 Aug 2018 16:22:58 +0200 Subject: [PATCH] wayland: Fix input/opaque regions calculation on hidpi Commit 6a92c6f83 unintendedly broke input/opaque region calculations on hidpi. Most visible side effect is that clicking is only allowed in the upper-left quarter of windows. The surface coordinates are returned in logical unscaled buffer size. We're however interested in actor coordinates (thus real pixels) here. As it is a bit of a detour how the scale to be applied is calculated, refactor a meta_wayland_actor_surface_get_geometry_scale() function that we can use it here, and use it consistently for surface size and the given regions. --- src/wayland/meta-wayland-actor-surface.c | 58 ++++++++++++++---------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/wayland/meta-wayland-actor-surface.c b/src/wayland/meta-wayland-actor-surface.c index 3c60ed56e..c05be63eb 100644 --- a/src/wayland/meta-wayland-actor-surface.c +++ b/src/wayland/meta-wayland-actor-surface.c @@ -99,6 +99,30 @@ queue_surface_actor_frame_callbacks (MetaSurfaceActorWayland *surface_actor, wl_list_init (&pending->frame_callback_list); } +static double +meta_wayland_actor_surface_get_geometry_scale (MetaWaylandActorSurface *actor_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (actor_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWindow *toplevel_window; + + toplevel_window = meta_wayland_surface_get_toplevel_window (surface); + if (meta_is_stage_views_scaled ()) + { + return 1; + } + else + { + if (!toplevel_window || + toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11) + return 1; + else + return meta_window_wayland_get_geometry_scale (toplevel_window); + } +} + double meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surface) { @@ -106,25 +130,12 @@ meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surfa META_WAYLAND_SURFACE_ROLE (actor_surface); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); - MetaWindow *toplevel_window; - int geometry_scale; + double geometry_scale; - toplevel_window = meta_wayland_surface_get_toplevel_window (surface); - if (meta_is_stage_views_scaled ()) - { - geometry_scale = 1; - } - else - { - if (!toplevel_window || - toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11) - geometry_scale = 1; - else - geometry_scale = - meta_window_wayland_get_geometry_scale (toplevel_window); - } + geometry_scale = + meta_wayland_actor_surface_get_geometry_scale (actor_surface); - return (double) geometry_scale / (double) surface->scale; + return geometry_scale / (double) surface->scale; } static void @@ -141,6 +152,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor double actor_scale; GList *l; cairo_rectangle_int_t surface_rect; + int geometry_scale; surface_actor = priv->actor; stex = meta_surface_actor_get_texture (surface_actor); @@ -148,20 +160,20 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor actor_scale = meta_wayland_actor_surface_calculate_scale (actor_surface); clutter_actor_set_scale (CLUTTER_ACTOR (stex), actor_scale, actor_scale); + /* Wayland surface coordinate space -> stage coordinate space */ + geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface); + surface_rect = (cairo_rectangle_int_t) { - .width = meta_wayland_surface_get_width (surface), - .height = meta_wayland_surface_get_height (surface), + .width = meta_wayland_surface_get_width (surface) * geometry_scale, + .height = meta_wayland_surface_get_height (surface) * geometry_scale, }; if (surface->input_region) { cairo_region_t *scaled_input_region; - int region_scale; - /* Wayland surface coordinate space -> stage coordinate space */ - region_scale = (int) (surface->scale * actor_scale); scaled_input_region = meta_region_scale (surface->input_region, - region_scale); + geometry_scale); cairo_region_intersect_rectangle (scaled_input_region, &surface_rect); meta_surface_actor_set_input_region (surface_actor, scaled_input_region); cairo_region_destroy (scaled_input_region);