1
0
Fork 0

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
This commit is contained in:
Adel Gadllah 2014-04-26 12:55:54 +02:00
parent 31c925c602
commit f9bffae9fd
5 changed files with 109 additions and 1 deletions

View file

@ -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;

View file

@ -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__ */

View file

@ -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

View file

@ -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;

View file

@ -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);