diff options
author | Rafal Mielniczuk <rafal.mielniczuk2@gmail.com> | 2012-03-22 22:22:04 +0100 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-03-22 22:34:11 -0400 |
commit | 2d7ab82d7407a0bfa96041421dbb62c8e87861d1 (patch) | |
tree | c1cf9653c6523cd2a0b4b98ebf7c051295da0d0c /src/shell.c | |
parent | a3aa9c9dd6d4e7b8d7df347ad1d5d981f43f5057 (diff) |
shell: fix matrix invertible bug in rotation handler
While activating and deactivating rotation mechanism without moving
the pointer, rotation matrix from rotate_grab object is not being
initialised and damage shell surface rotation matrix in
rotate_grab_button handler, making it invertible.
This patch initialise rotate matrix in rotate_binding
and moves surface position check to rotate_grab_motion handler.
Diffstat (limited to 'src/shell.c')
-rw-r--r-- | src/shell.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/shell.c b/src/shell.c index b26cbf4e..a262b4f6 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1241,9 +1241,10 @@ rotate_grab_motion(struct wl_pointer_grab *grab, container_of(grab, struct rotate_grab, grab); struct wl_input_device *device = grab->input_device; struct shell_surface *surface = rotate->surface; - GLfloat cx = 0.5f * surface->surface->geometry.width; - GLfloat cy = 0.5f * surface->surface->geometry.height; - GLfloat dx, dy; + struct weston_surface *base_surface = surface->surface; + GLfloat cx = 0.5f * base_surface->geometry.width; + GLfloat cy = 0.5f * base_surface->geometry.height; + GLfloat dx, dy, cposx, cposy, dposx, dposy; GLfloat r; dx = device->x - rotate->center.x; @@ -1278,6 +1279,18 @@ rotate_grab_motion(struct wl_pointer_grab *grab, weston_matrix_init(&rotate->rotation); } + /* We need to adjust the position of the surface + * in case it was resized in a rotated state before */ + cposx = base_surface->geometry.x + cx; + cposy = base_surface->geometry.y + cy; + dposx = rotate->center.x - cposx; + dposy = rotate->center.y - cposy; + if (dposx != 0.0f || dposy != 0.0f) { + weston_surface_set_position(base_surface, + base_surface->geometry.x + dposx, + base_surface->geometry.y + dposy); + } + /* Repaint implies weston_surface_update_transform(), which * lazily applies the damage due to rotation update. */ @@ -1315,7 +1328,7 @@ rotate_binding(struct wl_input_device *device, uint32_t time, (struct weston_surface *) device->pointer_focus; struct shell_surface *surface; struct rotate_grab *rotate; - GLfloat dx, dy, cx, cy, cposx, cposy, dposx, dposy; + GLfloat dx, dy; GLfloat r; if (base_surface == NULL) @@ -1361,25 +1374,17 @@ rotate_binding(struct wl_input_device *device, uint32_t time, inverse.d[1] = -inverse.d[4]; inverse.d[5] = inverse.d[0]; weston_matrix_multiply(&surface->rotation.rotation, &inverse); + + weston_matrix_init(&rotate->rotation); + rotate->rotation.d[0] = dx / r; + rotate->rotation.d[4] = -dy / r; + rotate->rotation.d[1] = -rotate->rotation.d[4]; + rotate->rotation.d[5] = rotate->rotation.d[0]; } else { weston_matrix_init(&surface->rotation.rotation); weston_matrix_init(&rotate->rotation); } - /* We need to adjust the position of the surface - * in case it was resized in a rotated state before */ - cx = 0.5f * surface->surface->geometry.width; - cy = 0.5f * surface->surface->geometry.height; - cposx = surface->surface->geometry.x + cx; - cposy = surface->surface->geometry.y + cy; - dposx = rotate->center.x - cposx; - dposy = rotate->center.y - cposy; - if (dposx != 0 || dposy != 0) { - weston_surface_set_position(base_surface, - base_surface->geometry.x + dposx, - base_surface->geometry.y + dposy); - } - wl_input_device_set_pointer_focus(device, NULL, time, 0, 0); } |