From a115c99da46817f256384df3e880de02d89c27aa Mon Sep 17 00:00:00 2001 From: attila Date: Fri, 9 Dec 2022 10:54:02 +0100 Subject: [PATCH] MouseInputSource: Avoid wrong ComponentPeer association When the mouse moves from one window to another, the mouseExit event for the old window can occur after the mouseMove event for the new. Until this commit this would cause the MouseInputSource to be associated with the old window, and getComponentUnderMouse() would incorrectly return a nullptr. --- .../mouse/juce_MouseInputSource.cpp | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index 24d0e63a04..646cdd1932 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -57,18 +57,18 @@ public: return lastPeer; } - Component* findComponentAt (Point screenPos) + static Component* findComponentAt (Point screenPos, ComponentPeer* peer) { - if (auto* peer = getPeer()) - { - auto relativePos = ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(), - peer->globalToLocal (screenPos)); - auto& comp = peer->getComponent(); + if (! ComponentPeer::isValidPeer (peer)) + return nullptr; - // (the contains() call is needed to test for overlapping desktop windows) - if (comp.contains (relativePos)) - return comp.getComponentAt (relativePos); - } + auto relativePos = ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(), + peer->globalToLocal (screenPos)); + auto& comp = peer->getComponent(); + + // (the contains() call is needed to test for overlapping desktop windows) + if (comp.contains (relativePos)) + return comp.getComponentAt (relativePos); return nullptr; } @@ -244,11 +244,12 @@ public: void setPeer (ComponentPeer& newPeer, const PointerState& pointerState, Time time) { - if (&newPeer != lastPeer) + if (&newPeer != lastPeer && ( findComponentAt (pointerState.position, &newPeer) != nullptr + || findComponentAt (pointerState.position, lastPeer) == nullptr)) { setComponentUnderMouse (nullptr, pointerState, time); lastPeer = &newPeer; - setComponentUnderMouse (findComponentAt (pointerState.position), pointerState, time); + setComponentUnderMouse (findComponentAt (pointerState.position, getPeer()), pointerState, time); } } @@ -257,7 +258,7 @@ public: const auto& newScreenPos = newPointerState.position; if (! isDragging()) - setComponentUnderMouse (findComponentAt (newScreenPos), newPointerState, time); + setComponentUnderMouse (findComponentAt (newScreenPos, getPeer()), newPointerState, time); if ((newPointerState != lastPointerState) || forceUpdate) {