@@ -659,6 +659,12 @@ void WaylandThread::_wl_registry_on_global(void *data, struct wl_registry *wl_re
659659 return ;
660660 }
661661
662+ if (strcmp (interface, wp_pointer_warp_v1_interface.name ) == 0 ) {
663+ registry->wp_pointer_warp = (struct wp_pointer_warp_v1 *)wl_registry_bind (wl_registry, name, &wp_pointer_warp_v1_interface, 1 );
664+ registry->wp_pointer_warp_name = name;
665+ return ;
666+ }
667+
662668 if (strcmp (interface, FIFO_INTERFACE_NAME) == 0 ) {
663669 registry->wp_fifo_manager_name = name;
664670 }
@@ -1023,6 +1029,17 @@ void WaylandThread::_wl_registry_on_global_remove(void *data, struct wl_registry
10231029 return ;
10241030 }
10251031
1032+ if (name == registry->wp_pointer_warp_name ) {
1033+ if (registry->wp_pointer_warp ) {
1034+ wp_pointer_warp_v1_destroy (registry->wp_pointer_warp );
1035+ registry->wp_pointer_warp = nullptr ;
1036+ }
1037+
1038+ registry->wp_pointer_warp_name = 0 ;
1039+
1040+ return ;
1041+ }
1042+
10261043 {
10271044 // Iterate through all of the seats to find if any got removed.
10281045 List<struct wl_seat *>::Element *E = registry->wl_seats .front ();
@@ -3374,6 +3391,21 @@ void WaylandThread::seat_state_set_hint(SeatState *p_ss, int p_x, int p_y) {
33743391 zwp_locked_pointer_v1_set_cursor_position_hint (p_ss->wp_locked_pointer , wl_fixed_from_int (p_x), wl_fixed_from_int (p_y));
33753392}
33763393
3394+ void WaylandThread::seat_state_warp_pointer (SeatState *p_ss, int p_x, int p_y) {
3395+ if (registry.wp_pointer_warp == nullptr ) {
3396+ return ;
3397+ }
3398+
3399+ if (p_ss->pointer_data .pointed_id == DisplayServer::INVALID_WINDOW_ID) {
3400+ return ;
3401+ }
3402+
3403+ struct wl_surface *surface = window_get_wl_surface (p_ss->pointer_data .pointed_id );
3404+ ERR_FAIL_NULL (surface);
3405+
3406+ wp_pointer_warp_v1_warp_pointer (registry.wp_pointer_warp , surface, p_ss->wl_pointer , wl_fixed_from_int (p_x), wl_fixed_from_int (p_y), p_ss->pointer_enter_serial );
3407+ }
3408+
33773409void WaylandThread::seat_state_confine_pointer (SeatState *p_ss) {
33783410 ERR_FAIL_NULL (p_ss);
33793411
@@ -4381,25 +4413,60 @@ void WaylandThread::pointer_set_hint(const Point2i &p_hint) {
43814413 }
43824414
43834415 WindowState *ws = window_get_state (ss->pointer_data .pointed_id );
4384-
4385- int hint_x = 0 ;
4386- int hint_y = 0 ;
4387-
4388- if (ws) {
4389- // NOTE: It looks like it's not really recommended to convert from
4390- // "godot-space" to "wayland-space" and in general I received mixed feelings
4391- // discussing about this. I'm not really sure about the maths behind this but,
4392- // oh well, we're setting a cursor hint. ¯\_(ツ)_/¯
4393- // See: https://oftc.irclog.whitequark.org/wayland/2023-08-23#1692756914-1692816818
4394- hint_x = std::round (p_hint.x / window_state_get_scale_factor (ws));
4395- hint_y = std::round (p_hint.y / window_state_get_scale_factor (ws));
4416+ if (!ws) {
4417+ return ;
43964418 }
43974419
4420+ // NOTE: It looks like it's not really recommended to convert from
4421+ // "godot-space" to "wayland-space" and in general I received mixed feelings
4422+ // discussing about this. I'm not really sure about the maths behind this but,
4423+ // oh well, we're setting a cursor hint. ¯\_(ツ)_/¯
4424+ // See: https://oftc.irclog.whitequark.org/wayland/2023-08-23#1692756914-1692816818
4425+ int hint_x = std::round (p_hint.x / window_state_get_scale_factor (ws));
4426+ int hint_y = std::round (p_hint.y / window_state_get_scale_factor (ws));
4427+
43984428 if (ss) {
43994429 seat_state_set_hint (ss, hint_x, hint_y);
44004430 }
44014431}
44024432
4433+ void WaylandThread::pointer_warp (const Point2i &p_to) {
4434+ // NOTE: This is for compositors that don't support the pointer-warp protocol.
4435+ // It's hacked together and not guaranteed to work.
4436+ if (registry.wp_pointer_warp == nullptr ) {
4437+ PointerConstraint old_constraint = pointer_get_constraint ();
4438+
4439+ pointer_set_constraint (PointerConstraint::LOCKED);
4440+ pointer_set_hint (p_to);
4441+
4442+ pointer_set_constraint (old_constraint);
4443+
4444+ return ;
4445+ }
4446+
4447+ SeatState *ss = wl_seat_get_seat_state (wl_seat_current);
4448+ if (!ss) {
4449+ return ;
4450+ }
4451+
4452+ WindowState *ws = window_get_state (ss->pointer_data .pointed_id );
4453+ if (!ws) {
4454+ return ;
4455+ }
4456+
4457+ // NOTE: It looks like it's not really recommended to convert from
4458+ // "godot-space" to "wayland-space" and in general I received mixed feelings
4459+ // discussing about this. I'm not really sure about the maths behind this but,
4460+ // oh well. ¯\_(ツ)_/¯
4461+ // See: https://oftc.irclog.whitequark.org/wayland/2023-08-23#1692756914-1692816818
4462+ int wl_pos_x = std::round (p_to.x / window_state_get_scale_factor (ws));
4463+ int wl_pos_y = std::round (p_to.y / window_state_get_scale_factor (ws));
4464+
4465+
4466+ if (ss) {
4467+ seat_state_warp_pointer (ss, wl_pos_x, wl_pos_y);
4468+ }
4469+ }
44034470WaylandThread::PointerConstraint WaylandThread::pointer_get_constraint () const {
44044471 return pointer_constraint;
44054472}
@@ -5135,6 +5202,14 @@ void WaylandThread::destroy() {
51355202 zwp_idle_inhibit_manager_v1_destroy (registry.wp_idle_inhibit_manager );
51365203 }
51375204
5205+ if (registry.wp_tablet_manager ) {
5206+ zwp_tablet_manager_v2_destroy (registry.wp_tablet_manager );
5207+ }
5208+
5209+ if (registry.wp_text_input_manager ) {
5210+ zwp_text_input_manager_v3_destroy (registry.wp_text_input_manager );
5211+ }
5212+
51385213 if (registry.wp_pointer_constraints ) {
51395214 zwp_pointer_constraints_v1_destroy (registry.wp_pointer_constraints );
51405215 }
@@ -5147,6 +5222,10 @@ void WaylandThread::destroy() {
51475222 zwp_relative_pointer_manager_v1_destroy (registry.wp_relative_pointer_manager );
51485223 }
51495224
5225+ if (registry.wp_pointer_warp ) {
5226+ wp_pointer_warp_v1_destroy (registry.wp_pointer_warp );
5227+ }
5228+
51505229 if (registry.xdg_activation ) {
51515230 xdg_activation_v1_destroy (registry.xdg_activation );
51525231 }
0 commit comments