shell: Rotate relative to current rotation

This avoids the surface jumping around when you start rotating it.
dev
Kristian Høgsberg 13 years ago
parent 18c93009c1
commit 765e27b9e2
  1. 42
      src/shell.c

@ -96,6 +96,7 @@ struct shell_surface {
struct { struct {
struct weston_transform transform; struct weston_transform transform;
struct weston_matrix rotation;
} rotation; } rotation;
struct { struct {
@ -118,6 +119,7 @@ struct weston_move_grab {
struct rotate_grab { struct rotate_grab {
struct wl_grab grab; struct wl_grab grab;
struct shell_surface *surface; struct shell_surface *surface;
struct weston_matrix rotation;
struct { struct {
int32_t x; int32_t x;
int32_t y; int32_t y;
@ -641,6 +643,7 @@ shell_get_shell_surface(struct wl_client *client,
/* empty when not in use */ /* empty when not in use */
wl_list_init(&shsurf->rotation.transform.link); wl_list_init(&shsurf->rotation.transform.link);
weston_matrix_init(&shsurf->rotation.rotation);
shsurf->type = SHELL_SURFACE_NONE; shsurf->type = SHELL_SURFACE_NONE;
@ -991,20 +994,20 @@ rotate_grab_motion(struct wl_grab *grab,
surface->surface->geometry.dirty = 1; surface->surface->geometry.dirty = 1;
if (r > 20.0f) { if (r > 20.0f) {
struct weston_matrix roto;
struct weston_matrix *matrix = struct weston_matrix *matrix =
&surface->rotation.transform.matrix; &surface->rotation.transform.matrix;
weston_matrix_init(&roto); weston_matrix_init(&rotate->rotation);
roto.d[0] = dx / r; rotate->rotation.d[0] = dx / r;
roto.d[4] = -dy / r; rotate->rotation.d[4] = -dy / r;
roto.d[1] = -roto.d[4]; rotate->rotation.d[1] = -rotate->rotation.d[4];
roto.d[5] = roto.d[0]; rotate->rotation.d[5] = rotate->rotation.d[0];
weston_matrix_init(matrix); weston_matrix_init(matrix);
weston_matrix_translate(matrix, -rotate->center.x, weston_matrix_translate(matrix, -rotate->center.x,
-rotate->center.y, 0.0f); -rotate->center.y, 0.0f);
weston_matrix_multiply(matrix, &roto); weston_matrix_multiply(matrix, &surface->rotation.rotation);
weston_matrix_multiply(matrix, &rotate->rotation);
weston_matrix_translate(matrix, rotate->center.x, weston_matrix_translate(matrix, rotate->center.x,
rotate->center.y, 0.0f); rotate->center.y, 0.0f);
@ -1013,6 +1016,8 @@ rotate_grab_motion(struct wl_grab *grab,
&surface->rotation.transform.link); &surface->rotation.transform.link);
} else { } else {
wl_list_init(&surface->rotation.transform.link); wl_list_init(&surface->rotation.transform.link);
weston_matrix_init(&surface->rotation.rotation);
weston_matrix_init(&rotate->rotation);
} }
weston_compositor_damage_all(surface->surface->compositor); weston_compositor_damage_all(surface->surface->compositor);
@ -1025,8 +1030,11 @@ rotate_grab_button(struct wl_grab *grab,
struct rotate_grab *rotate = struct rotate_grab *rotate =
container_of(grab, struct rotate_grab, grab); container_of(grab, struct rotate_grab, grab);
struct wl_input_device *device = grab->input_device; struct wl_input_device *device = grab->input_device;
struct shell_surface *surface = rotate->surface;
if (device->button_count == 0 && state == 0) { if (device->button_count == 0 && state == 0) {
weston_matrix_multiply(&surface->rotation.rotation,
&rotate->rotation);
wl_input_device_end_grab(device, time); wl_input_device_end_grab(device, time);
free(rotate); free(rotate);
} }
@ -1046,6 +1054,8 @@ rotate_binding(struct wl_input_device *device, uint32_t time,
(struct weston_surface *) device->pointer_focus; (struct weston_surface *) device->pointer_focus;
struct shell_surface *surface; struct shell_surface *surface;
struct rotate_grab *rotate; struct rotate_grab *rotate;
GLfloat dx, dy;
GLfloat r;
if (base_surface == NULL) if (base_surface == NULL)
return; return;
@ -1077,6 +1087,24 @@ rotate_binding(struct wl_input_device *device, uint32_t time,
&rotate->center.x, &rotate->center.y); &rotate->center.x, &rotate->center.y);
wl_input_device_start_grab(device, &rotate->grab, time); wl_input_device_start_grab(device, &rotate->grab, time);
dx = device->x - rotate->center.x;
dy = device->y - rotate->center.y;
r = sqrtf(dx * dx + dy * dy);
if (r > 20.0f) {
struct weston_matrix inverse;
weston_matrix_init(&inverse);
inverse.d[0] = dx / r;
inverse.d[4] = dy / r;
inverse.d[1] = -inverse.d[4];
inverse.d[5] = inverse.d[0];
weston_matrix_multiply(&surface->rotation.rotation, &inverse);
} else {
weston_matrix_init(&surface->rotation.rotation);
weston_matrix_init(&rotate->rotation);
}
wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0); wl_input_device_set_pointer_focus(device, NULL, time, 0, 0, 0, 0);
} }

Loading…
Cancel
Save