Bug 480582

Summary: Wine 9 Wayland cursor does not hide when holding mouse button on game world to move camera/character
Product: [Plasma] kwin Reporter: Yao Mitachi <yaomtc>
Component: wayland-genericAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: nate
Priority: NOR    
Version: 5.27.10   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 6.0
Sentry Crash Report:

Description Yao Mitachi 2024-01-31 03:55:05 UTC
SUMMARY
When playing Final Fantasy XIV using Wayland with Wine, with Wine 9's new Wayland driver enabled, the cursor does not hide when holding down a mouse button to move the camera/character. In GNOME (Wayland) and in Plasma (X11) this works fine.

STEPS TO REPRODUCE
1. Launch FFXIV with Wayland enabled in Wine
2. Once logged in, hold down left or right mouse button on the game world to move the camera, or hold both to move the character

OBSERVED RESULT
Cursor stays visible on the screen while the mouse button is held down.

EXPECTED RESULT
Cursor hides until the button is released, as occurs with X11, XWayland, and GNOME (Wayland).

SOFTWARE/OS VERSIONS
Linux: 6.7.2
KDE Plasma Version: 5.27.10
KDE Frameworks Version: 5.114.0
Qt Version: 5.15.12

ADDITIONAL INFORMATION
These can be used to more easily test Wayland with FFXIV:
https://github.com/rankynbass/unofficial-wine-xiv-git/releases/tag/v9.1
https://github.com/rankynbass/XIVLauncher.Core/releases/tag/rb-v1.0.7.1
Comment 1 Vlad Zahorodnii 2024-01-31 11:20:42 UTC
Hmm video games won't start on my machine when running with wine+wayland. Do you know if any other applications or video games are affected by this issue?

Also are you able to test Plasma 6? It had a few changes related to how cursor is handled
Comment 2 Vlad Zahorodnii 2024-01-31 11:21:16 UTC
> Hmm video games won't start on my machine when running with wine+wayland

DISPLAY= winecfg, works fine, just not video games...
Comment 3 Yao Mitachi 2024-02-07 00:20:15 UTC
Just tested Plasma 6, no difference there.

I did find one thing though, which I didn't test before. The cursor does hide when set in-game to Software Cursor. The issue only occurs when using either Hardware Cursor option ("FFXIV Custom" or "OS Standard". So if you don't mind slightly higher cursor latency and are particularly bothered by the cursor staying on screen (I'm not) this can be a workaround.
Comment 4 Bug Janitor Service 2024-02-09 11:52:43 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/5158
Comment 5 Vlad Zahorodnii 2024-02-09 12:07:57 UTC
Git commit 13e7cac019fcb9825a3e2f1655622cf393e438ab by Vlad Zahorodnii.
Committed on 09/02/2024 at 11:53.
Pushed by vladz into branch 'master'.

Handle wl_surface destruction in SurfaceCursorSource

Wine/Wayland hides the cursor as follows:

[ 853107.473]  -> wl_pointer@15.set_cursor(172832, wl_surface@38, 0, 0)
...
[ 858989.757]  -> wl_surface@38.destroy()
[ 858989.759]  -> wl_pointer@15.set_cursor(172832, nil, 0, 0)

i.e. it destroys the cursor surface, then calls wl_pointer.set_cursor().

SurfaceCursorSource stores the wl_surface in a QPointer, furthermore it
is going to emit the changed signal, which is needed to force the
CursorItem to update its content, only if either a new hotspot or a
surface has been passed to SurfaceCursorSource::update(). So what happens
is the following:

- The SurfaceInterface object is destroyed and the QPointer resets its
  value to nullptr
- SurfaceCursorSource::update(nullptr, QPointF(0, 0)) gets called in
  response to wl_pointer@15.set_cursor(nil, 0, 0)
- but since m_surface has been implicitly reset to nullptr, no changed
  signal is going to be emitted

This change addresses the issue by making the SurfaceCursorSource track
the SurfaceInterface's destroyed signal.

M  +10   -0    src/cursorsource.cpp
M  +2    -2    src/cursorsource.h

https://invent.kde.org/plasma/kwin/-/commit/13e7cac019fcb9825a3e2f1655622cf393e438ab
Comment 6 Vlad Zahorodnii 2024-02-09 12:16:07 UTC
Git commit 7644499e20280fd7cf99b2bb1424fc38f021ccd6 by Vlad Zahorodnii.
Committed on 09/02/2024 at 12:08.
Pushed by vladz into branch 'Plasma/6.0'.

Handle wl_surface destruction in SurfaceCursorSource

Wine/Wayland hides the cursor as follows:

[ 853107.473]  -> wl_pointer@15.set_cursor(172832, wl_surface@38, 0, 0)
...
[ 858989.757]  -> wl_surface@38.destroy()
[ 858989.759]  -> wl_pointer@15.set_cursor(172832, nil, 0, 0)

i.e. it destroys the cursor surface, then calls wl_pointer.set_cursor().

SurfaceCursorSource stores the wl_surface in a QPointer, furthermore it
is going to emit the changed signal, which is needed to force the
CursorItem to update its content, only if either a new hotspot or a
surface has been passed to SurfaceCursorSource::update(). So what happens
is the following:

- The SurfaceInterface object is destroyed and the QPointer resets its
  value to nullptr
- SurfaceCursorSource::update(nullptr, QPointF(0, 0)) gets called in
  response to wl_pointer@15.set_cursor(nil, 0, 0)
- but since m_surface has been implicitly reset to nullptr, no changed
  signal is going to be emitted

This change addresses the issue by making the SurfaceCursorSource track
the SurfaceInterface's destroyed signal.


(cherry picked from commit 13e7cac019fcb9825a3e2f1655622cf393e438ab)

M  +10   -0    src/cursorsource.cpp
M  +2    -2    src/cursorsource.h

https://invent.kde.org/plasma/kwin/-/commit/7644499e20280fd7cf99b2bb1424fc38f021ccd6
Comment 7 Yao Mitachi 2024-03-06 02:51:12 UTC
Can confirm that fixed the issue with the FFXIV cursor, thank you!