File Fix-resizing-issue-with-the-PopupMenu.patch of Package juce6
From 379b0c6229ab5ad998091b20333a6c3faf481aea Mon Sep 17 00:00:00 2001
From: haenkel <100365267+haenkel@users.noreply.github.com>
Date: Mon, 4 Jul 2022 16:33:21 +0200
Subject: [PATCH] Linux: Fix resizing issue with the PopupMenu (#1)
Previously opening a PopupMenu and then clicking somewhere outside
the application would cause the mouse button representation to be
stuck in a down state.
Co-authored-by: attila <attila@juce.com>
---
.../native/x11/juce_linux_XWindowSystem.cpp | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
index 2ea809908b8e..e2fc28220d16 100644
--- a/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
+++ b/modules/juce_gui_basics/native/x11/juce_linux_XWindowSystem.cpp
@@ -413,6 +413,31 @@ namespace Keys
static bool capsLock = false;
static char keyStates [32];
static constexpr int extendedKeyModifier = 0x10000000;
+ static bool modifierKeysAreStale = false;
+
+ static void refreshStaleModifierKeys()
+ {
+ if (modifierKeysAreStale)
+ {
+ XWindowSystem::getInstance()->getNativeRealtimeModifiers();
+ modifierKeysAreStale = false;
+ }
+ }
+
+ // Call this function when only the mouse keys need to be refreshed e.g. when the event
+ // parameter already has information about the keys.
+ static void refreshStaleMouseKeys()
+ {
+ if (modifierKeysAreStale)
+ {
+ const auto oldMods = ModifierKeys::currentModifiers;
+ XWindowSystem::getInstance()->getNativeRealtimeModifiers();
+ ModifierKeys::currentModifiers = oldMods.withoutMouseButtons()
+ .withFlags (ModifierKeys::currentModifiers.withOnlyMouseButtons()
+ .getRawFlags());
+ modifierKeysAreStale = false;
+ }
+ }
}
const int KeyPress::spaceKey = XK_space & 0xff;
@@ -2445,6 +2470,18 @@ ModifierKeys XWindowSystem::getNativeRealtimeModifiers() const
ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods);
+ // We are keeping track of the state of modifier keys and mouse buttons with the assumption that
+ // for every mouse down we are going to receive a mouse up etc.
+ //
+ // This assumption is broken when getNativeRealtimeModifiers() is called. If for example we call
+ // this function when the mouse cursor is in another application and the mouse button happens to
+ // be down, then its represented state in currentModifiers may remain down indefinitely, since
+ // we aren't going to receive an event when it's released.
+ //
+ // We mark this state in this variable, and we can restore synchronization when our window
+ // receives an event again.
+ Keys::modifierKeysAreStale = true;
+
return ModifierKeys::currentModifiers;
}
@@ -3305,6 +3342,7 @@ void XWindowSystem::handleWindowMessage (LinuxComponentPeer* peer, XEvent& event
void XWindowSystem::handleKeyPressEvent (LinuxComponentPeer* peer, XKeyEvent& keyEvent) const
{
auto oldMods = ModifierKeys::currentModifiers;
+ Keys::refreshStaleModifierKeys();
char utf8 [64] = { 0 };
juce_wchar unicodeChar = 0;
@@ -3535,6 +3573,7 @@ void XWindowSystem::handleButtonReleaseEvent (LinuxComponentPeer* peer, const XB
void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer* peer, const XPointerMovedEvent& movedEvent) const
{
updateKeyModifiers ((int) movedEvent.state);
+ Keys::refreshStaleMouseKeys();
auto& dragState = dragAndDropStateMap[peer];