diff --git a/modules/juce_core/native/juce_win32_Threads.cpp b/modules/juce_core/native/juce_win32_Threads.cpp index 6320facd05..85df799375 100644 --- a/modules/juce_core/native/juce_win32_Threads.cpp +++ b/modules/juce_core/native/juce_win32_Threads.cpp @@ -210,17 +210,15 @@ static SleepEvent sleepEvent; void JUCE_CALLTYPE Thread::sleep (const int millisecs) { + jassert (millisecs >= 0); + if (millisecs >= 10 || sleepEvent.handle == 0) - { Sleep ((DWORD) millisecs); - } else - { // unlike Sleep() this is guaranteed to return to the current thread after // the time expires, so we'll use this for short waits, which are more likely // to need to be accurate WaitForSingleObject (sleepEvent.handle, (DWORD) millisecs); - } } void Thread::yield() @@ -231,7 +229,7 @@ void Thread::yield() //============================================================================== static int lastProcessPriority = -1; -// called by WindowDriver because Windows does weird things to process priority +// called when the app gains focus because Windows does weird things to process priority // when you swap apps, and this forces an update when the app is brought to the front. void juce_repeatLastProcessPriority() { diff --git a/modules/juce_core/threads/juce_ReadWriteLock.h b/modules/juce_core/threads/juce_ReadWriteLock.h index ab05099606..47bcf0e16b 100644 --- a/modules/juce_core/threads/juce_ReadWriteLock.h +++ b/modules/juce_core/threads/juce_ReadWriteLock.h @@ -59,18 +59,15 @@ public: ReadWriteLock() noexcept; /** Destructor. - - If the object is deleted whilst locked, any subsequent behaviour - is unpredictable. + If the object is deleted whilst locked, any subsequent behaviour is undefined. */ ~ReadWriteLock() noexcept; //============================================================================== /** Locks this object for reading. - Multiple threads can simulaneously lock the object for reading, but if another - thread has it locked for writing, then this will block until it releases the - lock. + Multiple threads can simultaneously lock the object for reading, but if another + thread has it locked for writing, then this will block until it releases the lock. @see exitRead, ScopedReadLock */ @@ -78,7 +75,7 @@ public: /** Tries to lock this object for reading. - Multiple threads can simulaneously lock the object for reading, but if another + Multiple threads can simultaneously lock the object for reading, but if another thread has it locked for writing, then this will fail and return false. @returns true if the lock is successfully gained. diff --git a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h index eb81aba129..123ffed203 100644 --- a/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h +++ b/modules/juce_gui_basics/keyboard/juce_ModifierKeys.h @@ -177,7 +177,7 @@ public: ModifierKeys withFlags (int rawFlagsToSet) const noexcept { return ModifierKeys (flags | rawFlagsToSet); } /** Tests a combination of flags and returns true if any of them are set. */ - bool testFlags (const int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } + bool testFlags (int flagsToTest) const noexcept { return (flags & flagsToTest) != 0; } /** Returns the total number of mouse buttons that are down. */ int getNumMouseButtonsDown() const noexcept; diff --git a/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp b/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp index 2cdb26e03e..3b85495cbd 100644 --- a/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp +++ b/modules/juce_gui_basics/mouse/juce_ComponentDragger.cpp @@ -49,7 +49,7 @@ void ComponentDragger::dragComponent (Component* const componentToDrag, const Mo // so their coordinates become wrong after the first one moves the window, so in that case, we'll use // the current mouse position instead of the one that the event contains... if (componentToDrag->isOnDesktop()) - bounds += componentToDrag->getMouseXYRelative() - mouseDownWithinTarget; + bounds += componentToDrag->getLocalPoint (nullptr, e.source.getScreenPosition()) - mouseDownWithinTarget; else bounds += e.getEventRelativeTo (componentToDrag).getPosition() - mouseDownWithinTarget; diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp index 07c5dfa6f8..5390a762f4 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp @@ -27,8 +27,9 @@ class MouseInputSourceInternal : private AsyncUpdater public: //============================================================================== MouseInputSourceInternal (const int i, const bool isMouse) - : index (i), isMouseDevice (isMouse), lastPeer (nullptr), - isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (nullptr), + : index (i), isMouseDevice (isMouse), + isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), + lastPeer (nullptr), currentCursorHandle (nullptr), mouseEventCounter (0), mouseMovedSignificantlySincePressed (false) { } @@ -463,12 +464,13 @@ public: Point lastScreenPos; ModifierKeys buttonState; + Point unboundedMouseOffset; + bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; + private: WeakReference componentUnderMouse; ComponentPeer* lastPeer; - Point unboundedMouseOffset; - bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; void* currentCursorHandle; int mouseEventCounter; @@ -550,6 +552,7 @@ bool MouseInputSource::hasMouseMovedSignificantlySincePressed() const noexcept bool MouseInputSource::canDoUnboundedMovement() const noexcept { return isMouse(); } void MouseInputSource::enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen) const { pimpl->enableUnboundedMouseMovement (isEnabled, keepCursorVisibleUntilOffscreen); } +bool MouseInputSource::isUnboundedMouseMovementEnabled() const { return pimpl->isUnboundedMouseModeOn; } bool MouseInputSource::hasMouseCursor() const noexcept { return isMouse(); } void MouseInputSource::showMouseCursor (const MouseCursor& cursor) { pimpl->showMouseCursor (cursor, false); } void MouseInputSource::hideCursor() { pimpl->hideCursor(); } diff --git a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h index 8185098990..c8ab0dffda 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseInputSource.h +++ b/modules/juce_gui_basics/mouse/juce_MouseInputSource.h @@ -158,6 +158,9 @@ public: */ void enableUnboundedMouseMovement (bool isEnabled, bool keepCursorVisibleUntilOffscreen = false) const; + /** Returns true if this source is currently in "unbounded" mode. */ + bool isUnboundedMouseMovementEnabled() const; + /** Attempts to set this mouse pointer's screen position. */ void setScreenPosition (Point newPosition); diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp index 3327e558e5..fd334e4eae 100644 --- a/modules/juce_gui_basics/widgets/juce_Slider.cpp +++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp @@ -818,13 +818,11 @@ public: valueWhenLastDragged = owner.proportionOfLengthToValue (jlimit (0.0, 1.0, currentPos + speed)); e.source.enableUnboundedMouseMovement (true, false); - mouseWasHidden = true; } } void mouseDown (const MouseEvent& e) { - mouseWasHidden = false; incDecDragged = false; useDragEvents = false; mouseDragStartPos = mousePosWhenLastDragged = e.getPosition(); @@ -880,9 +878,9 @@ public: void mouseDrag (const MouseEvent& e) { - if (useDragEvents - && maximum > minimum - && ! ((style == LinearBar || style == LinearBarVertical) && e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable())) + if (useDragEvents && maximum > minimum + && ! ((style == LinearBar || style == LinearBarVertical) + && e.mouseWasClicked() && valueBox != nullptr && valueBox->isEditable())) { if (style == Rotary) { @@ -899,10 +897,7 @@ public: mouseDragStartPos = e.getPosition(); } - if (isVelocityBased == (userKeyOverridesVelocity && e.mods.testFlags (ModifierKeys::ctrlModifier - | ModifierKeys::commandModifier - | ModifierKeys::altModifier)) - || (maximum - minimum) / sliderRegionSize < interval) + if (isAbsoluteDragMode (e.mods) || (maximum - minimum) / sliderRegionSize < interval) handleAbsoluteDrag (e); else handleVelocityDrag (e); @@ -1019,50 +1014,54 @@ public: void modifierKeysChanged (const ModifierKeys& modifiers) { - if (style != IncDecButtons - && style != Rotary - && isVelocityBased == modifiers.isAnyModifierKeyDown()) - { + if (style != IncDecButtons && style != Rotary && isAbsoluteDragMode (modifiers)) restoreMouseIfHidden(); - } + } + + bool isAbsoluteDragMode (ModifierKeys mods) const + { + return isVelocityBased == (userKeyOverridesVelocity + && mods.testFlags (ModifierKeys::ctrlAltCommandModifiers)); } void restoreMouseIfHidden() { - if (mouseWasHidden) + const Array& mouseSources = Desktop::getInstance().getMouseSources(); + + for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) { - mouseWasHidden = false; + if (mi->isUnboundedMouseMovementEnabled()) + { + mi->enableUnboundedMouseMovement (false); - const Array& mouseSources = Desktop::getInstance().getMouseSources(); + const double pos = sliderBeingDragged == 2 ? getMaxValue() + : (sliderBeingDragged == 1 ? getMinValue() + : (double) currentValue.getValue()); + Point mousePos; - for (MouseInputSource* mi = mouseSources.begin(), * const e = mouseSources.end(); mi != e; ++mi) - mi->enableUnboundedMouseMovement (false); + if (isRotary()) + { + mousePos = mi->getLastMouseDownPosition(); - const double pos = sliderBeingDragged == 2 ? getMaxValue() - : (sliderBeingDragged == 1 ? getMinValue() - : (double) currentValue.getValue()); - Point mousePos; + const int delta = roundToInt (pixelsForFullDragExtent * (owner.valueToProportionOfLength (valueOnMouseDown) + - owner.valueToProportionOfLength (pos))); - if (isRotary()) - { - mousePos = Desktop::getLastMouseDownPosition(); + if (style == RotaryHorizontalDrag) mousePos += Point (-delta, 0); + else if (style == RotaryVerticalDrag) mousePos += Point (0, delta); + else mousePos += Point (delta / -2, delta / 2); - const int delta = roundToInt (pixelsForFullDragExtent * (owner.valueToProportionOfLength (valueOnMouseDown) - - owner.valueToProportionOfLength (pos))); + mousePos = owner.getScreenBounds().getConstrainedPoint (mousePos); + } + else + { + const int pixelPos = (int) getLinearSliderPos (pos); - if (style == RotaryHorizontalDrag) mousePos += Point (-delta, 0); - else if (style == RotaryVerticalDrag) mousePos += Point (0, delta); - else mousePos += Point (delta / -2, delta / 2); - } - else - { - const int pixelPos = (int) getLinearSliderPos (pos); + mousePos = owner.localPointToGlobal (Point (isHorizontal() ? pixelPos : (owner.getWidth() / 2), + isVertical() ? pixelPos : (owner.getHeight() / 2))); + } - mousePos = owner.localPointToGlobal (Point (isHorizontal() ? pixelPos : (owner.getWidth() / 2), - isVertical() ? pixelPos : (owner.getHeight() / 2))); + mi->setScreenPosition (mousePos); } - - Desktop::setMousePosition (mousePos); } } @@ -1254,7 +1253,6 @@ public: bool popupDisplayEnabled; bool menuEnabled; bool useDragEvents; - bool mouseWasHidden; bool incDecDragged; bool scrollWheelEnabled; bool snapsToMousePos;