diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c index e0c6ff7b7..c55322884 100644 --- a/src/compositor/meta-surface-actor-wayland.c +++ b/src/compositor/meta-surface-actor-wayland.c @@ -108,6 +108,53 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor) return FALSE; } +static int +get_output_scale (int output_id) +{ + MetaMonitorManager *monitor_manager = meta_monitor_manager_get (); + MetaOutput *outputs; + guint n_outputs, i; + int output_scale = 1; + + outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs); + + for (i = 0; i < n_outputs; i++) + { + if (outputs[i].output_id == output_id) + { + output_scale = outputs[i].scale; + break; + } + } + + return output_scale; +} + +double +meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor); + MetaWaylandSurface *surface = priv->surface; + MetaWindow *window = surface->window; + int output_scale = 1; + + while (surface) + { + if (surface->window) + { + window = surface->window; + break; + } + surface = surface->sub.parent; + } + + /* XXX: We do not handle x11 clients yet */ + if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11) + output_scale = get_output_scale (window->monitor->output_id); + + return (double)output_scale / (double)priv->surface->scale; +} + static MetaWindow * meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor) { @@ -116,6 +163,44 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor) return priv->surface->window; } +static void +meta_surface_actor_wayland_get_preferred_width (ClutterActor *self, + gfloat for_height, + gfloat *min_width_p, + gfloat *natural_width_p) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self)); + + clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex), for_height, min_width_p, natural_width_p); + + if (min_width_p) + *min_width_p *= scale; + + if (natural_width_p) + *natural_width_p *= scale; +} + +static void +meta_surface_actor_wayland_get_preferred_height (ClutterActor *self, + gfloat for_width, + gfloat *min_height_p, + gfloat *natural_height_p) +{ + MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self); + MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self)); + double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self)); + + clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex), for_width, min_height_p, natural_height_p); + + if (min_height_p) + *min_height_p *= scale; + + if (natural_height_p) + *natural_height_p *= scale; +} + static void meta_surface_actor_wayland_dispose (GObject *object) { @@ -130,8 +215,12 @@ static void meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass) { MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass); + ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); + actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width; + actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height; + surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage; surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint; surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible; diff --git a/src/compositor/meta-surface-actor-wayland.h b/src/compositor/meta-surface-actor-wayland.h index 35058ccf2..f820523fe 100644 --- a/src/compositor/meta-surface-actor-wayland.h +++ b/src/compositor/meta-surface-actor-wayland.h @@ -61,6 +61,8 @@ MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWay void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self, MetaWaylandBuffer *buffer); +double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor); + G_END_DECLS #endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */ diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c index 33cd54782..c1628d55c 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -32,6 +32,7 @@ #include "meta-surface-actor.h" #include "meta-surface-actor-x11.h" +#include "meta-surface-actor-wayland.h" #include "wayland/meta-wayland-surface.h" @@ -549,6 +550,16 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self, MetaWindowActorPrivate *priv = self->priv; cairo_region_get_extents (priv->shape_region, bounds); + + if (meta_is_wayland_compositor ()) + { + double scale = priv->surface ? + meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.; + bounds->x *= scale; + bounds->y *= scale; + bounds->width *= scale; + bounds->height *= scale; + } } static void diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 5a3a09cff..f68c29c9a 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -721,7 +721,7 @@ meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer, ClutterPoint pos; clutter_input_device_get_coords (pointer->device, NULL, &pos); - clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface->surface_actor), + clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), pos.x, pos.y, &xf, &yf); *sx = wl_fixed_from_double (xf) / surface->scale; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 7696ff4d7..6a47167b9 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -324,6 +324,7 @@ commit_pending_state (MetaWaylandSurface *surface, MetaWaylandPendingState *pending) { MetaWaylandCompositor *compositor = surface->compositor; + double output_scale; /* If this surface is a subsurface in in synchronous mode, commit * has a special-case and should not apply the pending state immediately. @@ -374,6 +375,11 @@ commit_pending_state (MetaWaylandSurface *surface, g_list_foreach (surface->subsurfaces, parent_surface_committed, NULL); + /* scale surface texture */ + output_scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (surface->surface_actor)); + clutter_actor_set_scale (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)), + output_scale, output_scale); + /* wl_surface.frame */ wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list); wl_list_init (&pending->frame_callback_list);