[mutter] wayland: Scale native surfaces for hidpi



commit f9bffae9fd7cf6263427239fa8c3c2286a92b496
Author: Adel Gadllah <adel gadllah gmail com>
Date:   Sat Apr 26 12:55:54 2014 +0200

    wayland: Scale native surfaces for hidpi
    
    Scale surfaces based on output scale and the buffer scale set by them.
    We pick the scale factor of the monitor there are mostly on.
    
    We only handle native i.e non xwayland / legacy clients yet.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728902

 src/compositor/meta-surface-actor-wayland.c |   89 +++++++++++++++++++++++++++
 src/compositor/meta-surface-actor-wayland.h |    2 +
 src/compositor/meta-window-actor.c          |   11 +++
 src/wayland/meta-wayland-pointer.c          |    2 +-
 src/wayland/meta-wayland-surface.c          |    6 ++
 5 files changed, 109 insertions(+), 1 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index e0c6ff7..c553228 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)
 {
@@ -117,6 +164,44 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
 }
 
 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)
 {
   MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (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 35058cc..f820523 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 33cd547..c1628d5 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 5a3a09c..f68c29c 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 7696ff4..6a47167 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);


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