JDK-8320965 : Scrolling on a touch enabled display fails on Wayland
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: jfx21
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • Submitted: 2023-11-29
  • Updated: 2024-03-15
  • Resolved: 2024-02-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
jfx23 b07Fixed
Related Reports
Blocks :  
Description
When running a JavaFX application (like the attached one) with just a pannable ScrollPane on an embedded device (Linux-aarch64) with a touch enabled display, users can scroll the content just by dragging their finger on the touch screen. This works fine on X11, but fails on Wayland: 

With X11, after MOUSE_PRESSED, MOUSE_DRAGGED events are fired repeatedly while the user moves their finger on the screen, and scrolling works as expected:

Event: MOUSE_PRESSED
Event: MOUSE_DRAGGED
Event: MOUSE_DRAGGED
...
Event: MOUSE_DRAGGED
Event: MOUSE_RELEASED

With Wayland, however, after MOUSE_PRESSED, dragging starts, there is one MOUSE_DRAGGED  event, and the view shifts slightly, but immediately stops scrolling and a MOUSE_RELEASED event is fired, even with the finger still pressing the display:

Event: MOUSE_PRESSED
Event: MOUSE_DRAGGED
Event: MOUSE_RELEASED

Running with GDK_DEBUG=events shows:

Gdk-Message: 09:56:07.169: touch begin:	window 4194306
	touch id: 18
	pointer emulating: true
Event: MOUSE_PRESSED
Gdk-Message: 09:56:07.216: touch update:	window 4194306
	touch id: 18
	pointer emulating: true
Gdk-Message: 09:56:07.327: touch update:	window 4194306
	touch id: 18
	pointer emulating: true
Gdk-Message: 09:56:07.329: touch update:	window 4194306
	touch id: 18
	pointer emulating: true
...
Gdk-Message: 09:56:07.339: touch update:	window 4194306
	touch id: 18
	pointer emulating: true
Event: MOUSE_DRAGGED
Gdk-Message: 09:56:07.363: touch end:	window 4194306
	touch id: 18
	pointer emulating: true
Event: MOUSE_RELEASED

And running with GDK_DEBUG=nograbs "fixes" the issue, and scrolling works fine on Wayland as well.

Comments
Changeset: df3707d7 Author: Jose Pereda <jpereda@openjdk.org> Date: 2024-02-26 16:02:05 +0000 URL: https://git.openjdk.org/jfx/commit/df3707d7444c542ba55a8e76a8ed7e8f0637e874
26-02-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jfx/pull/1305 Date: 2023-12-12 11:19:23 +0000
12-12-2023

I've created https://github.com/openjdk/jfx/pull/1305
12-12-2023

I've looked around in Gtk code, they have different implementations for gdk_seat_grab() and gdk_device_grab(). https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/gdkdevice.c https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gdk/gdkseat.c The seat terminology was born with wayland, so it makes sense this will work better.
05-12-2023

Mouse drag events are emitted (see logs), and when using GDK_DEBUG=nograbs (with JavaFX from head), everything works. Only doing the API changes I described (from gdk_pointer_grab() to gdk_seat_grab()), it works fine, without any debug flag. If there is anything else I can try out, let me know?
04-12-2023

It seems like a good solution, but internally gtk is probably converting the old API to the new API - so there might be another solution. Maybe it's falling in the mouse drag?
04-12-2023

> To fix the issue, we might need to introduce GLASS_GTK3_20 identifier? [~jpereda] We would need to do this via dlsym using a runtime check rather than a compile-time check. We want to still be able to run on a system without GTK 3.20 (3.8 is the minimum we compile for). See, for example, gdk_x11_display_set_window_scale in "wrapped.c".
30-11-2023

[~tsayao] Would you be willing to comment on the proposed solution?
30-11-2023

The fact that GDK_DEBUG=nograbs helps means that the issue might be related to the call WindowContextBase::grab_mouse_drag_focus() in gtk/glass_window.cpp has something to do with this. It calls glass_gdk_mouse_devices_grab_with_cursor(), which in turns calls gdk_pointer_grab() in gtk/glass_general.cpp. Checking gtk docs show that this method has been deprecated since GDK 3.0 (https://docs.gtk.org/gdk3/func.pointer_grab.html), to be replaced with gdk_device_grab(), which has also been deprecated since GDK 3.20 (https://docs.gtk.org/gdk3/method.Device.grab.html), to be replaced with gdk_seat_grab() (see https://docs.gtk.org/gdk3/method.Seat.grab.html). Replacing gdk_pointer_grab with gdk_device_grab seems to fix the issue (scrolling works), but this is printed out: (java:2604): Gdk-CRITICAL **: 12:15:28.025: gdk_device_grab: assertion 'GDK_IS_DEVICE (device)' failed (so it might be that grabs are not used after all) However, replacing gdk_pointer_grab with gdk_seat_grab does fix the issue and scrolling works now as expected (except for an issue with the mouse pointer location which is not updated). To fix the issue, we might need to introduce GLASS_GTK3_20 identifier?
29-11-2023