diff --git a/clutter/clutter/clutter-seat-private.h b/clutter/clutter/clutter-seat-private.h index da6349e66..8271799a2 100644 --- a/clutter/clutter/clutter-seat-private.h +++ b/clutter/clutter/clutter-seat-private.h @@ -33,4 +33,9 @@ ClutterGrabState clutter_seat_grab (ClutterSeat *seat, void clutter_seat_ungrab (ClutterSeat *seat, uint32_t time); +CLUTTER_EXPORT +void clutter_seat_init_pointer_position (ClutterSeat *seat, + float x, + float y); + #endif /* CLUTTER_SEAT_PRIVATE_H */ diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index 1c057325b..39b3ffa49 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -626,6 +626,16 @@ clutter_seat_warp_pointer (ClutterSeat *seat, CLUTTER_SEAT_GET_CLASS (seat)->warp_pointer (seat, x, y); } +void +clutter_seat_init_pointer_position (ClutterSeat *seat, + float x, + float y) +{ + g_return_if_fail (CLUTTER_IS_SEAT (seat)); + + CLUTTER_SEAT_GET_CLASS (seat)->init_pointer_position (seat, x, y); +} + /** * clutter_seat_get_touch_mode: * @seat: a #ClutterSeat diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h index 30d176acf..cc9872772 100644 --- a/clutter/clutter/clutter-seat.h +++ b/clutter/clutter/clutter-seat.h @@ -90,6 +90,10 @@ struct _ClutterSeatClass int x, int y); + void (* init_pointer_position) (ClutterSeat *seat, + float x, + float y); + gboolean (* query_state) (ClutterSeat *seat, ClutterInputDevice *device, ClutterEventSequence *sequence, diff --git a/src/backends/native/meta-seat-impl.c b/src/backends/native/meta-seat-impl.c index 5715c7ee3..b70c785fa 100644 --- a/src/backends/native/meta-seat-impl.c +++ b/src/backends/native/meta-seat-impl.c @@ -3157,6 +3157,38 @@ meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, g_object_unref (task); } +static gboolean +init_pointer_position_in_impl (GTask *task) +{ + MetaSeatImpl *seat_impl = g_task_get_source_object (task); + graphene_point_t *point; + + point = g_task_get_task_data (task); + seat_impl->pointer_x = point->x; + seat_impl->pointer_y = point->y; + g_task_return_boolean (task, TRUE); + + return G_SOURCE_REMOVE; +} + +void +meta_seat_impl_init_pointer_position (MetaSeatImpl *seat_impl, + float x, + float y) +{ + graphene_point_t *point; + g_autoptr (GTask) task = NULL; + + point = graphene_point_alloc (); + point->x = x; + point->y = y; + + task = g_task_new (seat_impl, NULL, NULL, NULL); + g_task_set_task_data (task, point, (GDestroyNotify) graphene_point_free); + meta_seat_impl_run_input_task (seat_impl, task, + (GSourceFunc) init_pointer_position_in_impl); +} + gboolean meta_seat_impl_query_state (MetaSeatImpl *seat_impl, ClutterInputDevice *device, diff --git a/src/backends/native/meta-seat-impl.h b/src/backends/native/meta-seat-impl.h index ff614586a..3bc8837d3 100644 --- a/src/backends/native/meta-seat-impl.h +++ b/src/backends/native/meta-seat-impl.h @@ -226,6 +226,9 @@ void meta_seat_impl_set_viewports (MetaSeatImpl *seat_impl, void meta_seat_impl_warp_pointer (MetaSeatImpl *seat_impl, int x, int y); +void meta_seat_impl_init_pointer_position (MetaSeatImpl *seat_impl, + float x, + float y); gboolean meta_seat_impl_query_state (MetaSeatImpl *seat_impl, ClutterInputDevice *device, ClutterEventSequence *sequence, diff --git a/src/backends/native/meta-seat-native.c b/src/backends/native/meta-seat-native.c index 7cf18b997..539f4a5bb 100644 --- a/src/backends/native/meta-seat-native.c +++ b/src/backends/native/meta-seat-native.c @@ -342,6 +342,16 @@ meta_seat_native_warp_pointer (ClutterSeat *seat, meta_seat_impl_warp_pointer (seat_native->impl, x, y); } +static void +meta_seat_native_init_pointer_position (ClutterSeat *seat, + float x, + float y) +{ + MetaSeatNative *seat_native = META_SEAT_NATIVE (seat); + + meta_seat_impl_init_pointer_position (seat_native->impl, x, y); +} + static gboolean meta_seat_native_query_state (ClutterSeat *seat, ClutterInputDevice *device, @@ -374,6 +384,7 @@ meta_seat_native_class_init (MetaSeatNativeClass *klass) seat_class->create_virtual_device = meta_seat_native_create_virtual_device; seat_class->get_supported_virtual_device_types = meta_seat_native_get_supported_virtual_device_types; seat_class->warp_pointer = meta_seat_native_warp_pointer; + seat_class->init_pointer_position = meta_seat_native_init_pointer_position; seat_class->handle_event_post = meta_seat_native_handle_event_post; seat_class->query_state = meta_seat_native_query_state; diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index ac2b56d13..37f069a70 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -1654,6 +1654,25 @@ meta_seat_x11_warp_pointer (ClutterSeat *seat, meta_clutter_x11_untrap_x_errors (); } +static void +meta_seat_x11_init_pointer_position (ClutterSeat *seat, + float x, + float y) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + Display *xdisplay = xdisplay_from_seat (seat_x11); + Window root_xwindow = root_xwindow_from_seat (seat_x11); + + meta_clutter_x11_trap_x_errors (); + XIWarpPointer (xdisplay, + seat_x11->pointer_id, + None, + root_xwindow, + 0, 0, 0, 0, + (int) x, (int) y); + meta_clutter_x11_untrap_x_errors (); +} + static uint32_t translate_state (XIButtonState *button_state, XIModifierState *modifier_state, @@ -1865,6 +1884,7 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass) seat_class->create_virtual_device = meta_seat_x11_create_virtual_device; seat_class->get_supported_virtual_device_types = meta_seat_x11_get_supported_virtual_device_types; seat_class->warp_pointer = meta_seat_x11_warp_pointer; + seat_class->init_pointer_position = meta_seat_x11_init_pointer_position; seat_class->handle_event_post = meta_seat_x11_handle_event_post; seat_class->query_state = meta_seat_x11_query_state; seat_class->grab = meta_seat_x11_grab;