The bug was triggered on Monterey where a pressure of 1 is reported while a mouse button is being held down. This caused an extra drag event being triggered between mouse down and up events, even if no movement occurred.v6.1.6
| @@ -4,6 +4,30 @@ JUCE breaking changes | |||
| develop | |||
| ======= | |||
| Change | |||
| ------ | |||
| The invalidPressure, invalidOrientation, invalidRotation, invalidTiltX and | |||
| invalidTiltY members of MouseInputSource have been deprecated. | |||
| Possible Issues | |||
| --------------- | |||
| Deprecation warnings will be seen when compiling code which uses these members | |||
| and eventually builds will fail when they are later removed from the API. | |||
| Workaround | |||
| ---------- | |||
| Use the equivalent defaultPressure, defaultOrientation, defaultRotation, | |||
| defaultTiltX and defaultTiltY members of MouseInputSource. | |||
| Rationale | |||
| --------- | |||
| The deprecated members represent valid values and the isPressureValid() etc. | |||
| functions return true when using them. This could be a source of confusion and | |||
| may be inviting programming errors. The new names are in line with the ongoing | |||
| practice of using these values to provide a neutral default in the absence of | |||
| actual OS provided values. | |||
| Change | |||
| ------ | |||
| Plugin wrappers will no longer call processBlockBypassed() if the wrapped | |||
| @@ -126,8 +126,8 @@ public: | |||
| { | |||
| ModifierKeys::currentModifiers = mods; | |||
| handleMouseEvent (juce::MouseInputSource::mouse, position, mods, juce::MouseInputSource::invalidPressure, | |||
| juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis()); | |||
| handleMouseEvent (juce::MouseInputSource::mouse, position, mods, juce::MouseInputSource::defaultPressure, | |||
| juce::MouseInputSource::defaultOrientation, juce::Time::currentTimeMillis()); | |||
| } | |||
| void forwardKeyPress (int code, String name, ModifierKeys mods) | |||
| @@ -199,7 +199,7 @@ private: | |||
| if (! ms.getCurrentModifiers().isLeftButtonDown()) | |||
| owner.handleMouseEvent (juce::MouseInputSource::mouse, owner.globalToLocal (pos.toFloat()), {}, | |||
| juce::MouseInputSource::invalidPressure, juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis()); | |||
| juce::MouseInputSource::defaultPressure, juce::MouseInputSource::defaultOrientation, juce::Time::currentTimeMillis()); | |||
| lastMousePos = pos; | |||
| } | |||
| @@ -2382,10 +2382,16 @@ void Component::internalMouseEnter (MouseInputSource source, Point<float> relati | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| this, this, time, relativePos, time, 0, false); | |||
| const auto me = makeMouseEvent (source, | |||
| PointerState().withPosition (relativePos), | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePos, | |||
| time, | |||
| 0, | |||
| false); | |||
| mouseEnter (me); | |||
| flags.cachedMouseInsideComponent = true; | |||
| @@ -2414,10 +2420,16 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| this, this, time, relativePos, time, 0, false); | |||
| const auto me = makeMouseEvent (source, | |||
| PointerState().withPosition (relativePos), | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePos, | |||
| time, | |||
| 0, | |||
| false); | |||
| mouseExit (me); | |||
| @@ -2429,8 +2441,7 @@ void Component::internalMouseExit (MouseInputSource source, Point<float> relativ | |||
| MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseExit, me); | |||
| } | |||
| void Component::internalMouseDown (MouseInputSource source, Point<float> relativePos, Time time, | |||
| float pressure, float orientation, float rotation, float tiltX, float tiltY) | |||
| void Component::internalMouseDown (MouseInputSource source, const PointerState& relativePointerState, Time time) | |||
| { | |||
| auto& desktop = Desktop::getInstance(); | |||
| BailOutChecker checker (this); | |||
| @@ -2448,9 +2459,16 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| // allow blocked mouse-events to go to global listeners.. | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure, | |||
| orientation, rotation, tiltX, tiltY, this, this, time, relativePos, | |||
| time, source.getNumberOfMultipleClicks(), false); | |||
| const auto me = makeMouseEvent (source, | |||
| relativePointerState, | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePointerState.position, | |||
| time, | |||
| source.getNumberOfMultipleClicks(), | |||
| false); | |||
| desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDown (me); }); | |||
| return; | |||
| @@ -2481,9 +2499,16 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| repaint(); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), pressure, | |||
| orientation, rotation, tiltX, tiltY, this, this, time, relativePos, | |||
| time, source.getNumberOfMultipleClicks(), false); | |||
| const auto me = makeMouseEvent (source, | |||
| relativePointerState, | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePointerState.position, | |||
| time, | |||
| source.getNumberOfMultipleClicks(), | |||
| false); | |||
| mouseDown (me); | |||
| if (checker.shouldBailOut()) | |||
| @@ -2494,8 +2519,7 @@ void Component::internalMouseDown (MouseInputSource source, Point<float> relativ | |||
| MouseListenerList::template sendMouseEvent<const MouseEvent&> (*this, checker, &MouseListener::mouseDown, me); | |||
| } | |||
| void Component::internalMouseUp (MouseInputSource source, Point<float> relativePos, Time time, | |||
| const ModifierKeys oldModifiers, float pressure, float orientation, float rotation, float tiltX, float tiltY) | |||
| void Component::internalMouseUp (MouseInputSource source, const PointerState& relativePointerState, Time time, const ModifierKeys oldModifiers) | |||
| { | |||
| if (flags.mouseDownWasBlocked && isCurrentlyBlockedByAnotherModalComponent()) | |||
| return; | |||
| @@ -2505,12 +2529,16 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP | |||
| if (flags.repaintOnMouseActivityFlag) | |||
| repaint(); | |||
| const MouseEvent me (source, relativePos, oldModifiers, pressure, orientation, | |||
| rotation, tiltX, tiltY, this, this, time, | |||
| getLocalPoint (nullptr, source.getLastMouseDownPosition()), | |||
| source.getLastMouseDownTime(), | |||
| source.getNumberOfMultipleClicks(), | |||
| source.isLongPressOrDrag()); | |||
| const auto me = makeMouseEvent (source, | |||
| relativePointerState, | |||
| oldModifiers, | |||
| this, | |||
| this, | |||
| time, | |||
| getLocalPoint (nullptr, source.getLastMouseDownPosition()), | |||
| source.getLastMouseDownTime(), | |||
| source.getNumberOfMultipleClicks(), | |||
| source.isLongPressOrDrag()); | |||
| mouseUp (me); | |||
| if (checker.shouldBailOut()) | |||
| @@ -2537,19 +2565,22 @@ void Component::internalMouseUp (MouseInputSource source, Point<float> relativeP | |||
| } | |||
| } | |||
| void Component::internalMouseDrag (MouseInputSource source, Point<float> relativePos, Time time, | |||
| float pressure, float orientation, float rotation, float tiltX, float tiltY) | |||
| void Component::internalMouseDrag (MouseInputSource source, const PointerState& relativePointerState, Time time) | |||
| { | |||
| if (! isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), | |||
| pressure, orientation, rotation, tiltX, tiltY, this, this, time, | |||
| getLocalPoint (nullptr, source.getLastMouseDownPosition()), | |||
| source.getLastMouseDownTime(), | |||
| source.getNumberOfMultipleClicks(), | |||
| source.isLongPressOrDrag()); | |||
| const auto me = makeMouseEvent (source, | |||
| relativePointerState, | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| getLocalPoint (nullptr, source.getLastMouseDownPosition()), | |||
| source.getLastMouseDownTime(), | |||
| source.getNumberOfMultipleClicks(), | |||
| source.isLongPressOrDrag()); | |||
| mouseDrag (me); | |||
| if (checker.shouldBailOut()) | |||
| @@ -2574,10 +2605,16 @@ void Component::internalMouseMove (MouseInputSource source, Point<float> relativ | |||
| { | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| this, this, time, relativePos, time, 0, false); | |||
| const auto me = makeMouseEvent (source, | |||
| PointerState().withPosition (relativePos), | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePos, | |||
| time, | |||
| 0, | |||
| false); | |||
| mouseMove (me); | |||
| if (checker.shouldBailOut()) | |||
| @@ -2595,10 +2632,16 @@ void Component::internalMouseWheel (MouseInputSource source, Point<float> relati | |||
| auto& desktop = Desktop::getInstance(); | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| this, this, time, relativePos, time, 0, false); | |||
| const auto me = makeMouseEvent (source, | |||
| PointerState().withPosition (relativePos), | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePos, | |||
| time, | |||
| 0, | |||
| false); | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| @@ -2625,10 +2668,16 @@ void Component::internalMagnifyGesture (MouseInputSource source, Point<float> re | |||
| auto& desktop = Desktop::getInstance(); | |||
| BailOutChecker checker (this); | |||
| const MouseEvent me (source, relativePos, source.getCurrentModifiers(), MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| this, this, time, relativePos, time, 0, false); | |||
| const auto me = makeMouseEvent (source, | |||
| PointerState().withPosition (relativePos), | |||
| source.getCurrentModifiers(), | |||
| this, | |||
| this, | |||
| time, | |||
| relativePos, | |||
| time, | |||
| 0, | |||
| false); | |||
| if (isCurrentlyBlockedByAnotherModalComponent()) | |||
| { | |||
| @@ -2594,9 +2594,9 @@ private: | |||
| //============================================================================== | |||
| void internalMouseEnter (MouseInputSource, Point<float>, Time); | |||
| void internalMouseExit (MouseInputSource, Point<float>, Time); | |||
| void internalMouseDown (MouseInputSource, Point<float>, Time, float, float, float, float, float); | |||
| void internalMouseUp (MouseInputSource, Point<float>, Time, const ModifierKeys oldModifiers, float, float, float, float, float); | |||
| void internalMouseDrag (MouseInputSource, Point<float>, Time, float, float, float, float, float); | |||
| void internalMouseDown (MouseInputSource, const PointerState&, Time); | |||
| void internalMouseUp (MouseInputSource, const PointerState&, Time, const ModifierKeys oldModifiers); | |||
| void internalMouseDrag (MouseInputSource, const PointerState&, Time); | |||
| void internalMouseMove (MouseInputSource, Point<float>, Time); | |||
| void internalMouseWheel (MouseInputSource, Point<float>, Time, const MouseWheelDetails&); | |||
| void internalMagnifyGesture (MouseInputSource, Point<float>, Time, float); | |||
| @@ -276,9 +276,9 @@ void Desktop::sendMouseMove() | |||
| auto pos = target->getLocalPoint (nullptr, lastFakeMouseMove); | |||
| auto now = Time::getCurrentTime(); | |||
| const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| const MouseEvent me (getMainMouseSource(), pos, ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| target, target, now, pos, now, 0, false); | |||
| if (me.mods.isAnyMouseButtonDown()) | |||
| @@ -127,6 +127,8 @@ namespace juce | |||
| }; | |||
| } // namespace juce | |||
| #include "mouse/juce_PointerState.h" | |||
| #include "accessibility/juce_AccessibilityHandler.cpp" | |||
| #include "components/juce_Component.cpp" | |||
| #include "components/juce_ComponentListener.cpp" | |||
| @@ -158,6 +158,7 @@ namespace juce | |||
| class Displays; | |||
| class AccessibilityHandler; | |||
| class KeyboardFocusTraverser; | |||
| class PointerState; | |||
| class FlexBox; | |||
| class Grid; | |||
| @@ -95,7 +95,7 @@ public: | |||
| Point<float> getRawScreenPosition() const noexcept | |||
| { | |||
| return unboundedMouseOffset + (inputType != MouseInputSource::InputSourceType::touch ? MouseInputSource::getCurrentRawMousePosition() | |||
| : lastScreenPos); | |||
| : lastPointerState.position); | |||
| } | |||
| void setScreenPosition (Point<float> p) | |||
| @@ -103,78 +103,80 @@ public: | |||
| MouseInputSource::setRawMousePosition (ScalingHelpers::scaledScreenPosToUnscaled (p)); | |||
| } | |||
| bool isPressureValid() const noexcept { return pressure >= 0.0f && pressure <= 1.0f; } | |||
| bool isOrientationValid() const noexcept { return orientation >= 0.0f && orientation <= MathConstants<float>::twoPi; } | |||
| bool isRotationValid() const noexcept { return rotation >= 0.0f && rotation <= MathConstants<float>::twoPi; } | |||
| bool isTiltValid (bool isX) const noexcept { return isX ? (tiltX >= -1.0f && tiltX <= 1.0f) : (tiltY >= -1.0f && tiltY <= 1.0f); } | |||
| //============================================================================== | |||
| #if JUCE_DUMP_MOUSE_EVENTS | |||
| #define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " << desc << " #" << index \ | |||
| << ": " << screenPosToLocalPos (comp, screenPos).toString() \ | |||
| << " - Comp: " << String::toHexString ((pointer_sized_int) &comp)); | |||
| #define JUCE_MOUSE_EVENT_DBG(desc, screenPos) DBG ("Mouse " << desc << " #" << index \ | |||
| << ": " << screenPosToLocalPos (comp, screenPos).toString() \ | |||
| << " - Comp: " << String::toHexString ((pointer_sized_int) &comp)); | |||
| #else | |||
| #define JUCE_MOUSE_EVENT_DBG(desc) | |||
| #define JUCE_MOUSE_EVENT_DBG(desc, screenPos) | |||
| #endif | |||
| void sendMouseEnter (Component& comp, Point<float> screenPos, Time time) | |||
| void sendMouseEnter (Component& comp, const PointerState& pointerState, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("enter") | |||
| comp.internalMouseEnter (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| JUCE_MOUSE_EVENT_DBG ("enter", pointerState.position) | |||
| comp.internalMouseEnter (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); | |||
| } | |||
| void sendMouseExit (Component& comp, Point<float> screenPos, Time time) | |||
| void sendMouseExit (Component& comp, const PointerState& pointerState, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("exit") | |||
| comp.internalMouseExit (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| JUCE_MOUSE_EVENT_DBG ("exit", pointerState.position) | |||
| comp.internalMouseExit (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); | |||
| } | |||
| void sendMouseMove (Component& comp, Point<float> screenPos, Time time) | |||
| void sendMouseMove (Component& comp, const PointerState& pointerState, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("move") | |||
| comp.internalMouseMove (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time); | |||
| JUCE_MOUSE_EVENT_DBG ("move", pointerState.position) | |||
| comp.internalMouseMove (MouseInputSource (this), screenPosToLocalPos (comp, pointerState.position), time); | |||
| } | |||
| void sendMouseDown (Component& comp, Point<float> screenPos, Time time) | |||
| void sendMouseDown (Component& comp, const PointerState& pointerState, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("down") | |||
| comp.internalMouseDown (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY); | |||
| JUCE_MOUSE_EVENT_DBG ("down", pointerState.position) | |||
| comp.internalMouseDown (MouseInputSource (this), | |||
| pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), | |||
| time); | |||
| } | |||
| void sendMouseDrag (Component& comp, Point<float> screenPos, Time time) | |||
| void sendMouseDrag (Component& comp, const PointerState& pointerState, Time time) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("drag") | |||
| comp.internalMouseDrag (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, pressure, orientation, rotation, tiltX, tiltY); | |||
| JUCE_MOUSE_EVENT_DBG ("drag", pointerState.position) | |||
| comp.internalMouseDrag (MouseInputSource (this), | |||
| pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), | |||
| time); | |||
| } | |||
| void sendMouseUp (Component& comp, Point<float> screenPos, Time time, ModifierKeys oldMods) | |||
| void sendMouseUp (Component& comp, const PointerState& pointerState, Time time, ModifierKeys oldMods) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("up") | |||
| comp.internalMouseUp (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, oldMods, pressure, orientation, rotation, tiltX, tiltY); | |||
| JUCE_MOUSE_EVENT_DBG ("up", pointerState.position) | |||
| comp.internalMouseUp (MouseInputSource (this), | |||
| pointerState.withPosition (screenPosToLocalPos (comp, pointerState.position)), | |||
| time, | |||
| oldMods); | |||
| } | |||
| void sendMouseWheel (Component& comp, Point<float> screenPos, Time time, const MouseWheelDetails& wheel) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("wheel") | |||
| JUCE_MOUSE_EVENT_DBG ("wheel", screenPos) | |||
| comp.internalMouseWheel (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, wheel); | |||
| } | |||
| void sendMagnifyGesture (Component& comp, Point<float> screenPos, Time time, float amount) | |||
| { | |||
| JUCE_MOUSE_EVENT_DBG ("magnify") | |||
| JUCE_MOUSE_EVENT_DBG ("magnify", screenPos) | |||
| comp.internalMagnifyGesture (MouseInputSource (this), screenPosToLocalPos (comp, screenPos), time, amount); | |||
| } | |||
| //============================================================================== | |||
| // (returns true if the button change caused a modal event loop) | |||
| bool setButtons (Point<float> screenPos, Time time, ModifierKeys newButtonState) | |||
| bool setButtons (const PointerState& pointerState, Time time, ModifierKeys newButtonState) | |||
| { | |||
| if (buttonState == newButtonState) | |||
| return false; | |||
| // (avoid sending a spurious mouse-drag when we receive a mouse-up) | |||
| if (! (isDragging() && ! newButtonState.isAnyMouseButtonDown())) | |||
| setScreenPos (screenPos, time, false); | |||
| setPointerState (pointerState, time, false); | |||
| // (ignore secondary clicks when there's already a button down) | |||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||
| @@ -192,7 +194,7 @@ public: | |||
| auto oldMods = getCurrentModifiers(); | |||
| buttonState = newButtonState; // must change this before calling sendMouseUp, in case it runs a modal loop | |||
| sendMouseUp (*current, screenPos + unboundedMouseOffset, time, oldMods); | |||
| sendMouseUp (*current, pointerState.withPositionOffset (unboundedMouseOffset), time, oldMods); | |||
| if (lastCounter != mouseEventCounter) | |||
| return true; // if a modal loop happened, then newButtonState is no longer valid. | |||
| @@ -209,16 +211,16 @@ public: | |||
| if (auto* current = getComponentUnderMouse()) | |||
| { | |||
| registerMouseDown (screenPos, time, *current, buttonState, | |||
| registerMouseDown (pointerState.position, time, *current, buttonState, | |||
| inputType == MouseInputSource::InputSourceType::touch); | |||
| sendMouseDown (*current, screenPos, time); | |||
| sendMouseDown (*current, pointerState, time); | |||
| } | |||
| } | |||
| return lastCounter != mouseEventCounter; | |||
| } | |||
| void setComponentUnderMouse (Component* newComponent, Point<float> screenPos, Time time) | |||
| void setComponentUnderMouse (Component* newComponent, const PointerState& pointerState, Time time) | |||
| { | |||
| auto* current = getComponentUnderMouse(); | |||
| @@ -230,12 +232,12 @@ public: | |||
| if (current != nullptr) | |||
| { | |||
| WeakReference<Component> safeOldComp (current); | |||
| setButtons (screenPos, time, ModifierKeys()); | |||
| setButtons (pointerState, time, ModifierKeys()); | |||
| if (auto oldComp = safeOldComp.get()) | |||
| { | |||
| componentUnderMouse = safeNewComp; | |||
| sendMouseExit (*oldComp, screenPos, time); | |||
| sendMouseExit (*oldComp, pointerState, time); | |||
| } | |||
| buttonState = originalButtonState; | |||
| @@ -245,48 +247,50 @@ public: | |||
| current = safeNewComp.get(); | |||
| if (current != nullptr) | |||
| sendMouseEnter (*current, screenPos, time); | |||
| sendMouseEnter (*current, pointerState, time); | |||
| revealCursor (false); | |||
| setButtons (screenPos, time, originalButtonState); | |||
| setButtons (pointerState, time, originalButtonState); | |||
| } | |||
| } | |||
| void setPeer (ComponentPeer& newPeer, Point<float> screenPos, Time time) | |||
| void setPeer (ComponentPeer& newPeer, const PointerState& pointerState, Time time) | |||
| { | |||
| if (&newPeer != lastPeer) | |||
| { | |||
| setComponentUnderMouse (nullptr, screenPos, time); | |||
| setComponentUnderMouse (nullptr, pointerState, time); | |||
| lastPeer = &newPeer; | |||
| setComponentUnderMouse (findComponentAt (screenPos), screenPos, time); | |||
| setComponentUnderMouse (findComponentAt (pointerState.position), pointerState, time); | |||
| } | |||
| } | |||
| void setScreenPos (Point<float> newScreenPos, Time time, bool forceUpdate) | |||
| void setPointerState (const PointerState& newPointerState, Time time, bool forceUpdate) | |||
| { | |||
| const auto& newScreenPos = newPointerState.position; | |||
| if (! isDragging()) | |||
| setComponentUnderMouse (findComponentAt (newScreenPos), newScreenPos, time); | |||
| setComponentUnderMouse (findComponentAt (newScreenPos), newPointerState, time); | |||
| if (newScreenPos != lastScreenPos || forceUpdate) | |||
| if ((newPointerState != lastPointerState) || forceUpdate) | |||
| { | |||
| cancelPendingUpdate(); | |||
| if (newScreenPos != MouseInputSource::offscreenMousePos) | |||
| lastScreenPos = newScreenPos; | |||
| if (newPointerState.position != MouseInputSource::offscreenMousePos) | |||
| lastPointerState = newPointerState; | |||
| if (auto* current = getComponentUnderMouse()) | |||
| { | |||
| if (isDragging()) | |||
| { | |||
| registerMouseDrag (newScreenPos); | |||
| sendMouseDrag (*current, newScreenPos + unboundedMouseOffset, time); | |||
| sendMouseDrag (*current, newPointerState.withPositionOffset (unboundedMouseOffset), time); | |||
| if (isUnboundedMouseModeOn) | |||
| handleUnboundedDrag (*current); | |||
| } | |||
| else | |||
| { | |||
| sendMouseMove (*current, newScreenPos, time); | |||
| sendMouseMove (*current, newPointerState, time); | |||
| } | |||
| } | |||
| @@ -299,43 +303,31 @@ public: | |||
| const ModifierKeys newMods, float newPressure, float newOrientation, PenDetails pen) | |||
| { | |||
| lastTime = time; | |||
| const bool pressureChanged = (pressure != newPressure); | |||
| pressure = newPressure; | |||
| const bool orientationChanged = (orientation != newOrientation); | |||
| orientation = newOrientation; | |||
| const bool rotationChanged = (rotation != pen.rotation); | |||
| rotation = pen.rotation; | |||
| const bool tiltChanged = (tiltX != pen.tiltX || tiltY != pen.tiltY); | |||
| tiltX = pen.tiltX; | |||
| tiltY = pen.tiltY; | |||
| const bool shouldUpdate = (pressureChanged || orientationChanged || rotationChanged || tiltChanged); | |||
| ++mouseEventCounter; | |||
| auto screenPos = newPeer.localToGlobal (positionWithinPeer); | |||
| const auto pointerState = PointerState().withPosition (newPeer.localToGlobal (positionWithinPeer)) | |||
| .withPressure (newPressure) | |||
| .withOrientation (newOrientation) | |||
| .withRotation (MouseInputSource::defaultRotation) | |||
| .withTiltX (pen.tiltX) | |||
| .withTiltY (pen.tiltY); | |||
| if (isDragging() && newMods.isAnyMouseButtonDown()) | |||
| { | |||
| setScreenPos (screenPos, time, shouldUpdate); | |||
| setPointerState (pointerState, time, false); | |||
| } | |||
| else | |||
| { | |||
| setPeer (newPeer, screenPos, time); | |||
| setPeer (newPeer, pointerState, time); | |||
| if (auto* peer = getPeer()) | |||
| { | |||
| if (setButtons (screenPos, time, newMods)) | |||
| if (setButtons (pointerState, time, newMods)) | |||
| return; // some modal events have been dispatched, so the current event is now out-of-date | |||
| peer = getPeer(); | |||
| if (peer != nullptr) | |||
| setScreenPos (screenPos, time, shouldUpdate); | |||
| setPointerState (pointerState, time, false); | |||
| } | |||
| } | |||
| } | |||
| @@ -347,8 +339,9 @@ public: | |||
| ++mouseEventCounter; | |||
| screenPos = peer.localToGlobal (positionWithinPeer); | |||
| setPeer (peer, screenPos, time); | |||
| setScreenPos (screenPos, time, false); | |||
| const auto pointerState = lastPointerState.withPosition (screenPos); | |||
| setPeer (peer, pointerState, time); | |||
| setPointerState (pointerState, time, false); | |||
| triggerFakeMove(); | |||
| return getComponentUnderMouse(); | |||
| @@ -428,7 +421,7 @@ public: | |||
| void handleAsyncUpdate() override | |||
| { | |||
| setScreenPos (lastScreenPos, jmax (lastTime, Time::getCurrentTime()), true); | |||
| setPointerState (lastPointerState, jmax (lastTime, Time::getCurrentTime()), true); | |||
| } | |||
| //============================================================================== | |||
| @@ -444,7 +437,7 @@ public: | |||
| // when released, return the mouse to within the component's bounds | |||
| if (auto* current = getComponentUnderMouse()) | |||
| setScreenPosition (current->getScreenBounds().toFloat() | |||
| .getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastScreenPos))); | |||
| .getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastPointerState.position))); | |||
| } | |||
| isUnboundedMouseModeOn = enable; | |||
| @@ -458,17 +451,17 @@ public: | |||
| { | |||
| auto componentScreenBounds = ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat()); | |||
| if (! componentScreenBounds.contains (lastScreenPos)) | |||
| if (! componentScreenBounds.contains (lastPointerState.position)) | |||
| { | |||
| auto componentCentre = current.getScreenBounds().toFloat().getCentre(); | |||
| unboundedMouseOffset += (lastScreenPos - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre)); | |||
| unboundedMouseOffset += (lastPointerState.position - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre)); | |||
| setScreenPosition (componentCentre); | |||
| } | |||
| else if (isCursorVisibleUntilOffscreen | |||
| && (! unboundedMouseOffset.isOrigin()) | |||
| && componentScreenBounds.contains (lastScreenPos + unboundedMouseOffset)) | |||
| && componentScreenBounds.contains (lastPointerState.position + unboundedMouseOffset)) | |||
| { | |||
| MouseInputSource::setRawMousePosition (lastScreenPos + unboundedMouseOffset); | |||
| MouseInputSource::setRawMousePosition (lastPointerState.position + unboundedMouseOffset); | |||
| unboundedMouseOffset = {}; | |||
| } | |||
| } | |||
| @@ -507,13 +500,9 @@ public: | |||
| //============================================================================== | |||
| const int index; | |||
| const MouseInputSource::InputSourceType inputType; | |||
| Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords | |||
| Point<float> unboundedMouseOffset; // NB: these are unscaled coords | |||
| PointerState lastPointerState; | |||
| ModifierKeys buttonState; | |||
| float pressure = 0; | |||
| float orientation = 0; | |||
| float rotation = 0; | |||
| float tiltX = 0; | |||
| float tiltY = 0; | |||
| bool isUnboundedMouseModeOn = false, isCursorVisibleUntilOffscreen = false; | |||
| @@ -600,14 +589,14 @@ bool MouseInputSource::isDragging() const noexcept | |||
| Point<float> MouseInputSource::getScreenPosition() const noexcept { return pimpl->getScreenPosition(); } | |||
| Point<float> MouseInputSource::getRawScreenPosition() const noexcept { return pimpl->getRawScreenPosition(); } | |||
| ModifierKeys MouseInputSource::getCurrentModifiers() const noexcept { return pimpl->getCurrentModifiers(); } | |||
| float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->pressure; } | |||
| bool MouseInputSource::isPressureValid() const noexcept { return pimpl->isPressureValid(); } | |||
| float MouseInputSource::getCurrentOrientation() const noexcept { return pimpl->orientation; } | |||
| bool MouseInputSource::isOrientationValid() const noexcept { return pimpl->isOrientationValid(); } | |||
| float MouseInputSource::getCurrentRotation() const noexcept { return pimpl->rotation; } | |||
| bool MouseInputSource::isRotationValid() const noexcept { return pimpl->isRotationValid(); } | |||
| float MouseInputSource::getCurrentTilt (bool tiltX) const noexcept { return tiltX ? pimpl->tiltX : pimpl->tiltY; } | |||
| bool MouseInputSource::isTiltValid (bool isX) const noexcept { return pimpl->isTiltValid (isX); } | |||
| float MouseInputSource::getCurrentPressure() const noexcept { return pimpl->lastPointerState.pressure; } | |||
| bool MouseInputSource::isPressureValid() const noexcept { return pimpl->lastPointerState.isPressureValid(); } | |||
| float MouseInputSource::getCurrentOrientation() const noexcept { return pimpl->lastPointerState.orientation; } | |||
| bool MouseInputSource::isOrientationValid() const noexcept { return pimpl->lastPointerState.isOrientationValid(); } | |||
| float MouseInputSource::getCurrentRotation() const noexcept { return pimpl->lastPointerState.rotation; } | |||
| bool MouseInputSource::isRotationValid() const noexcept { return pimpl->lastPointerState.isRotationValid(); } | |||
| float MouseInputSource::getCurrentTilt (bool tiltX) const noexcept { return tiltX ? pimpl->lastPointerState.tiltX : pimpl->lastPointerState.tiltY; } | |||
| bool MouseInputSource::isTiltValid (bool isX) const noexcept { return pimpl->lastPointerState.isTiltValid (isX); } | |||
| Component* MouseInputSource::getComponentUnderMouse() const { return pimpl->getComponentUnderMouse(); } | |||
| void MouseInputSource::triggerFakeMove() const { pimpl->triggerFakeMove(); } | |||
| int MouseInputSource::getNumberOfMultipleClicks() const noexcept { return pimpl->getNumberOfMultipleClicks(); } | |||
| @@ -698,7 +687,7 @@ struct MouseInputSource::SourceList : public Timer | |||
| } | |||
| else if (type == MouseInputSource::InputSourceType::touch) | |||
| { | |||
| jassert (touchIndex >= 0 && touchIndex < 100); // sanity-check on number of fingers | |||
| jassert (0 <= touchIndex && touchIndex < 100); // sanity-check on number of fingers | |||
| for (auto& m : sourceArray) | |||
| if (type == m.getType() && touchIndex == m.getIndex()) | |||
| @@ -763,7 +752,7 @@ struct MouseInputSource::SourceList : public Timer | |||
| // because on some OSes the queue can get overloaded with messages so that mouse-events don't get through.. | |||
| if (s->isDragging() && ComponentPeer::getCurrentModifiersRealtime().isAnyMouseButtonDown()) | |||
| { | |||
| s->lastScreenPos = s->getRawScreenPosition(); | |||
| s->lastPointerState.position = s->getRawScreenPosition(); | |||
| s->triggerFakeMove(); | |||
| anyDragging = true; | |||
| } | |||
| @@ -224,16 +224,50 @@ public: | |||
| /** A default value for pressure, which is used when a device doesn't support it, or for | |||
| mouse-moves, mouse-ups, etc. | |||
| */ | |||
| static const float invalidPressure; | |||
| static constexpr float defaultPressure = 0.0f; | |||
| /** A default value for orientation, which is used when a device doesn't support it */ | |||
| static const float invalidOrientation; | |||
| static constexpr float defaultOrientation = 0.0f; | |||
| /** A default value for rotation, which is used when a device doesn't support it */ | |||
| static const float invalidRotation; | |||
| static constexpr float defaultRotation = 0.0f; | |||
| /** Default values for tilt, which are used when a device doesn't support it */ | |||
| static constexpr float defaultTiltX = 0.0f; | |||
| static constexpr float defaultTiltY = 0.0f; | |||
| /** A default value for pressure, which is used when a device doesn't support it. | |||
| This is a valid value, returning true when calling isPressureValid() hence the | |||
| deprecation. Use defaultPressure instead. | |||
| */ | |||
| [[deprecated ("Use defaultPressure instead.")]] | |||
| static const float invalidPressure; | |||
| /** A default value for orientation, which is used when a device doesn't support it. | |||
| This is a valid value, returning true when calling isOrientationValid() hence the | |||
| deprecation. Use defaultOrientation instead. | |||
| */ | |||
| [[deprecated ("Use defaultOrientation instead.")]] | |||
| static const float invalidOrientation; | |||
| /** A default value for rotation, which is used when a device doesn't support it. | |||
| This is a valid value, returning true when calling isRotationValid() hence the | |||
| deprecation. Use defaultRotation instead. | |||
| */ | |||
| [[deprecated ("Use defaultRotation instead.")]] | |||
| static const float invalidRotation; | |||
| /** Default values for tilt, which are used when a device doesn't support it | |||
| These are valid values, returning true when calling isTiltValid() hence the | |||
| deprecation. Use defaultTiltX and defaultTiltY instead. | |||
| */ | |||
| [[deprecated ("Use defaultTiltX instead.")]] | |||
| static const float invalidTiltX; | |||
| [[deprecated ("Use defaultTiltY instead.")]] | |||
| static const float invalidTiltY; | |||
| /** An offscreen mouse position used when triggering mouse exits where we don't want to move | |||
| @@ -0,0 +1,109 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2020 - Raw Material Software Limited | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 6 End-User License | |||
| Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). | |||
| End User License Agreement: www.juce.com/juce-6-licence | |||
| Privacy Policy: www.juce.com/juce-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #ifndef DOXYGEN | |||
| class PointerState | |||
| { | |||
| auto tie() const noexcept | |||
| { | |||
| return std::tie (position, pressure, orientation, rotation, tiltX, tiltY); | |||
| } | |||
| public: | |||
| PointerState() = default; | |||
| bool operator== (const PointerState& other) const noexcept { return tie() == other.tie(); } | |||
| bool operator!= (const PointerState& other) const noexcept { return tie() != other.tie(); } | |||
| JUCE_NODISCARD PointerState withPositionOffset (Point<float> x) const noexcept { return with (&PointerState::position, position + x); } | |||
| JUCE_NODISCARD PointerState withPosition (Point<float> x) const noexcept { return with (&PointerState::position, x); } | |||
| JUCE_NODISCARD PointerState withPressure (float x) const noexcept { return with (&PointerState::pressure, x); } | |||
| JUCE_NODISCARD PointerState withOrientation (float x) const noexcept { return with (&PointerState::orientation, x); } | |||
| JUCE_NODISCARD PointerState withRotation (float x) const noexcept { return with (&PointerState::rotation, x); } | |||
| JUCE_NODISCARD PointerState withTiltX (float x) const noexcept { return with (&PointerState::tiltX, x); } | |||
| JUCE_NODISCARD PointerState withTiltY (float x) const noexcept { return with (&PointerState::tiltY, x); } | |||
| Point<float> position; | |||
| float pressure = MouseInputSource::defaultPressure; | |||
| float orientation = MouseInputSource::defaultOrientation; | |||
| float rotation = MouseInputSource::defaultRotation; | |||
| float tiltX = MouseInputSource::defaultTiltX; | |||
| float tiltY = MouseInputSource::defaultTiltY; | |||
| bool isPressureValid() const noexcept { return 0.0f <= pressure && pressure <= 1.0f; } | |||
| bool isOrientationValid() const noexcept { return 0.0f <= orientation && orientation <= MathConstants<float>::twoPi; } | |||
| bool isRotationValid() const noexcept { return 0.0f <= rotation && rotation <= MathConstants<float>::twoPi; } | |||
| bool isTiltValid (bool isX) const noexcept | |||
| { | |||
| return isX ? (-1.0f <= tiltX && tiltX <= 1.0f) | |||
| : (-1.0f <= tiltY && tiltY <= 1.0f); | |||
| } | |||
| private: | |||
| template <typename Value> | |||
| PointerState with (Value PointerState::* member, Value item) const | |||
| { | |||
| auto copy = *this; | |||
| copy.*member = std::move (item); | |||
| return copy; | |||
| } | |||
| }; | |||
| inline auto makeMouseEvent (MouseInputSource source, | |||
| const PointerState& ps, | |||
| ModifierKeys modifiers, | |||
| Component* eventComponent, | |||
| Component* originator, | |||
| Time eventTime, | |||
| Point<float> mouseDownPos, | |||
| Time mouseDownTime, | |||
| int numberOfClicks, | |||
| bool mouseWasDragged) | |||
| { | |||
| return MouseEvent (source, | |||
| ps.position, | |||
| modifiers, | |||
| ps.pressure, | |||
| ps.orientation, | |||
| ps.rotation, | |||
| ps.tiltX, | |||
| ps.tiltY, | |||
| eventComponent, | |||
| originator, | |||
| eventTime, | |||
| mouseDownPos, | |||
| mouseDownTime, | |||
| numberOfClicks, | |||
| mouseWasDragged); | |||
| } | |||
| #endif | |||
| } // namespace juce | |||
| @@ -679,8 +679,8 @@ public: | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, | |||
| pos, | |||
| ModifierKeys::currentModifiers.withoutMouseButtons(), | |||
| MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, | |||
| MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, | |||
| time, | |||
| {}, | |||
| index); | |||
| @@ -702,8 +702,8 @@ public: | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, | |||
| pos, | |||
| ModifierKeys::currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier), | |||
| MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, | |||
| MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, | |||
| time, | |||
| {}, | |||
| index); | |||
| @@ -723,8 +723,8 @@ public: | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, | |||
| pos, | |||
| ModifierKeys::currentModifiers.withoutMouseButtons(), | |||
| MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, | |||
| MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, | |||
| time, | |||
| {}, | |||
| index); | |||
| @@ -958,7 +958,7 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, MouseEventFlags mouseEv | |||
| // 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(), | |||
| MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex); | |||
| MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, time, {}, touchIndex); | |||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||
| return; | |||
| @@ -983,10 +983,10 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, MouseEventFlags mouseEv | |||
| // NB: some devices return 0 or 1.0 if pressure is unknown, so we'll clip our value to a believable range: | |||
| auto pressure = maximumForce > 0 ? jlimit (0.0001f, 0.9999f, getTouchForce (touch) / maximumForce) | |||
| : MouseInputSource::invalidPressure; | |||
| : MouseInputSource::defaultPressure; | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, | |||
| pos, modsToSend, pressure, MouseInputSource::invalidOrientation, time, { }, touchIndex); | |||
| pos, modsToSend, pressure, MouseInputSource::defaultOrientation, time, { }, touchIndex); | |||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||
| return; | |||
| @@ -994,7 +994,7 @@ void UIViewComponentPeer::handleTouches (UIEvent* event, MouseEventFlags mouseEv | |||
| if (isUp (mouseEventFlags)) | |||
| { | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, MouseInputSource::offscreenMousePos, modsToSend, | |||
| MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, time, {}, touchIndex); | |||
| MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, time, {}, touchIndex); | |||
| if (! isValidPeer (this)) | |||
| return; | |||
| @@ -1011,7 +1011,7 @@ void UIViewComponentPeer::onHover (UIHoverGestureRecognizer* gesture) | |||
| handleMouseEvent (MouseInputSource::InputSourceType::touch, | |||
| pos, | |||
| ModifierKeys::currentModifiers, | |||
| MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, | |||
| MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, | |||
| UIViewComponentPeer::getMouseTime ([[NSProcessInfo processInfo] systemUptime]), | |||
| {}); | |||
| } | |||
| @@ -668,7 +668,7 @@ public: | |||
| else | |||
| // moved into another window which overlaps this one, so trigger an exit | |||
| handleMouseEvent (MouseInputSource::InputSourceType::mouse, MouseInputSource::offscreenMousePos, ModifierKeys::currentModifiers, | |||
| getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); | |||
| getMousePressure (ev), MouseInputSource::defaultOrientation, getMouseTime (ev)); | |||
| showArrowCursorIfNeeded(); | |||
| } | |||
| @@ -780,7 +780,7 @@ public: | |||
| { | |||
| updateModifiers (ev); | |||
| handleMouseEvent (MouseInputSource::InputSourceType::mouse, getMousePos (ev, view), ModifierKeys::currentModifiers, | |||
| getMousePressure (ev), MouseInputSource::invalidOrientation, getMouseTime (ev)); | |||
| getMousePressure (ev), MouseInputSource::defaultOrientation, getMouseTime (ev)); | |||
| } | |||
| bool handleKeyEvent (NSEvent* ev, bool isKeyDown) | |||
| @@ -2810,8 +2810,8 @@ private: | |||
| if (now >= lastMouseTime + minTimeBetweenMouses) | |||
| { | |||
| lastMouseTime = now; | |||
| doMouseEvent (position, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, modsToSend); | |||
| doMouseEvent (position, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, modsToSend); | |||
| } | |||
| } | |||
| @@ -2837,7 +2837,7 @@ private: | |||
| isDragging = true; | |||
| doMouseEvent (position, MouseInputSource::invalidPressure); | |||
| doMouseEvent (position, MouseInputSource::defaultPressure); | |||
| } | |||
| } | |||
| @@ -2864,7 +2864,7 @@ private: | |||
| // NB: under some circumstances (e.g. double-clicking a native title bar), a mouse-up can | |||
| // arrive without a mouse-down, so in that case we need to avoid sending a message. | |||
| if (wasDragging) | |||
| doMouseEvent (position, MouseInputSource::invalidPressure); | |||
| doMouseEvent (position, MouseInputSource::defaultPressure); | |||
| } | |||
| void doCaptureChanged() | |||
| @@ -2886,7 +2886,7 @@ private: | |||
| isMouseOver = false; | |||
| if (! areOtherTouchSourcesActive()) | |||
| doMouseEvent (getCurrentMousePos(), MouseInputSource::invalidPressure); | |||
| doMouseEvent (getCurrentMousePos(), MouseInputSource::defaultPressure); | |||
| } | |||
| ComponentPeer* findPeerUnderMouse (Point<float>& localPos) | |||
| @@ -3003,7 +3003,7 @@ private: | |||
| } | |||
| bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp, | |||
| const float touchPressure = MouseInputSource::invalidPressure, | |||
| const float touchPressure = MouseInputSource::defaultPressure, | |||
| const float orientation = 0.0f) | |||
| { | |||
| auto isCancel = false; | |||
| @@ -3080,9 +3080,9 @@ private: | |||
| return false; | |||
| const auto pressure = touchInfo.touchMask & TOUCH_MASK_PRESSURE ? static_cast<float> (touchInfo.pressure) | |||
| : MouseInputSource::invalidPressure; | |||
| : MouseInputSource::defaultPressure; | |||
| const auto orientation = touchInfo.touchMask & TOUCH_MASK_ORIENTATION ? degreesToRadians (static_cast<float> (touchInfo.orientation)) | |||
| : MouseInputSource::invalidOrientation; | |||
| : MouseInputSource::defaultOrientation; | |||
| if (! handleTouchInput (emulateTouchEventFromPointer (touchInfo.pointerInfo.ptPixelLocationRaw, wParam), | |||
| isDown, isUp, pressure, orientation)) | |||
| @@ -3095,7 +3095,7 @@ private: | |||
| if (! getPointerPenInfo (GET_POINTERID_WPARAM (wParam), &penInfo)) | |||
| return false; | |||
| const auto pressure = (penInfo.penMask & PEN_MASK_PRESSURE) ? (float) penInfo.pressure / 1024.0f : MouseInputSource::invalidPressure; | |||
| const auto pressure = (penInfo.penMask & PEN_MASK_PRESSURE) ? (float) penInfo.pressure / 1024.0f : MouseInputSource::defaultPressure; | |||
| if (! handlePenInput (penInfo, globalToLocal (convertPhysicalScreenPointToLogical (pointFromPOINT (getPOINTFromLParam (lParam)), hwnd).toFloat()), | |||
| pressure, isDown, isUp)) | |||
| @@ -3126,9 +3126,9 @@ private: | |||
| ModifierKeys modsToSend (ModifierKeys::currentModifiers); | |||
| PenDetails penDetails; | |||
| penDetails.rotation = (penInfo.penMask & PEN_MASK_ROTATION) ? degreesToRadians (static_cast<float> (penInfo.rotation)) : MouseInputSource::invalidRotation; | |||
| penDetails.tiltX = (penInfo.penMask & PEN_MASK_TILT_X) ? (float) penInfo.tiltX / 90.0f : MouseInputSource::invalidTiltX; | |||
| penDetails.tiltY = (penInfo.penMask & PEN_MASK_TILT_Y) ? (float) penInfo.tiltY / 90.0f : MouseInputSource::invalidTiltY; | |||
| penDetails.rotation = (penInfo.penMask & PEN_MASK_ROTATION) ? degreesToRadians (static_cast<float> (penInfo.rotation)) : MouseInputSource::defaultRotation; | |||
| penDetails.tiltX = (penInfo.penMask & PEN_MASK_TILT_X) ? (float) penInfo.tiltX / 90.0f : MouseInputSource::defaultTiltX; | |||
| penDetails.tiltY = (penInfo.penMask & PEN_MASK_TILT_Y) ? (float) penInfo.tiltY / 90.0f : MouseInputSource::defaultTiltY; | |||
| auto pInfoFlags = penInfo.pointerInfo.pointerFlags; | |||
| @@ -3143,7 +3143,7 @@ private: | |||
| // 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(), | |||
| pressure, MouseInputSource::invalidOrientation, time, penDetails); | |||
| pressure, MouseInputSource::defaultOrientation, time, penDetails); | |||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||
| return false; | |||
| @@ -3155,7 +3155,7 @@ private: | |||
| } | |||
| handleMouseEvent (MouseInputSource::InputSourceType::pen, pos, modsToSend, pressure, | |||
| MouseInputSource::invalidOrientation, time, penDetails); | |||
| MouseInputSource::defaultOrientation, time, penDetails); | |||
| if (! isValidPeer (this)) // (in case this component was deleted by the event) | |||
| return false; | |||
| @@ -3163,7 +3163,7 @@ private: | |||
| if (isUp) | |||
| { | |||
| handleMouseEvent (MouseInputSource::InputSourceType::pen, MouseInputSource::offscreenMousePos, ModifierKeys::currentModifiers, | |||
| pressure, MouseInputSource::invalidOrientation, time, penDetails); | |||
| pressure, MouseInputSource::defaultOrientation, time, penDetails); | |||
| if (! isValidPeer (this)) | |||
| return false; | |||
| @@ -3463,7 +3463,7 @@ private: | |||
| const ScopedValueSetter<bool> scope (inHandlePositionChanged, true); | |||
| if (! areOtherTouchSourcesActive()) | |||
| doMouseEvent (pos, MouseInputSource::invalidPressure); | |||
| doMouseEvent (pos, MouseInputSource::defaultPressure); | |||
| if (! isValidPeer (this)) | |||
| return true; | |||
| @@ -3472,8 +3472,8 @@ void XWindowSystem::handleButtonPressEvent (LinuxComponentPeer* peer, const XBut | |||
| ModifierKeys::currentModifiers = ModifierKeys::currentModifiers.withFlags (buttonModifierFlag); | |||
| peer->toFront (true); | |||
| peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (buttonPressEvent, peer->getPlatformScaleFactor()), | |||
| ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, getEventTime (buttonPressEvent), {}); | |||
| ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, getEventTime (buttonPressEvent), {}); | |||
| } | |||
| void XWindowSystem::handleButtonPressEvent (LinuxComponentPeer* peer, const XButtonPressedEvent& buttonPressEvent) const | |||
| @@ -3522,7 +3522,7 @@ void XWindowSystem::handleButtonReleaseEvent (LinuxComponentPeer* peer, const XB | |||
| dragState.handleExternalDragButtonReleaseEvent(); | |||
| peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (buttonRelEvent, peer->getPlatformScaleFactor()), | |||
| ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, getEventTime (buttonRelEvent)); | |||
| ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, getEventTime (buttonRelEvent)); | |||
| } | |||
| void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer* peer, const XPointerMovedEvent& movedEvent) const | |||
| @@ -3535,8 +3535,8 @@ void XWindowSystem::handleMotionNotifyEvent (LinuxComponentPeer* peer, const XPo | |||
| dragState.handleExternalDragMotionNotify(); | |||
| peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (movedEvent, peer->getPlatformScaleFactor()), | |||
| ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, getEventTime (movedEvent)); | |||
| ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, getEventTime (movedEvent)); | |||
| } | |||
| void XWindowSystem::handleEnterNotifyEvent (LinuxComponentPeer* peer, const XEnterWindowEvent& enterEvent) const | |||
| @@ -3548,8 +3548,8 @@ void XWindowSystem::handleEnterNotifyEvent (LinuxComponentPeer* peer, const XEnt | |||
| { | |||
| updateKeyModifiers ((int) enterEvent.state); | |||
| peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (enterEvent, peer->getPlatformScaleFactor()), | |||
| ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, getEventTime (enterEvent)); | |||
| ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, getEventTime (enterEvent)); | |||
| } | |||
| } | |||
| @@ -3563,8 +3563,8 @@ void XWindowSystem::handleLeaveNotifyEvent (LinuxComponentPeer* peer, const XLea | |||
| { | |||
| updateKeyModifiers ((int) leaveEvent.state); | |||
| peer->handleMouseEvent (MouseInputSource::InputSourceType::mouse, getLogicalMousePos (leaveEvent, peer->getPlatformScaleFactor()), | |||
| ModifierKeys::currentModifiers, MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, getEventTime (leaveEvent)); | |||
| ModifierKeys::currentModifiers, MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, getEventTime (leaveEvent)); | |||
| } | |||
| } | |||
| @@ -222,8 +222,8 @@ private: | |||
| auto topLeft = itemComp.getRepresentedItem().getItemPosition (false).toFloat().getTopLeft(); | |||
| return { Desktop::getInstance().getMainMouseSource(), topLeft, mods, | |||
| MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &itemComp, &itemComp, Time::getCurrentTime(), topLeft, Time::getCurrentTime(), 0, false }; | |||
| } | |||
| @@ -160,22 +160,22 @@ struct ButtonBasedStatusItem : public StatusItemContainer | |||
| eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier | |||
| : ModifierKeys::rightButtonModifier), | |||
| pressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false }); | |||
| owner.mouseUp ({ mouseSource, {}, | |||
| eventMods.withoutMouseButtons(), | |||
| pressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false }); | |||
| } | |||
| else if (type == NSEventTypeMouseMoved) | |||
| { | |||
| owner.mouseMove (MouseEvent (mouseSource, {}, eventMods, pressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false)); | |||
| } | |||
| } | |||
| @@ -289,20 +289,20 @@ struct ViewBasedStatusItem : public StatusItemContainer | |||
| owner.mouseDown (MouseEvent (mouseSource, {}, | |||
| eventMods.withFlags (isLeft ? ModifierKeys::leftButtonModifier | |||
| : ModifierKeys::rightButtonModifier), | |||
| pressure, MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| pressure, MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false)); | |||
| owner.mouseUp (MouseEvent (mouseSource, {}, eventMods.withoutMouseButtons(), pressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false)); | |||
| } | |||
| else if (type == NSEventTypeMouseMoved) | |||
| { | |||
| owner.mouseMove (MouseEvent (mouseSource, {}, eventMods, pressure, | |||
| MouseInputSource::invalidOrientation, MouseInputSource::invalidRotation, | |||
| MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultOrientation, MouseInputSource::defaultRotation, | |||
| MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, now, {}, now, 1, false)); | |||
| } | |||
| } | |||
| @@ -224,8 +224,8 @@ namespace ActiveXHelpers | |||
| { (float) (GET_X_LPARAM (lParam) + activeXRect.left - peerRect.left), | |||
| (float) (GET_Y_LPARAM (lParam) + activeXRect.top - peerRect.top) }, | |||
| ComponentPeer::getCurrentModifiersRealtime(), | |||
| MouseInputSource::invalidPressure, | |||
| MouseInputSource::invalidOrientation, | |||
| MouseInputSource::defaultPressure, | |||
| MouseInputSource::defaultOrientation, | |||
| getMouseEventTime()); | |||
| break; | |||
| } | |||
| @@ -115,8 +115,8 @@ public: | |||
| const Time eventTime (getMouseEventTime()); | |||
| const MouseEvent e (Desktop::getInstance().getMainMouseSource(), {}, eventMods, | |||
| MouseInputSource::invalidPressure, MouseInputSource::invalidOrientation, | |||
| MouseInputSource::invalidRotation, MouseInputSource::invalidTiltX, MouseInputSource::invalidTiltY, | |||
| MouseInputSource::defaultPressure, MouseInputSource::defaultOrientation, | |||
| MouseInputSource::defaultRotation, MouseInputSource::defaultTiltX, MouseInputSource::defaultTiltY, | |||
| &owner, &owner, eventTime, {}, eventTime, 1, false); | |||
| if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) | |||