Browse Source

Worked around a situation where mouse-drag auto-repeat can create a message-queue traffic jam on windows. Also tidied up inside MouseInputSource

tags/2021-05-28
jules 8 years ago
parent
commit
99c5843c3f
1 changed files with 54 additions and 61 deletions
  1. +54
    -61
      modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp

+ 54
- 61
modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp View File

@@ -27,11 +27,7 @@
class MouseInputSourceInternal : private AsyncUpdater class MouseInputSourceInternal : private AsyncUpdater
{ {
public: public:
//==============================================================================
MouseInputSourceInternal (const int i, const MouseInputSource::InputSourceType type)
: index (i), inputType (type), pressure (0.0f), orientation (0.0f), rotation (0.0f), tiltX (0.0f), tiltY (0.0f),
isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), lastPeer (nullptr),
currentCursorHandle (nullptr), mouseEventCounter (0), mouseMovedSignificantlySincePressed (false)
MouseInputSourceInternal (int i, MouseInputSource::InputSourceType type) : index (i), inputType (type)
{ {
} }
@@ -61,10 +57,10 @@ public:
static Point<float> screenPosToLocalPos (Component& comp, Point<float> pos) static Point<float> screenPosToLocalPos (Component& comp, Point<float> pos)
{ {
if (ComponentPeer* const peer = comp.getPeer())
if (auto* peer = comp.getPeer())
{ {
pos = peer->globalToLocal (pos); pos = peer->globalToLocal (pos);
Component& peerComp = peer->getComponent();
auto& peerComp = peer->getComponent();
return comp.getLocalPoint (&peerComp, ScalingHelpers::unscaledScreenPosToScaled (peerComp, pos)); return comp.getLocalPoint (&peerComp, ScalingHelpers::unscaledScreenPosToScaled (peerComp, pos));
} }
@@ -73,13 +69,12 @@ public:
Component* findComponentAt (Point<float> screenPos) Component* findComponentAt (Point<float> screenPos)
{ {
if (ComponentPeer* const peer = getPeer())
if (auto* peer = getPeer())
{ {
Point<float> relativePos (ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(),
peer->globalToLocal (screenPos)));
Component& comp = peer->getComponent();
const Point<int> pos (relativePos.roundToInt());
auto relativePos = ScalingHelpers::unscaledScreenPosToScaled (peer->getComponent(),
peer->globalToLocal (screenPos));
auto& comp = peer->getComponent();
auto pos = relativePos.roundToInt();
// (the contains() call is needed to test for overlapping desktop windows) // (the contains() call is needed to test for overlapping desktop windows)
if (comp.contains (pos)) if (comp.contains (pos))
@@ -110,8 +105,7 @@ public:
//============================================================================== //==============================================================================
#if JUCE_DUMP_MOUSE_EVENTS #if JUCE_DUMP_MOUSE_EVENTS
#define JUCE_MOUSE_EVENT_
(desc) DBG ("Mouse " << desc << " #" << index \
#define JUCE_MOUSE_EVENT_DBG(desc) DBG ("Mouse " << desc << " #" << index \
<< ": " << screenPosToLocalPos (comp, screenPos).toString() \ << ": " << screenPosToLocalPos (comp, screenPos).toString() \
<< " - Comp: " << String::toHexString ((pointer_sized_int) &comp)); << " - Comp: " << String::toHexString ((pointer_sized_int) &comp));
#else #else
@@ -184,13 +178,13 @@ public:
return false; return false;
} }
const int lastCounter = mouseEventCounter;
auto lastCounter = mouseEventCounter;
if (buttonState.isAnyMouseButtonDown()) if (buttonState.isAnyMouseButtonDown())
{ {
if (Component* const current = getComponentUnderMouse())
if (auto* current = getComponentUnderMouse())
{ {
const ModifierKeys oldMods (getCurrentModifiers());
auto oldMods = getCurrentModifiers();
buttonState = newButtonState; // must change this before calling sendMouseUp, in case it runs a modal loop buttonState = newButtonState; // must change this before calling sendMouseUp, in case it runs a modal loop
sendMouseUp (*current, screenPos + unboundedMouseOffset, time, oldMods); sendMouseUp (*current, screenPos + unboundedMouseOffset, time, oldMods);
@@ -208,7 +202,7 @@ public:
{ {
Desktop::getInstance().incrementMouseClickCounter(); Desktop::getInstance().incrementMouseClickCounter();
if (Component* const current = getComponentUnderMouse())
if (auto* current = getComponentUnderMouse())
{ {
registerMouseDown (screenPos, time, *current, buttonState); registerMouseDown (screenPos, time, *current, buttonState);
sendMouseDown (*current, screenPos, time); sendMouseDown (*current, screenPos, time);
@@ -220,12 +214,12 @@ public:
void setComponentUnderMouse (Component* const newComponent, Point<float> screenPos, Time time) void setComponentUnderMouse (Component* const newComponent, Point<float> screenPos, Time time)
{ {
Component* current = getComponentUnderMouse();
auto* current = getComponentUnderMouse();
if (newComponent != current) if (newComponent != current)
{ {
WeakReference<Component> safeNewComp (newComponent); WeakReference<Component> safeNewComp (newComponent);
const ModifierKeys originalButtonState (buttonState);
auto originalButtonState = buttonState;
if (current != nullptr) if (current != nullptr)
{ {
@@ -273,7 +267,7 @@ public:
cancelPendingUpdate(); cancelPendingUpdate();
lastScreenPos = newScreenPos; lastScreenPos = newScreenPos;
if (Component* const current = getComponentUnderMouse())
if (auto* current = getComponentUnderMouse())
{ {
if (isDragging()) if (isDragging())
{ {
@@ -316,7 +310,7 @@ public:
++mouseEventCounter; ++mouseEventCounter;
const Point<float> screenPos (newPeer.localToGlobal (positionWithinPeer));
auto screenPos = newPeer.localToGlobal (positionWithinPeer);
if (isDragging() && newMods.isAnyMouseButtonDown()) if (isDragging() && newMods.isAnyMouseButtonDown())
{ {
@@ -326,7 +320,7 @@ public:
{ {
setPeer (newPeer, screenPos, time); setPeer (newPeer, screenPos, time);
if (ComponentPeer* peer = getPeer())
if (auto* peer = getPeer())
{ {
if (setButtons (screenPos, time, newMods)) if (setButtons (screenPos, time, newMods))
return; // some modal events have been dispatched, so the current event is now out-of-date return; // some modal events have been dispatched, so the current event is now out-of-date
@@ -376,7 +370,8 @@ public:
Time time, const float scaleFactor) Time time, const float scaleFactor)
{ {
Point<float> screenPos; Point<float> screenPos;
if (Component* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos))
if (auto* current = getTargetForGesture (peer, positionWithinPeer, time, screenPos))
sendMagnifyGesture (*current, screenPos, time, scaleFactor); sendMagnifyGesture (*current, screenPos, time, scaleFactor);
} }
@@ -430,13 +425,13 @@ public:
if ((! enable) && ((! isCursorVisibleUntilOffscreen) || ! unboundedMouseOffset.isOrigin())) if ((! enable) && ((! isCursorVisibleUntilOffscreen) || ! unboundedMouseOffset.isOrigin()))
{ {
// when released, return the mouse to within the component's bounds // when released, return the mouse to within the component's bounds
if (Component* current = getComponentUnderMouse())
if (auto* current = getComponentUnderMouse())
setScreenPosition (current->getScreenBounds().toFloat() setScreenPosition (current->getScreenBounds().toFloat()
.getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastScreenPos))); .getConstrainedPoint (ScalingHelpers::unscaledScreenPosToScaled (lastScreenPos)));
} }
isUnboundedMouseModeOn = enable; isUnboundedMouseModeOn = enable;
unboundedMouseOffset = Point<float>();
unboundedMouseOffset = {};
revealCursor (true); revealCursor (true);
} }
@@ -444,12 +439,11 @@ public:
void handleUnboundedDrag (Component& current) void handleUnboundedDrag (Component& current)
{ {
const Rectangle<float> componentScreenBounds
= ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat());
auto componentScreenBounds = ScalingHelpers::scaledScreenPosToUnscaled (current.getParentMonitorArea().reduced (2, 2).toFloat());
if (! componentScreenBounds.contains (lastScreenPos)) if (! componentScreenBounds.contains (lastScreenPos))
{ {
const Point<float> componentCentre (current.getScreenBounds().toFloat().getCentre());
auto componentCentre = current.getScreenBounds().toFloat().getCentre();
unboundedMouseOffset += (lastScreenPos - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre)); unboundedMouseOffset += (lastScreenPos - ScalingHelpers::scaledScreenPosToUnscaled (componentCentre));
setScreenPosition (componentCentre); setScreenPosition (componentCentre);
} }
@@ -458,7 +452,7 @@ public:
&& componentScreenBounds.contains (lastScreenPos + unboundedMouseOffset)) && componentScreenBounds.contains (lastScreenPos + unboundedMouseOffset))
{ {
MouseInputSource::setRawMousePosition (lastScreenPos + unboundedMouseOffset); MouseInputSource::setRawMousePosition (lastScreenPos + unboundedMouseOffset);
unboundedMouseOffset = Point<float>();
unboundedMouseOffset = {};
} }
} }
@@ -487,7 +481,7 @@ public:
{ {
MouseCursor mc (MouseCursor::NormalCursor); MouseCursor mc (MouseCursor::NormalCursor);
if (Component* current = getComponentUnderMouse())
if (auto* current = getComponentUnderMouse())
mc = current->getLookAndFeel().getMouseCursorFor (*current); mc = current->getLookAndFeel().getMouseCursorFor (*current);
showMouseCursor (mc, forcedUpdate); showMouseCursor (mc, forcedUpdate);
@@ -498,31 +492,31 @@ public:
const MouseInputSource::InputSourceType inputType; const MouseInputSource::InputSourceType inputType;
Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords Point<float> lastScreenPos, unboundedMouseOffset; // NB: these are unscaled coords
ModifierKeys buttonState; ModifierKeys buttonState;
float pressure;
float orientation;
float rotation;
float tiltX;
float tiltY;
float pressure = 0;
float orientation = 0;
float rotation = 0;
float tiltX = 0;
float tiltY = 0;
bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen;
bool isUnboundedMouseModeOn = false, isCursorVisibleUntilOffscreen = false;
private: private:
WeakReference<Component> componentUnderMouse, lastNonInertialWheelTarget; WeakReference<Component> componentUnderMouse, lastNonInertialWheelTarget;
ComponentPeer* lastPeer;
ComponentPeer* lastPeer = nullptr;
void* currentCursorHandle;
int mouseEventCounter;
void* currentCursorHandle = nullptr;
int mouseEventCounter = 0;
struct RecentMouseDown struct RecentMouseDown
{ {
RecentMouseDown() noexcept : peerID (0) {}
RecentMouseDown() = default;
Point<float> position; Point<float> position;
Time time; Time time;
ModifierKeys buttons; ModifierKeys buttons;
uint32 peerID;
uint32 peerID = 0;
bool canBePartOfMultipleClickWith (const RecentMouseDown& other, const int maxTimeBetweenMs) const
bool canBePartOfMultipleClickWith (const RecentMouseDown& other, int maxTimeBetweenMs) const noexcept
{ {
return time - other.time < RelativeTime::milliseconds (maxTimeBetweenMs) return time - other.time < RelativeTime::milliseconds (maxTimeBetweenMs)
&& std::abs (position.x - other.position.x) < 8 && std::abs (position.x - other.position.x) < 8
@@ -534,7 +528,7 @@ private:
RecentMouseDown mouseDowns[4]; RecentMouseDown mouseDowns[4];
Time lastTime; Time lastTime;
bool mouseMovedSignificantlySincePressed;
bool mouseMovedSignificantlySincePressed = false;
void registerMouseDown (Point<float> screenPos, Time time, void registerMouseDown (Point<float> screenPos, Time time,
Component& component, const ModifierKeys modifiers) noexcept Component& component, const ModifierKeys modifiers) noexcept
@@ -546,7 +540,7 @@ private:
mouseDowns[0].time = time; mouseDowns[0].time = time;
mouseDowns[0].buttons = modifiers.withOnlyMouseButtons(); mouseDowns[0].buttons = modifiers.withOnlyMouseButtons();
if (ComponentPeer* const peer = component.getPeer())
if (auto* peer = component.getPeer())
mouseDowns[0].peerID = peer->getUniqueID(); mouseDowns[0].peerID = peer->getUniqueID();
else else
mouseDowns[0].peerID = 0; mouseDowns[0].peerID = 0;
@@ -688,8 +682,8 @@ struct MouseInputSource::SourceList : public Timer
{ {
int num = 0; int num = 0;
for (int i = 0; i < sources.size(); ++i)
if (sources.getUnchecked(i)->isDragging())
for (auto* s : sources)
if (s->isDragging())
++num; ++num;
return num; return num;
@@ -699,14 +693,12 @@ struct MouseInputSource::SourceList : public Timer
{ {
int num = 0; int num = 0;
for (int i = 0; i < sources.size(); ++i)
for (auto& s : sourceArray)
{ {
MouseInputSource* const mi = &(sourceArray.getReference(i));
if (mi->isDragging())
if (s.isDragging())
{ {
if (index == num) if (index == num)
return mi;
return &s;
++num; ++num;
} }
@@ -730,20 +722,21 @@ struct MouseInputSource::SourceList : public Timer
void timerCallback() override void timerCallback() override
{ {
int numMiceDown = 0;
bool anyDragging = false;
for (int i = 0; i < sources.size(); ++i)
for (auto* s : sources)
{ {
MouseInputSourceInternal* const mi = sources.getUnchecked(i);
if (mi->isDragging())
// 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())
{ {
mi->triggerFakeMove();
++numMiceDown;
s->lastScreenPos = s->getScreenPosition();
s->triggerFakeMove();
anyDragging = true;
} }
} }
if (numMiceDown == 0)
if (! anyDragging)
stopTimer(); stopTimer();
} }


Loading…
Cancel
Save