compositor: make position a surface transformation
Put the surface translation (absolute position) into the surface
transformations list. This allows to set additional transformations
before and after the global translation.
Having the translation cached, changing the surface x,y now requires to
set the geometry.dirty flag.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
diff --git a/src/compositor.c b/src/compositor.c
index f2fa789..27408e7 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -206,6 +206,9 @@
surface->buffer_destroy_listener.func = surface_handle_buffer_destroy;
wl_list_init(&surface->geometry.transformation_list);
+ wl_list_insert(&surface->geometry.transformation_list,
+ &surface->transform.position.link);
+ weston_matrix_init(&surface->transform.position.matrix);
surface->geometry.dirty = 1;
return surface;
@@ -239,13 +242,20 @@
surface->geometry.dirty = 0;
- if (wl_list_empty(&surface->geometry.transformation_list)) {
+ /* transform.position is always in transformation_list */
+ if (surface->geometry.transformation_list.next ==
+ &surface->transform.position.link &&
+ surface->geometry.transformation_list.prev ==
+ &surface->transform.position.link) {
surface->transform.enabled = 0;
return;
}
surface->transform.enabled = 1;
+ surface->transform.position.matrix.d[12] = surface->x;
+ surface->transform.position.matrix.d[13] = surface->y;
+
weston_matrix_init(matrix);
wl_list_for_each(tform, &surface->geometry.transformation_list, link)
weston_matrix_multiply(matrix, &tform->matrix);
@@ -267,9 +277,6 @@
if (surface->transform.enabled) {
struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
- v.f[0] += surface->x;
- v.f[1] += surface->y;
-
weston_matrix_transform(&surface->transform.matrix, &v);
if (fabsf(v.f[3]) < 1e-6) {
@@ -307,8 +314,8 @@
return;
}
- *sx = v.f[0] / v.f[3] - surface->x;
- *sy = v.f[1] / v.f[3] - surface->y;
+ *sx = v.f[0] / v.f[3];
+ *sy = v.f[1] / v.f[3];
} else {
*sx = x - surface->x;
*sy = y - surface->y;
@@ -394,6 +401,7 @@
surface->y = y;
surface->width = width;
surface->height = height;
+ surface->geometry.dirty = 1;
weston_surface_assign_output(surface);
weston_surface_damage(surface);
@@ -1231,6 +1239,7 @@
wd->sprite->x = device->x - wd->hotspot_x;
wd->sprite->y = device->y - wd->hotspot_y;
+ wd->sprite->geometry.dirty = 1;
weston_surface_damage(wd->sprite);
}
@@ -1585,6 +1594,7 @@
device->sprite->height = buffer->height;
device->sprite->x = device->input_device.x - device->hotspot_x;
device->sprite->y = device->input_device.y - device->hotspot_y;
+ device->sprite->geometry.dirty = 1;
weston_surface_damage(device->sprite);
}