diff --git a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp index 9a6e61621f..26e196b32e 100644 --- a/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp +++ b/extras/Projucer/Source/ComponentEditor/PaintElements/jucer_PaintElement.cpp @@ -515,7 +515,7 @@ void PaintElement::checkBounds (Rectangle& b, const bool isStretchingBottom, const bool isStretchingRight) { - if (ModifierKeys::getCurrentModifiers().isShiftDown()) + if (ModifierKeys::currentModifiers.isShiftDown()) setFixedAspectRatio (originalAspectRatio); else setFixedAspectRatio (0.0); diff --git a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp index 64250a8ce0..3ced818308 100644 --- a/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp +++ b/extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentOverlayComponent.cpp @@ -189,7 +189,7 @@ void ComponentOverlayComponent::checkBounds (Rectangle& b, const bool isStretchingBottom, const bool isStretchingRight) { - if (ModifierKeys::getCurrentModifiers().isShiftDown()) + if (ModifierKeys::currentModifiers.isShiftDown()) setFixedAspectRatio (originalAspectRatio); else setFixedAspectRatio (0.0); diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp index 6d431c2709..0c3c09f308 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp @@ -217,7 +217,7 @@ void JucerDocument::setInitialSize (int w, int h) //============================================================================== bool JucerDocument::isSnapActive (const bool disableIfCtrlKeyDown) const noexcept { - return snapActive != (disableIfCtrlKeyDown && ModifierKeys::getCurrentModifiers().isCtrlDown()); + return snapActive != (disableIfCtrlKeyDown && ModifierKeys::currentModifiers.isCtrlDown()); } int JucerDocument::snapPosition (int pos) const noexcept diff --git a/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h b/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h index c05a48edbd..e8e2c9ac6a 100644 --- a/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h +++ b/modules/juce_audio_plugin_client/utility/juce_FakeMouseMoveGenerator.h @@ -68,7 +68,7 @@ public: if (screenPos != lastScreenPos) { lastScreenPos = screenPos; - auto mods = ModifierKeys::getCurrentModifiers(); + auto mods = ModifierKeys::currentModifiers; if (! mods.isAnyMouseButtonDown()) { diff --git a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp index a00d93df6d..af86714488 100644 --- a/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp +++ b/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp @@ -528,7 +528,7 @@ struct AudioProcessorValueTreeState::SliderAttachment::Pimpl : private Attached { const ScopedLock selfCallbackLock (selfCallbackMutex); - if ((! ignoreCallbacks) && (! ModifierKeys::getCurrentModifiers().isRightButtonDown())) + if ((! ignoreCallbacks) && (! ModifierKeys::currentModifiers.isRightButtonDown())) setNewUnnormalisedValue ((float) s->getValue()); } diff --git a/modules/juce_gui_basics/buttons/juce_Button.cpp b/modules/juce_gui_basics/buttons/juce_Button.cpp index 95a3a60703..1e44876f56 100644 --- a/modules/juce_gui_basics/buttons/juce_Button.cpp +++ b/modules/juce_gui_basics/buttons/juce_Button.cpp @@ -179,7 +179,7 @@ void Button::setToggleState (bool shouldBeOn, NotificationType clickNotification // async callbacks aren't possible here jassert (clickNotification != sendNotificationAsync); - sendClickMessage (ModifierKeys::getCurrentModifiers()); + sendClickMessage (ModifierKeys::currentModifiers); if (deletionWatcher == nullptr) return; @@ -368,7 +368,7 @@ void Button::handleCommandMessage (int commandId) if (isEnabled()) { flashButtonState(); - internalClickCallback (ModifierKeys::getCurrentModifiers()); + internalClickCallback (ModifierKeys::currentModifiers); } } else @@ -624,7 +624,7 @@ bool Button::keyStateChangedCallback() if (isEnabled() && wasDown && ! isKeyDown) { - internalClickCallback (ModifierKeys::getCurrentModifiers()); + internalClickCallback (ModifierKeys::currentModifiers); // (return immediately - this button may now have been deleted) return true; @@ -685,7 +685,7 @@ void Button::repeatTimerCallback() lastRepeatTime = now; callbackHelper->startTimer (repeatSpeed); - internalClickCallback (ModifierKeys::getCurrentModifiers()); + internalClickCallback (ModifierKeys::currentModifiers); } else if (! needsToRelease) { diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 47eaa9af5b..501ec4dbbf 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -2901,7 +2901,7 @@ bool Component::isMouseOverOrDragging (bool includeChildren) const bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() noexcept { - return ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(); + return ModifierKeys::currentModifiers.isAnyMouseButtonDown(); } Point Component::getMouseXYRelative() const @@ -2936,7 +2936,7 @@ void Component::modifierKeysChanged (const ModifierKeys& modifiers) void Component::internalModifierKeysChanged() { sendFakeMouseMove(); - modifierKeysChanged (ModifierKeys::getCurrentModifiers()); + modifierKeysChanged (ModifierKeys::currentModifiers); } //============================================================================== diff --git a/modules/juce_gui_basics/components/juce_Desktop.cpp b/modules/juce_gui_basics/components/juce_Desktop.cpp index fe7f2cbc11..bfa3564200 100644 --- a/modules/juce_gui_basics/components/juce_Desktop.cpp +++ b/modules/juce_gui_basics/components/juce_Desktop.cpp @@ -247,7 +247,7 @@ void Desktop::sendMouseMove() auto pos = target->getLocalPoint (nullptr, lastFakeMouseMove); auto now = Time::getCurrentTime(); - const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::getCurrentModifiers(), MouseInputSource::invalidPressure, + const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, target, target, now, pos, now, 0, false); diff --git a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp index 63ed2aa892..af1c4da752 100644 --- a/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp +++ b/modules/juce_gui_basics/keyboard/juce_KeyPress.cpp @@ -77,7 +77,7 @@ bool KeyPress::operator!= (int otherKeyCode) const noexcept { return ! o bool KeyPress::isCurrentlyDown() const { return isKeyCurrentlyDown (keyCode) - && (ModifierKeys::getCurrentModifiers().getRawFlags() & ModifierKeys::allKeyboardModifiers) + && (ModifierKeys::currentModifiers.getRawFlags() & ModifierKeys::allKeyboardModifiers) == (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers); } diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp index 5133ed23c6..ec6f5d9a81 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.cpp @@ -27,8 +27,10 @@ namespace juce { -ModifierKeys::ModifierKeys() noexcept : flags (0) {} -ModifierKeys::ModifierKeys (int rawFlags) noexcept : flags (rawFlags) {} +ModifierKeys ModifierKeys::currentModifiers; + +ModifierKeys::ModifierKeys() noexcept : flags (0) {} +ModifierKeys::ModifierKeys (int rawFlags) noexcept : flags (rawFlags) {} ModifierKeys::ModifierKeys (const ModifierKeys& other) noexcept : flags (other.flags) {} ModifierKeys& ModifierKeys::operator= (const ModifierKeys other) noexcept @@ -37,13 +39,6 @@ ModifierKeys& ModifierKeys::operator= (const ModifierKeys other) noexcept return *this; } -ModifierKeys ModifierKeys::currentModifiers; - -ModifierKeys ModifierKeys::getCurrentModifiers() noexcept -{ - return currentModifiers; -} - int ModifierKeys::getNumMouseButtonsDown() const noexcept { int num = 0; @@ -55,4 +50,9 @@ int ModifierKeys::getNumMouseButtonsDown() const noexcept return num; } +ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept +{ + return ComponentPeer::getCurrentModifiersRealtime(); +} + } // namespace juce diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h index 951503101f..4c75078ba2 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h @@ -186,40 +186,27 @@ public: int getNumMouseButtonsDown() const noexcept; //============================================================================== + /** This object represents the last-known state of the keyboard and mouse buttons. */ + static ModifierKeys currentModifiers; + /** Creates a ModifierKeys object to represent the last-known state of the keyboard and mouse buttons. - @see getCurrentModifiersRealtime - */ - static ModifierKeys getCurrentModifiers() noexcept; + This method is here for backwards compatibility and there's no need to call it anymore, + you should use the public currentModifiers member directly. + */ + static ModifierKeys getCurrentModifiers() noexcept { return currentModifiers; } /** Creates a ModifierKeys object to represent the current state of the keyboard and mouse buttons. - This isn't often needed and isn't recommended, but will actively check all the - mouse and key states rather than just returning their last-known state like - getCurrentModifiers() does. - - This is only needed in special circumstances for up-to-date modifier information - at times when the app's event loop isn't running normally. - - Another reason to avoid this method is that it's not stateless, and calling it may - update the value returned by getCurrentModifiers(), which could cause subtle changes - in the behaviour of some components. + This method is here for backwards compatibility and you should call ComponentPeer::getCurrentModifiersRealtime() + instead (which is what this method now does). */ static ModifierKeys getCurrentModifiersRealtime() noexcept; - private: - //============================================================================== int flags; - - friend class ComponentPeer; - friend class MouseInputSource; - friend class MouseInputSourceInternal; - - static ModifierKeys currentModifiers; - static void updateCurrentModifiers() noexcept; }; } // namespace juce diff --git a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp index b349043818..7acacad3e3 100644 --- a/modules/juce_gui_basics/menus/juce_PopupMenu.cpp +++ b/modules/juce_gui_basics/menus/juce_PopupMenu.cpp @@ -1076,8 +1076,8 @@ private: const bool wasDown, const bool overScrollArea, const bool isOverAny) { isDown = window.hasBeenOver - && (ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown() - || ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown()); + && (ModifierKeys::currentModifiers.isAnyMouseButtonDown() + || ComponentPeer::getCurrentModifiersRealtime().isAnyMouseButtonDown()); if (! window.doesAnyJuceCompHaveFocus()) { @@ -1593,7 +1593,7 @@ Component* PopupMenu::createWindow (const Options& options, return items.isEmpty() ? nullptr : new HelperClasses::MenuWindow (*this, nullptr, options, ! options.getTargetScreenArea().isEmpty(), - ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), + ModifierKeys::currentModifiers.isAnyMouseButtonDown(), managerOfChosenCommand); } diff --git a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp index ea4e509512..5bff2bb74f 100644 --- a/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp +++ b/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp @@ -316,7 +316,7 @@ private: { hasCheckedForExternalDrag = true; - if (ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown()) + if (ComponentPeer::getCurrentModifiersRealtime().isAnyMouseButtonDown()) { StringArray files; auto canMoveFiles = false; diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index 4a3e0b5264..efe7654ce0 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -47,7 +47,7 @@ public: ModifierKeys getCurrentModifiers() const noexcept { - return ModifierKeys::getCurrentModifiers().withoutMouseButtons().withFlags (buttonState.getRawFlags()); + return ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (buttonState.getRawFlags()); } ComponentPeer* getPeer() noexcept @@ -255,8 +255,6 @@ public: void setPeer (ComponentPeer& newPeer, Point screenPos, Time time) { - ModifierKeys::updateCurrentModifiers(); - if (&newPeer != lastPeer) { setComponentUnderMouse (nullptr, screenPos, time); @@ -760,7 +758,7 @@ struct MouseInputSource::SourceList : public Timer { // NB: when doing auto-repeat, we need to force an update of the current position and button state, // because on some OSes the queue can get overloaded with messages so that mouse-events don't get through.. - if (s->isDragging() && ModifierKeys::getCurrentModifiersRealtime().isAnyMouseButtonDown()) + if (s->isDragging() && ComponentPeer::getCurrentModifiersRealtime().isAnyMouseButtonDown()) { s->lastScreenPos = s->getRawScreenPosition(); s->triggerFakeMove(); diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 9f8ca138d5..34b71143bc 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -502,7 +502,7 @@ public: lastMousePos = localToGlobal (pos); // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. - handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(), + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); if (isValidPeer (this)) @@ -516,8 +516,8 @@ public: jassert (index < 64); touchesDown = (touchesDown | (1 << (index & 63))); - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); - handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); } @@ -530,9 +530,9 @@ public: touchesDown = (touchesDown & ~(1 << (index & 63))); if (touchesDown == 0) - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); - handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, + handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, ModifierKeys::currentModifiers.withoutMouseButtons(), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, index); } @@ -720,7 +720,6 @@ public: } //============================================================================== - static ModifierKeys currentModifiers; static Point lastMousePos; static int64 touchesDown; @@ -788,7 +787,6 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer) }; -ModifierKeys AndroidComponentPeer::currentModifiers = 0; Point AndroidComponentPeer::lastMousePos; int64 AndroidComponentPeer::touchesDown = 0; AndroidComponentPeer* AndroidComponentPeer::frontWindow = nullptr; @@ -896,16 +894,6 @@ bool KeyPress::isKeyCurrentlyDown (const int /*keyCode*/) return false; } -void ModifierKeys::updateCurrentModifiers() noexcept -{ - currentModifiers = AndroidComponentPeer::currentModifiers; -} - -ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept -{ - return AndroidComponentPeer::currentModifiers; -} - JUCE_API void JUCE_CALLTYPE Process::hide() { if (android.activity.callBooleanMethod (JuceAppActivity.moveTaskToBack, true) == 0) diff --git a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm index 2e910821fb..dc2499a82d 100644 --- a/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm @@ -220,7 +220,6 @@ public: JuceUIView* view; JuceUIViewController* controller; bool isSharedWindow, fullScreen, insideDrawRect, isAppex; - static ModifierKeys currentModifiers; static int64 getMouseTime (UIEvent* e) noexcept { @@ -536,18 +535,6 @@ bool KeyPress::isKeyCurrentlyDown (int) return false; } -ModifierKeys UIViewComponentPeer::currentModifiers; - -ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept -{ - return UIViewComponentPeer::currentModifiers; -} - -void ModifierKeys::updateCurrentModifiers() noexcept -{ - currentModifiers = UIViewComponentPeer::currentModifiers; -} - Point juce_lastMousePos; //============================================================================== @@ -844,15 +831,15 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons const int64 time = getMouseTime (event); const int touchIndex = currentTouches.getIndexOfTouch (this, touch); - ModifierKeys modsToSend (currentModifiers); + ModifierKeys modsToSend (ModifierKeys::currentModifiers); if (isDown) { if ([touch phase] != UITouchPhaseBegan) continue; - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); - modsToSend = currentModifiers; + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + modsToSend = ModifierKeys::currentModifiers; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(), @@ -876,7 +863,7 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, cons if (isCancel) { currentTouches.clearTouch (touchIndex); - modsToSend = currentModifiers = currentModifiers.withoutMouseButtons(); + modsToSend = ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); } // NB: some devices return 0 or 1.0 if pressure is unknown, so we'll clip our value to a believable range: diff --git a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp index fe0457c359..d6dc752ffd 100644 --- a/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp @@ -1483,6 +1483,33 @@ public: createWindow (parentToAddTo); setTitle (component.getName()); + + getNativeRealtimeModifiers = [] + { + ScopedXDisplay xDisplay; + + if (auto display = xDisplay.display) + { + Window root, child; + int x, y, winx, winy; + unsigned int mask; + int mouseMods = 0; + + ScopedXLock xlock (display); + + if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), + &root, &child, &x, &y, &winx, &winy, &mask) != False) + { + if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; + if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; + if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; + } + + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); + } + + return ModifierKeys::currentModifiers; + }; } ~LinuxComponentPeer() @@ -2034,7 +2061,7 @@ public: void handleKeyPressEvent (XKeyEvent& keyEvent) { - auto oldMods = currentModifiers; + auto oldMods = ModifierKeys::currentModifiers; char utf8 [64] = { 0 }; juce_wchar unicodeChar = 0; @@ -2057,7 +2084,7 @@ public: keyCode = (int) unicodeChar; if (keyCode < 0x20) - keyCode = (int) XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, currentModifiers.isShiftDown() ? 1 : 0); + keyCode = (int) XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, ModifierKeys::currentModifiers.isShiftDown() ? 1 : 0); keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, true); } @@ -2141,7 +2168,7 @@ public: if (utf8[0] != 0 || ((sym & 0xff00) == 0 && sym >= 8)) keyPressed = true; - if (oldMods != currentModifiers) + if (oldMods != ModifierKeys::currentModifiers) handleModifierKeysChange(); if (keyDownChange) @@ -2179,10 +2206,10 @@ public: sym = XkbKeycodeToKeysym (display, (::KeyCode) keyEvent.keycode, 0, 0); } - auto oldMods = currentModifiers; + auto oldMods = ModifierKeys::currentModifiers; const bool keyDownChange = (sym != NoSymbol) && ! updateKeyModifiersFromSym (sym, false); - if (oldMods != currentModifiers) + if (oldMods != ModifierKeys::currentModifiers) handleModifierKeysChange(); if (keyDownChange) @@ -2211,9 +2238,9 @@ public: void handleButtonPressEvent (const XButtonPressedEvent& buttonPressEvent, int buttonModifierFlag) { - currentModifiers = currentModifiers.withFlags (buttonModifierFlag); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (buttonModifierFlag); toFront (true); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonPressEvent), ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {}); } @@ -2252,9 +2279,9 @@ public: { switch (pointerMap[mapIndex]) { - case Keys::LeftButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; - case Keys::RightButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; - case Keys::MiddleButton: currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; + case Keys::LeftButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::leftButtonModifier); break; + case Keys::RightButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::rightButtonModifier); break; + case Keys::MiddleButton: ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); break; default: break; } } @@ -2262,7 +2289,7 @@ public: if (dragState->dragging) handleExternalDragButtonReleaseEvent(); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonRelEvent), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (buttonRelEvent), ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent)); clearLastMousePos(); @@ -2277,7 +2304,7 @@ public: if (dragState->dragging) handleExternalDragMotionNotify(); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (movedEvent), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (movedEvent), ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (movedEvent)); } @@ -2288,10 +2315,10 @@ public: clearLastMousePos(); - if (! currentModifiers.isAnyMouseButtonDown()) + if (! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) { updateKeyModifiers ((int) enterEvent.state); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (enterEvent), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (enterEvent), ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (enterEvent)); } } @@ -2301,11 +2328,11 @@ public: // Suppress the normal leave if we've got a pointer grab, or if // it's a bogus one caused by clicking a mouse button when running // in a Window manager - if (((! currentModifiers.isAnyMouseButtonDown()) && leaveEvent.mode == NotifyNormal) + if (((! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) && leaveEvent.mode == NotifyNormal) || leaveEvent.mode == NotifyUngrab) { updateKeyModifiers ((int) leaveEvent.state); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (leaveEvent), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (leaveEvent), ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (leaveEvent)); } } @@ -2594,8 +2621,6 @@ public: //============================================================================== bool dontRepaint; - - static ModifierKeys currentModifiers; static bool isActiveApplication; private: @@ -2784,7 +2809,7 @@ private: if ((status & ControlMask) != 0) keyMods |= ModifierKeys::ctrlModifier; if ((status & Keys::AltMask) != 0) keyMods |= ModifierKeys::altModifier; - currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); Keys::numLock = ((status & Keys::NumLockMask) != 0); Keys::capsLock = ((status & LockMask) != 0); @@ -2826,8 +2851,8 @@ private: break; } - currentModifiers = press ? currentModifiers.withFlags (modifier) - : currentModifiers.withoutFlags (modifier); + ModifierKeys::currentModifiers = press ? ModifierKeys::currentModifiers.withFlags (modifier) + : ModifierKeys::currentModifiers.withoutFlags (modifier); return isModifier; } @@ -3731,7 +3756,6 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LinuxComponentPeer) }; -ModifierKeys LinuxComponentPeer::currentModifiers; bool LinuxComponentPeer::isActiveApplication = false; Point LinuxComponentPeer::lastMousePos; ::Display* LinuxComponentPeer::display = nullptr; @@ -3779,40 +3803,6 @@ JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {} JUCE_API void JUCE_CALLTYPE Process::hide() {} -//============================================================================== -void ModifierKeys::updateCurrentModifiers() noexcept -{ - currentModifiers = LinuxComponentPeer::currentModifiers; -} - -ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept -{ - ScopedXDisplay xDisplay; - - if (auto display = xDisplay.display) - { - Window root, child; - int x, y, winx, winy; - unsigned int mask; - int mouseMods = 0; - - ScopedXLock xlock (display); - - if (XQueryPointer (display, RootWindow (display, DefaultScreen (display)), - &root, &child, &x, &y, &winx, &winy, &mask) != False) - { - if ((mask & Button1Mask) != 0) mouseMods |= ModifierKeys::leftButtonModifier; - if ((mask & Button2Mask) != 0) mouseMods |= ModifierKeys::middleButtonModifier; - if ((mask & Button3Mask) != 0) mouseMods |= ModifierKeys::rightButtonModifier; - } - - LinuxComponentPeer::currentModifiers = LinuxComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods); - } - - return LinuxComponentPeer::currentModifiers; -} - - //============================================================================== void Desktop::setKioskComponent (Component* comp, bool enableOrDisable, bool /* allowMenusAndBars */) { diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 4622bc6af1..520cb77b80 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -175,6 +175,16 @@ public: setAlpha (alpha); setTitle (component.getName()); + + getNativeRealtimeModifiers = [] + { + #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + if ([NSEvent respondsToSelector: @selector (modifierFlags)]) + NSViewComponentPeer::updateModifiers ([NSEvent modifierFlags]); + #endif + + return ModifierKeys::currentModifiers; + }; } ~NSViewComponentPeer() @@ -569,26 +579,26 @@ public: if (! Process::isForegroundProcess()) Process::makeForegroundProcess(); - currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); sendMouseEvent (ev); } void redirectMouseUp (NSEvent* ev) { - currentModifiers = currentModifiers.withoutFlags (getModifierForButtonNumber ([ev buttonNumber])); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutFlags (getModifierForButtonNumber ([ev buttonNumber])); sendMouseEvent (ev); showArrowCursorIfNeeded(); } void redirectMouseDrag (NSEvent* ev) { - currentModifiers = currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (getModifierForButtonNumber ([ev buttonNumber])); sendMouseEvent (ev); } void redirectMouseMove (NSEvent* ev) { - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); NSPoint windowPos = [ev locationInWindow]; @@ -602,7 +612,7 @@ public: sendMouseEvent (ev); else // moved into another window which overlaps this one, so trigger an exit - handleMouseEvent (MouseInputSource::InputSourceType::mouse, { -1.0f, -1.0f }, currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, { -1.0f, -1.0f }, ModifierKeys::currentModifiers, getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); showArrowCursorIfNeeded(); @@ -611,13 +621,13 @@ public: void redirectMouseEnter (NSEvent* ev) { Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate(); - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); sendMouseEvent (ev); } void redirectMouseExit (NSEvent* ev) { - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); sendMouseEvent (ev); } @@ -706,7 +716,7 @@ public: void sendMouseEvent (NSEvent* ev) { updateModifiers (ev); - handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), ModifierKeys::currentModifiers, getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); } @@ -1118,7 +1128,7 @@ public: if ((flags & NSEventModifierFlagOption) != 0) m |= ModifierKeys::altModifier; if ((flags & NSEventModifierFlagCommand) != 0) m |= ModifierKeys::commandModifier; - currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (m); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons().withFlags (m); } static void updateKeysDown (NSEvent* ev, bool isKeyDown) @@ -1388,7 +1398,6 @@ public: RectangleList deferredRepaints; uint32 lastRepaintTime; - static ModifierKeys currentModifiers; static ComponentPeer* currentlyFocusedPeer; static Array keysCurrentlyDown; static int insideToFrontCall; @@ -2042,7 +2051,6 @@ NSWindow* NSViewComponentPeer::createWindowInstance() //============================================================================== -ModifierKeys NSViewComponentPeer::currentModifiers; ComponentPeer* NSViewComponentPeer::currentlyFocusedPeer = nullptr; Array NSViewComponentPeer::keysCurrentlyDown; @@ -2063,23 +2071,6 @@ bool KeyPress::isKeyCurrentlyDown (int keyCode) return false; } - -ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept -{ - #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 - if ([NSEvent respondsToSelector: @selector (modifierFlags)]) - NSViewComponentPeer::updateModifiers ((NSUInteger) [NSEvent modifierFlags]); - #endif - - return NSViewComponentPeer::currentModifiers; -} - -void ModifierKeys::updateCurrentModifiers() noexcept -{ - currentModifiers = NSViewComponentPeer::currentModifiers; -} - - //============================================================================== bool MouseInputSource::SourceList::addSource() { diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index b5c946f33d..84bb8ce84c 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -1011,6 +1011,20 @@ public: // make sure that the on-screen keyboard code is loaded OnScreenKeyboard::getInstance(); + + getNativeRealtimeModifiers = [] + { + HWNDComponentPeer::updateKeyModifiers(); + + int mouseMods = 0; + if (HWNDComponentPeer::isKeyDown (VK_LBUTTON)) mouseMods |= ModifierKeys::leftButtonModifier; + if (HWNDComponentPeer::isKeyDown (VK_RBUTTON)) mouseMods |= ModifierKeys::rightButtonModifier; + if (HWNDComponentPeer::isKeyDown (VK_MBUTTON)) mouseMods |= ModifierKeys::middleButtonModifier; + + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); + + return ModifierKeys::currentModifiers; + }; } ~HWNDComponentPeer() @@ -1389,7 +1403,7 @@ public: keyMods = (keyMods & ~ModifierKeys::ctrlModifier) | ModifierKeys::altModifier; } - currentModifiers = currentModifiers.withOnlyMouseButtons().withFlags (keyMods); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withOnlyMouseButtons().withFlags (keyMods); } static void updateModifiersFromWParam (const WPARAM wParam) @@ -1399,14 +1413,12 @@ public: if (wParam & MK_RBUTTON) mouseMods |= ModifierKeys::rightButtonModifier; if (wParam & MK_MBUTTON) mouseMods |= ModifierKeys::middleButtonModifier; - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (mouseMods); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (mouseMods); updateKeyModifiers(); } //============================================================================== bool dontRepaint; - - static ModifierKeys currentModifiers; static ModifierKeys modifiersAtLastCallback; //============================================================================== @@ -2094,7 +2106,7 @@ private: } //============================================================================== - void doMouseEvent (Point position, float pressure, float orientation = 0.0f, ModifierKeys mods = currentModifiers) + void doMouseEvent (Point position, float pressure, float orientation = 0.0f, ModifierKeys mods = ModifierKeys::currentModifiers) { handleMouseEvent (MouseInputSource::InputSourceType::mouse, position, mods, pressure, orientation, getMouseEventTime()); } @@ -2169,7 +2181,7 @@ private: void doMouseMove (Point position, bool isMouseDownEvent) { - ModifierKeys modsToSend (currentModifiers); + ModifierKeys modsToSend (ModifierKeys::currentModifiers); // this will be handled by WM_TOUCH if (isTouchEvent() || areOtherTouchSourcesActive()) @@ -2182,14 +2194,14 @@ private: // This avoids a rare stuck-button problem when focus is lost unexpectedly, but must // not be called as part of a move, in case it's actually a mouse-drag from another // app which ends up here when we get focus before the mouse is released.. - if (isMouseDownEvent) - ModifierKeys::getCurrentModifiersRealtime(); + if (isMouseDownEvent && getNativeRealtimeModifiers != nullptr) + getNativeRealtimeModifiers(); updateKeyModifiers(); #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client if (modProvider != nullptr) - currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (modProvider->getWin32Modifiers()); #endif TRACKMOUSEEVENT tme; @@ -2241,7 +2253,7 @@ private: #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client if (modProvider != nullptr) - currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (modProvider->getWin32Modifiers()); #endif isDragging = true; @@ -2260,7 +2272,7 @@ private: #if JUCE_MODULE_AVAILABLE_juce_audio_plugin_client if (modProvider != nullptr) - currentModifiers = currentModifiers.withFlags (modProvider->getWin32Modifiers()); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (modProvider->getWin32Modifiers()); #endif const bool wasDragging = isDragging; @@ -2421,12 +2433,12 @@ private: const auto time = getMouseEventTime(); const auto pos = globalToLocal ({ touch.x / 100.0f, touch.y / 100.0f }); const auto pressure = touchPressure; - auto modsToSend = currentModifiers; + auto modsToSend = ModifierKeys::currentModifiers; if (isDown) { - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); - modsToSend = currentModifiers; + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + modsToSend = ModifierKeys::currentModifiers; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend.withoutMouseButtons(), @@ -2438,7 +2450,7 @@ private: else if (isUp) { modsToSend = modsToSend.withoutMouseButtons(); - currentModifiers = modsToSend; + ModifierKeys::currentModifiers = modsToSend; currentTouches.clearTouch (touchIndex); if (! currentTouches.areAnyTouchesActive()) @@ -2446,7 +2458,7 @@ private: } else { - modsToSend = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + modsToSend = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); } handleMouseEvent (MouseInputSource::InputSourceType::touch, pos, modsToSend, @@ -2457,7 +2469,7 @@ private: if (isUp) { - handleMouseEvent (MouseInputSource::InputSourceType::touch, { -10.0f, -10.0f }, currentModifiers.withoutMouseButtons(), + handleMouseEvent (MouseInputSource::InputSourceType::touch, { -10.0f, -10.0f }, ModifierKeys::currentModifiers.withoutMouseButtons(), pressure, orientation, time, {}, touchIndex); if (! isValidPeer (this)) @@ -2466,7 +2478,7 @@ private: if (isCancel) { currentTouches.clear(); - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); } } @@ -2530,7 +2542,7 @@ private: bool handlePenInput (POINTER_PEN_INFO penInfo, Point pos, const float pressure, bool isDown, bool isUp) { const auto time = getMouseEventTime(); - ModifierKeys modsToSend (currentModifiers); + ModifierKeys modsToSend (ModifierKeys::currentModifiers); PenDetails penDetails; penDetails.rotation = (penInfo.penMask & PEN_MASK_ROTATION) ? degreesToRadians (static_cast (penInfo.rotation)) : MouseInputSource::invalidRotation; @@ -2540,13 +2552,13 @@ private: auto pInfoFlags = penInfo.pointerInfo.pointerFlags; if ((pInfoFlags & POINTER_FLAG_FIRSTBUTTON) != 0) - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); else if ((pInfoFlags & POINTER_FLAG_SECONDBUTTON) != 0) - currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::rightButtonModifier); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::rightButtonModifier); if (isDown) { - modsToSend = currentModifiers; + modsToSend = ModifierKeys::currentModifiers; // this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before. handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend.withoutMouseButtons(), @@ -2558,7 +2570,7 @@ private: else if (isUp || ! (pInfoFlags & POINTER_FLAG_INCONTACT)) { modsToSend = modsToSend.withoutMouseButtons(); - currentModifiers = currentModifiers.withoutMouseButtons(); + ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withoutMouseButtons(); } handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend, pressure, @@ -2569,7 +2581,7 @@ private: if (isUp) { - handleMouseEvent (MouseInputSource::InputSourceType::pen, { -10.0f, -10.0f }, currentModifiers, + handleMouseEvent (MouseInputSource::InputSourceType::pen, { -10.0f, -10.0f }, ModifierKeys::currentModifiers, pressure, MouseInputSource::invalidOrientation, time, penDetails); if (! isValidPeer (this)) @@ -2582,9 +2594,9 @@ private: //============================================================================== void sendModifierKeyChangeIfNeeded() { - if (modifiersAtLastCallback != currentModifiers) + if (modifiersAtLastCallback != ModifierKeys::currentModifiers) { - modifiersAtLastCallback = currentModifiers; + modifiersAtLastCallback = ModifierKeys::currentModifiers; handleModifierKeysChange(); } } @@ -2747,7 +2759,7 @@ private: key = (int) keyChar; // avoid sending junk text characters for some control-key combinations - if (textChar < ' ' && currentModifiers.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::altModifier)) + if (textChar < ' ' && ModifierKeys::currentModifiers.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::altModifier)) textChar = 0; } @@ -3633,10 +3645,8 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (HWNDComponentPeer) }; -ModifierKeys HWNDComponentPeer::currentModifiers; -ModifierKeys HWNDComponentPeer::modifiersAtLastCallback; - MultiTouchMapper HWNDComponentPeer::currentTouches; +ModifierKeys HWNDComponentPeer::modifiersAtLastCallback; ComponentPeer* Component::createNewPeer (int styleFlags, void* parentHWND) { @@ -3649,30 +3659,8 @@ JUCE_API ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& compo (HWND) parentHWND, true); } - JUCE_IMPLEMENT_SINGLETON (HWNDComponentPeer::WindowClassHolder) -//============================================================================== -void ModifierKeys::updateCurrentModifiers() noexcept -{ - currentModifiers = HWNDComponentPeer::currentModifiers; -} - -ModifierKeys ModifierKeys::getCurrentModifiersRealtime() noexcept -{ - HWNDComponentPeer::updateKeyModifiers(); - - int mouseMods = 0; - if (HWNDComponentPeer::isKeyDown (VK_LBUTTON)) mouseMods |= ModifierKeys::leftButtonModifier; - if (HWNDComponentPeer::isKeyDown (VK_RBUTTON)) mouseMods |= ModifierKeys::rightButtonModifier; - if (HWNDComponentPeer::isKeyDown (VK_MBUTTON)) mouseMods |= ModifierKeys::middleButtonModifier; - - HWNDComponentPeer::currentModifiers - = HWNDComponentPeer::currentModifiers.withoutMouseButtons().withFlags (mouseMods); - - return HWNDComponentPeer::currentModifiers; -} - //============================================================================== bool KeyPress::isKeyCurrentlyDown (const int keyCode) { diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 20fa433239..f7363eb6c8 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2057,7 +2057,7 @@ bool TextEditor::keyStateChanged (const bool isKeyDown) return false; // (overridden to avoid forwarding key events to the parent) - return ! ModifierKeys::getCurrentModifiers().isCommandDown(); + return ! ModifierKeys::currentModifiers.isCommandDown(); } //============================================================================== diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp index 55b8bd2e7b..11ce907574 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp @@ -103,8 +103,6 @@ void ComponentPeer::handleMagnifyGesture (MouseInputSource::InputSourceType type //============================================================================== void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) { - ModifierKeys::updateCurrentModifiers(); - Graphics g (contextToPaintTo); if (component.isTransformed()) @@ -173,10 +171,8 @@ Component* ComponentPeer::getTargetForKeyPress() bool ComponentPeer::handleKeyPress (const int keyCode, const juce_wchar textCharacter) { - ModifierKeys::updateCurrentModifiers(); - return handleKeyPress (KeyPress (keyCode, - ModifierKeys::getCurrentModifiers().withoutMouseButtons(), + ModifierKeys::currentModifiers.withoutMouseButtons(), textCharacter)); } @@ -228,7 +224,6 @@ bool ComponentPeer::handleKeyPress (const KeyPress& keyInfo) bool ComponentPeer::handleKeyUpOrDown (const bool isKeyDown) { - ModifierKeys::updateCurrentModifiers(); bool keyWasUsed = false; for (auto* target = getTargetForKeyPress(); target != nullptr; target = target->getParentComponent()) @@ -259,8 +254,6 @@ bool ComponentPeer::handleKeyUpOrDown (const bool isKeyDown) void ComponentPeer::handleModifierKeysChange() { - ModifierKeys::updateCurrentModifiers(); - auto* target = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); if (target == nullptr) @@ -289,7 +282,6 @@ void ComponentPeer::dismissPendingTextInput() {} //============================================================================== void ComponentPeer::handleBroughtToFront() { - ModifierKeys::updateCurrentModifiers(); component.internalBroughtToFront(); } @@ -300,8 +292,6 @@ void ComponentPeer::setConstrainer (ComponentBoundsConstrainer* const newConstra void ComponentPeer::handleMovedOrResized() { - ModifierKeys::updateCurrentModifiers(); - const bool nowMinimised = isMinimised(); if (component.flags.hasHeavyweightPeerFlag && ! nowMinimised) @@ -341,8 +331,6 @@ void ComponentPeer::handleMovedOrResized() void ComponentPeer::handleFocusGain() { - ModifierKeys::updateCurrentModifiers(); - if (component.isParentOf (lastFocusedComponent) && lastFocusedComponent->isShowing() && lastFocusedComponent->getWantsKeyboardFocus()) @@ -362,8 +350,6 @@ void ComponentPeer::handleFocusGain() void ComponentPeer::handleFocusLoss() { - ModifierKeys::updateCurrentModifiers(); - if (component.hasKeyboardFocus (true)) { lastFocusedComponent = Component::currentlyFocusedComponent; @@ -386,8 +372,6 @@ Component* ComponentPeer::getLastFocusedSubcomponent() const noexcept void ComponentPeer::handleScreenSizeChange() { - ModifierKeys::updateCurrentModifiers(); - component.parentSizeChanged(); handleMovedOrResized(); } @@ -453,8 +437,6 @@ namespace DragHelpers bool ComponentPeer::handleDragMove (const ComponentPeer::DragInfo& info) { - ModifierKeys::updateCurrentModifiers(); - auto* compUnderMouse = component.getComponentAt (info.position); auto* lastTarget = dragAndDropTargetComponent.get(); Component* newTarget = nullptr; @@ -562,7 +544,6 @@ bool ComponentPeer::handleDragDrop (const ComponentPeer::DragInfo& info) //============================================================================== void ComponentPeer::handleUserClosingWindow() { - ModifierKeys::updateCurrentModifiers(); component.userTriedToCloseWindow(); } @@ -579,4 +560,16 @@ void ComponentPeer::setRepresentedFile (const File&) int ComponentPeer::getCurrentRenderingEngine() const { return 0; } void ComponentPeer::setCurrentRenderingEngine (int index) { jassert (index == 0); ignoreUnused (index); } +//============================================================================== +std::function ComponentPeer::getNativeRealtimeModifiers = nullptr; + +ModifierKeys ComponentPeer::getCurrentModifiersRealtime() noexcept +{ + if (getNativeRealtimeModifiers != nullptr) + return getNativeRealtimeModifiers(); + + return ModifierKeys::currentModifiers; +} + + } // namespace juce diff --git a/modules/juce_gui_basics/windows/juce_ComponentPeer.h b/modules/juce_gui_basics/windows/juce_ComponentPeer.h index 49384e5070..1440597d89 100644 --- a/modules/juce_gui_basics/windows/juce_ComponentPeer.h +++ b/modules/juce_gui_basics/windows/juce_ComponentPeer.h @@ -364,12 +364,26 @@ public: virtual int getCurrentRenderingEngine() const; virtual void setCurrentRenderingEngine (int index); + //============================================================================== + /** On desktop platforms this method will check all the mouse and key states and return + a ModifierKeys object representing them. + + This isn't recommended and is only needed in special circumstances for up-to-date + modifier information at times when the app's event loop isn't running normally. + + Another reason to avoid this method is that it's not stateless and calling it may + update the ModifierKeys::currentModifiers object, which could cause subtle changes + in the behaviour of some components. + */ + static ModifierKeys getCurrentModifiersRealtime() noexcept; + protected: //============================================================================== Component& component; const int styleFlags; Rectangle lastNonFullscreenBounds; ComponentBoundsConstrainer* constrainer = nullptr; + static std::function getNativeRealtimeModifiers; private: //============================================================================== diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index cf863fe2d1..8bd5d8e9f3 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -122,7 +122,7 @@ void TooltipWindow::displayTip (Point screenPos, const String& tip) String TooltipWindow::getTipFor (Component& c) { if (Process::isForegroundProcess() - && ! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown()) + && ! ModifierKeys::currentModifiers.isAnyMouseButtonDown()) { if (auto* ttc = dynamic_cast (&c)) if (! c.isCurrentlyBlockedByAnotherModalComponent()) diff --git a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp index c228c3d304..b49f9060ff 100644 --- a/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_mac_SystemTrayIcon.cpp @@ -95,7 +95,7 @@ public: } else { - auto eventMods = ModifierKeys::getCurrentModifiersRealtime(); + auto eventMods = ComponentPeer::getCurrentModifiersRealtime(); if (([e modifierFlags] & NSEventModifierFlagCommand) != 0) eventMods = eventMods.withFlags (ModifierKeys::commandModifier); diff --git a/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp b/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp index 65a65ec6bc..98ead94094 100644 --- a/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp +++ b/modules/juce_gui_extra/native/juce_win32_ActiveXComponent.cpp @@ -216,7 +216,7 @@ namespace ActiveXHelpers peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, { (float) (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left), (float) (GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top) }, - ModifierKeys::getCurrentModifiersRealtime(), + ComponentPeer::getCurrentModifiersRealtime(), MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getMouseEventTime()); diff --git a/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp b/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp index b6bfb16faf..66b540a400 100644 --- a/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp +++ b/modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp @@ -104,7 +104,7 @@ public: } else { - ModifierKeys eventMods (ModifierKeys::getCurrentModifiersRealtime()); + ModifierKeys eventMods (ComponentPeer::getCurrentModifiersRealtime()); if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) eventMods = eventMods.withFlags (ModifierKeys::leftButtonModifier);