Release 1.1.3 with game window and Gamescope lifecycle fixes

This commit is contained in:
2026-10-25 20:47:19 +01:00
parent b6de80e758
commit 1f2aad0ee2
42 changed files with 9291 additions and 153 deletions

View File

@@ -0,0 +1,64 @@
From: PT Linux Launcher maintainers
Subject: Keep client-side decoration clicks out of nested applications
Bug: https://github.com/ValveSoftware/gamescope/issues/2299
Forwarded: https://github.com/ValveSoftware/gamescope/issues/2299
On compositors without xdg-decoration support, libdecor creates client-side
surfaces owned by the Gamescope Wayland connection. Pointer button callbacks
for those titlebar and resize surfaces consequently also reach Gamescope's
input thread. Forwarding a decoration press to the nested application can
leave its button permanently held because libdecor consumes the matching
release while performing a move, resize, or maximize operation.
Only begin nested button sequences while the pointer is over Gamescope's
actual toplevel surface. Track those presses so their releases are delivered
even if the pointer or keyboard focus changes during a game-originated drag.
--- a/src/Backends/WaylandBackend.cpp
+++ b/src/Backends/WaylandBackend.cpp
@@ -562,6 +562,7 @@
std::atomic<std::shared_ptr<zwp_relative_pointer_v1>> m_pRelativePointer = nullptr;
std::unordered_set<uint32_t> m_uScancodesHeld;
+ std::unordered_set<uint32_t> m_uMouseButtonsHeld;
void Wayland_Registry_Global( wl_registry *pRegistry, uint32_t uName, const char *pInterface, uint32_t uVersion );
static const wl_registry_listener s_RegistryListener;
@@ -3091,13 +3092,33 @@
}
void CWaylandInputThread::Wayland_Pointer_Button( wl_pointer *pPointer, uint32_t uSerial, uint32_t uTime, uint32_t uButton, uint32_t uState )
{
- // Don't do any motion/movement stuff if we don't have kb focus
- if ( !cv_wayland_mouse_warp_without_keyboard_focus && !m_bKeyboardEntered )
- return;
+ const bool bPressed = uState == WL_POINTER_BUTTON_STATE_PRESSED;
+ const bool bWasPressed = m_uMouseButtonsHeld.contains( uButton );
+
+ if ( bPressed )
+ {
+ // libdecor's client-side decorations share our Wayland seat, but
+ // their button events must not be sent to the nested application.
+ if ( !m_bMouseEntered || bWasPressed )
+ return;
+
+ // Don't start an application click without keyboard focus.
+ if ( !cv_wayland_mouse_warp_without_keyboard_focus && !m_bKeyboardEntered )
+ return;
+ }
+ else if ( !bWasPressed )
+ {
+ return;
+ }
wlserver_lock();
- wlserver_mousebutton( uButton, uState == WL_POINTER_BUTTON_STATE_PRESSED, ++m_uFakeTimestamp );
+ wlserver_mousebutton( uButton, bPressed, ++m_uFakeTimestamp );
wlserver_unlock();
+
+ if ( bPressed )
+ m_uMouseButtonsHeld.emplace( uButton );
+ else
+ m_uMouseButtonsHeld.erase( uButton );
}
void CWaylandInputThread::Wayland_Pointer_Axis( wl_pointer *pPointer, uint32_t uTime, uint32_t uAxis, wl_fixed_t fValue )
{