[PATCH 4/8] compositor: Don't let pointers get outside of an output on mode switch
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Fri Dec 14 07:37:26 PST 2012
From: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
When an output suffers a mode switch, it is possible that a pointer
was inside the old output area but falls outside of it with the new
size. In that case, move the cursor to the output's bottom-right
corner. Otherwise, there's a crash in clip_pointer_motion().
---
src/compositor.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/src/compositor.c b/src/compositor.c
index 567105e..e556766 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -90,6 +90,8 @@ weston_output_transform_init(struct weston_output *output, uint32_t transform);
WL_EXPORT int
weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode)
{
+ struct weston_seat *seat;
+ pixman_region32_t old_output_region;
int ret;
if (!output->switch_mode)
@@ -99,6 +101,9 @@ weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode
if (ret < 0)
return ret;
+ pixman_region32_init(&old_output_region);
+ pixman_region32_copy(&old_output_region, &output->region);
+
/* Update output region and transformation matrix */
weston_output_transform_init(output, output->transform);
@@ -108,6 +113,35 @@ weston_output_switch_mode(struct weston_output *output, struct weston_mode *mode
weston_output_update_matrix(output);
+ /* If a pointer falls outside the outputs new geometry, move it to its
+ * lower-right corner */
+ wl_list_for_each(seat, &output->compositor->seat_list, link) {
+ struct wl_pointer *pointer = seat->seat.pointer;
+ int32_t x, y;
+
+ if (!pointer)
+ continue;
+
+ x = wl_fixed_to_int(pointer->x);
+ y = wl_fixed_to_int(pointer->y);
+
+ if (!pixman_region32_contains_point(&old_output_region,
+ x, y, NULL) ||
+ pixman_region32_contains_point(&output->region,
+ x, y, NULL))
+ continue;
+
+ if (x >= output->x + output->width)
+ x = output->x + output->width - 1;
+ if (y >= output->y + output->height)
+ y = output->y + output->height - 1;
+
+ pointer->x = wl_fixed_from_int(x);
+ pointer->y = wl_fixed_from_int(y);
+ }
+
+ pixman_region32_fini(&old_output_region);
+
return ret;
}
--
1.7.9.5
More information about the wayland-devel
mailing list