[mutter] wayland: Scale native surfaces for hidpi
- From: Adel Gadllah <agadllah src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland: Scale native surfaces for hidpi
- Date: Sat, 3 May 2014 08:12:11 +0000 (UTC)
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]