summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafal Mielniczuk <rafal.mielniczuk2@gmail.com>2012-03-22 22:22:04 +0100
committerKristian Høgsberg <krh@bitplanet.net>2012-03-22 22:34:11 -0400
commit2d7ab82d7407a0bfa96041421dbb62c8e87861d1 (patch)
treec1cf9653c6523cd2a0b4b98ebf7c051295da0d0c
parenta3aa9c9dd6d4e7b8d7df347ad1d5d981f43f5057 (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.
-rw-r--r--src/shell.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/shell.c b/src/shell.c
index b26cbf4..a262b4f 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);
}