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.
This commit is contained in:
parent
a3aa9c9dd6
commit
2d7ab82d74
41
src/shell.c
41
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user