wayland: Fix calculation of window geometry when scaled

Take the surface actor scale into account when calculating the window
geometry.

https://bugzilla.gnome.org/show_bug.cgi?id=744934
This commit is contained in:
Jonas Ådahl 2015-03-25 17:18:35 +08:00
parent db6caa2c49
commit f01247d815
3 changed files with 41 additions and 10 deletions

View File

@ -30,6 +30,7 @@
#include <cogl/cogl-wayland-server.h>
#include "meta-shaped-texture-private.h"
#include "wayland/meta-wayland-buffer.h"
#include "wayland/meta-wayland-private.h"
#include "wayland/meta-window-wayland.h"
@ -119,6 +120,30 @@ logical_to_actor_position (MetaSurfaceActorWayland *self,
*y = *y * monitor_scale;
}
/* Convert the current actor state to the corresponding subsurface rectangle
* in logical pixel coordinate space. */
void
meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
MetaRectangle *rect)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
CoglTexture *texture = surface->buffer->texture;
MetaWindow *toplevel_window;
int monitor_scale;
float x, y;
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
clutter_actor_get_position (CLUTTER_ACTOR (self), &x, &y);
*rect = (MetaRectangle) {
.x = x / monitor_scale,
.y = y / monitor_scale,
.width = cogl_texture_get_width (texture) / surface->scale,
.height = cogl_texture_get_height (texture) / surface->scale,
};
}
void
meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self)
{

View File

@ -66,6 +66,9 @@ void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
MetaRectangle *rect);
void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self);

View File

@ -188,32 +188,35 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface,
float parent_x,
float parent_y)
{
ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
MetaSurfaceActorWayland *surface_actor =
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
MetaRectangle subsurface_rect;
MetaRectangle geom;
float x, y;
GList *l;
/* Unmapped surfaces don't count. */
if (!CLUTTER_ACTOR_IS_VISIBLE (surface_actor))
if (!CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (surface_actor)))
return;
if (!surface->buffer)
return;
/* XXX: Is there a better way to do this using Clutter APIs? */
clutter_actor_get_position (surface_actor, &x, &y);
meta_surface_actor_wayland_get_subsurface_rect (surface_actor,
&subsurface_rect);
geom.x = parent_x + x;
geom.y = parent_x + y;
geom.width = cogl_texture_get_width (surface->buffer->texture);
geom.height = cogl_texture_get_height (surface->buffer->texture);
geom.x = parent_x + subsurface_rect.x;
geom.y = parent_x + subsurface_rect.y;
geom.width = subsurface_rect.width;
geom.height = subsurface_rect.height;
meta_rectangle_union (total_geometry, &geom, total_geometry);
for (l = surface->subsurfaces; l != NULL; l = l->next)
{
MetaWaylandSurface *subsurface = l->data;
calculate_surface_window_geometry (subsurface, total_geometry, x, y);
calculate_surface_window_geometry (subsurface, total_geometry,
subsurface_rect.x,
subsurface_rect.y);
}
}