Added a fix for X11 / Cinnamon window popups and maximize button not visible.

This commit is contained in:
2026-09-07 22:19:05 +02:00
parent f06fc2e4e3
commit 1cfe8625e9
10 changed files with 678 additions and 34 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 )
{