1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Linux: Fix resizing issue with the PopupMenu

Previously opening a PopupMenu and then clicking somewhere outside
the application would cause the mouse button representation to be
stuck in a down state.
This commit is contained in:
attila 2022-07-01 21:15:00 +02:00 committed by Tom Poole
parent 5cfef70994
commit f5d2642874

View file

@ -413,6 +413,31 @@ namespace Keys
static bool capsLock = false; static bool capsLock = false;
static char keyStates [32]; static char keyStates [32];
static constexpr int extendedKeyModifier = 0x10000000; 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; const int KeyPress::spaceKey = XK_space & 0xff;
@ -2448,6 +2473,18 @@ ModifierKeys XWindowSystem::getNativeRealtimeModifiers() const
ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); 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; return ModifierKeys::currentModifiers;
} }
@ -3310,6 +3347,7 @@ void XWindowSystem::handleWindowMessage (LinuxComponentPeer* peer, XEvent& event
void XWindowSystem::handleKeyPressEvent (LinuxComponentPeer* peer, XKeyEvent& keyEvent) const void XWindowSystem::handleKeyPressEvent (LinuxComponentPeer* peer, XKeyEvent& keyEvent) const
{ {
auto oldMods = ModifierKeys::currentModifiers; auto oldMods = ModifierKeys::currentModifiers;
Keys::refreshStaleModifierKeys();
char utf8 [64] = { 0 }; char utf8 [64] = { 0 };
juce_wchar unicodeChar = 0; juce_wchar unicodeChar = 0;
@ -3540,6 +3578,7 @@ void XWindowSystem::handleButtonReleaseEvent (LinuxComponentPeer* peer, const XB
void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer* peer, const XPointerMovedEvent& movedEvent) const void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer* peer, const XPointerMovedEvent& movedEvent) const
{ {
updateKeyModifiers ((int) movedEvent.state); updateKeyModifiers ((int) movedEvent.state);
Keys::refreshStaleMouseKeys();
auto& dragState = dragAndDropStateMap[peer]; auto& dragState = dragAndDropStateMap[peer];