[mutter/wip/carlosg/move-pointer-onscreen: 1/2] backends/native: Ensure pointer is onscreen in input thread
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/move-pointer-onscreen: 1/2] backends/native: Ensure pointer is onscreen in input thread
- Date: Fri, 14 Jan 2022 21:03:51 +0000 (UTC)
commit 5df3364f1c6e22a29845f8210a414d63ed0005e1
Author: Carlos Garnacho <carlosg gnome org>
Date: Fri Jan 14 20:29:45 2022 +0100
backends/native: Ensure pointer is onscreen in input thread
It's slightly racy to have the main thread update the views and warp
the pointer, since the input thread may not be aware yet of the new
viewport layout.
Make the input thread clamp the pointer so it remains onscreen
instead, when the new viewports are obtained.
src/backends/native/meta-seat-impl.c | 55 ++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
---
diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c
index 8bf0c68759..b2f428b613 100644
--- a/src/backends/native/meta-seat-impl.c
+++ b/src/backends/native/meta-seat-impl.c
@@ -3514,6 +3514,59 @@ meta_seat_impl_set_pointer_constraint (MetaSeatImpl *seat_impl,
g_object_unref (task);
}
+static void
+ensure_pointer_onscreen (MetaSeatImpl *seat_impl)
+{
+ int i, candidate = -1;
+ int nearest_monitor_x, nearest_monitor_y, min_distance = G_MAXINT;
+ cairo_rectangle_int_t monitor_rect;
+ graphene_point_t coords;
+
+ if (!meta_seat_impl_query_state (seat_impl,
+ seat_impl->core_pointer, NULL,
+ &coords, NULL))
+ return;
+
+ /* Pointer is in a view */
+ if (meta_viewport_info_get_view_at (seat_impl->viewports,
+ coords.x, coords.y) >= 0)
+ return;
+
+ /* Find nearest view */
+ for (i = 0; i < meta_viewport_info_get_num_views (seat_impl->viewports); i++)
+ {
+ meta_viewport_info_get_view_info (seat_impl->viewports, i,
+ &monitor_rect, NULL);
+ nearest_monitor_x = MIN (ABS (coords.x - monitor_rect.x),
+ ABS (coords.x -
+ monitor_rect.x + monitor_rect.width));
+ nearest_monitor_y = MIN (ABS (coords.y - monitor_rect.y),
+ ABS (coords.y -
+ monitor_rect.y + monitor_rect.height));
+ if (nearest_monitor_x < min_distance ||
+ nearest_monitor_y < min_distance)
+ {
+ min_distance = MIN (nearest_monitor_x, nearest_monitor_y);
+ candidate = i;
+ }
+ }
+
+ if (candidate < 0)
+ return;
+
+ /* Calculate new coordinates on nearest view */
+ meta_viewport_info_get_view_info (seat_impl->viewports,
+ candidate,
+ &monitor_rect, NULL);
+ coords.x = CLAMP (coords.x, monitor_rect.x,
+ monitor_rect.x + monitor_rect.width);
+ coords.y = CLAMP (coords.y, monitor_rect.y,
+ monitor_rect.y + monitor_rect.height);
+
+ notify_absolute_motion_in_impl (seat_impl->core_pointer, 0,
+ coords.x, coords.y, NULL);
+}
+
static gboolean
set_viewports (GTask *task)
{
@@ -3523,6 +3576,8 @@ set_viewports (GTask *task)
g_set_object (&seat_impl->viewports, viewports);
g_task_return_boolean (task, TRUE);
+ ensure_pointer_onscreen (seat_impl);
+
return G_SOURCE_REMOVE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]