summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qnamespace.h3
-rw-r--r--src/gui/kernel/qevent.cpp10
-rw-r--r--src/gui/kernel/qevent.h5
-rw-r--r--src/plugins/platforms/cocoa/qnsview_mouse.mm64
4 files changed, 51 insertions, 31 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 288c966eec..dec2c44637 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1704,7 +1704,8 @@ public:
NoScrollPhase = 0,
ScrollBegin,
ScrollUpdate,
- ScrollEnd
+ ScrollEnd,
+ ScrollMomentum
};
enum MouseEventSource {
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 49f1ba3048..f5527354a2 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -783,7 +783,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
Qt::Orientation orient)
: QInputEvent(Wheel, modifiers), p(pos), qt4D(delta), qt4O(orient), mouseState(buttons),
- ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized), invertedScrolling(false)
+ src(Qt::MouseEventNotSynthesized), invertedScrolling(false), ph(Qt::NoScrollPhase)
{
g = QCursor::pos();
if (orient == Qt::Vertical)
@@ -818,7 +818,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
Qt::Orientation orient)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), qt4D(delta), qt4O(orient), mouseState(buttons),
- ph(Qt::NoScrollPhase), src(Qt::MouseEventNotSynthesized), invertedScrolling(false)
+ src(Qt::MouseEventNotSynthesized), invertedScrolling(false), ph(Qt::NoScrollPhase)
{
if (orient == Qt::Vertical)
angleD = QPoint(0, delta);
@@ -959,8 +959,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos,
QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source, bool inverted)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta),
- angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), ph(phase), src(source),
- invertedScrolling(inverted)
+ angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), src(source),
+ invertedScrolling(inverted), ph(phase)
{}
/*!
@@ -997,7 +997,7 @@ QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoi
bool inverted, Qt::MouseEventSource source)
: QInputEvent(Wheel, modifiers), p(pos), g(globalPos), pixelD(pixelDelta), angleD(angleDelta),
qt4O(qAbs(angleDelta.x()) > qAbs(angleDelta.y()) ? Qt::Horizontal : Qt::Vertical),
- mouseState(buttons), ph(phase), src(source), invertedScrolling(inverted)
+ mouseState(buttons), src(source), invertedScrolling(inverted), ph(phase)
{
qt4D = (qt4O == Qt::Horizontal ? angleDelta.x() : angleDelta.y());
}
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 8d2f225809..2b1c6a6e31 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -232,10 +232,11 @@ protected:
int qt4D = 0;
Qt::Orientation qt4O = Qt::Vertical;
Qt::MouseButtons mouseState;
- uint ph : 2;
+ uint _unused_ : 2; // Kept for binary compatibility
uint src: 2;
bool invertedScrolling : 1;
- int reserved : 27;
+ uint ph : 3;
+ int reserved : 24;
friend class QApplication;
};
diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm
index 1de256825a..65bc9f837d 100644
--- a/src/plugins/platforms/cocoa/qnsview_mouse.mm
+++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm
@@ -566,6 +566,42 @@
NSTimeInterval timestamp = [theEvent timestamp];
ulong qt_timestamp = timestamp * 1000;
+ Qt::ScrollPhase phase = Qt::NoScrollPhase;
+ if (theEvent.phase == NSEventPhaseMayBegin || theEvent.phase == NSEventPhaseBegan) {
+ // MayBegin is likely to happen. We treat it the same as an actual begin,
+ // and follow it with an update when the actual begin is delivered.
+ phase = m_scrolling ? Qt::ScrollUpdate : Qt::ScrollBegin;
+ m_scrolling = true;
+ } else if (theEvent.phase == NSEventPhaseStationary || theEvent.phase == NSEventPhaseChanged) {
+ phase = Qt::ScrollUpdate;
+ } else if (theEvent.phase == NSEventPhaseEnded) {
+ // A scroll event phase may be followed by a momentum phase after the user releases
+ // the finger, and in that case we don't want to send a Qt::ScrollEnd until after
+ // the momentum phase has ended. Unfortunately there isn't any guaranteed way of
+ // knowing whether or not a NSEventPhaseEnded will be followed by a momentum phase.
+ // The best we can do is to look at the event queue and hope that the system has
+ // had time to emit a momentum phase event.
+ if ([NSApp nextEventMatchingMask:NSScrollWheelMask untilDate:[NSDate distantPast]
+ inMode:@"QtMomementumEventSearchMode" dequeue:NO].momentumPhase == NSEventPhaseBegan) {
+ Q_ASSERT(pixelDelta.isNull() && angleDelta.isNull());
+ return; // Ignore this event, as it has a delta of 0,0
+ }
+ phase = Qt::ScrollEnd;
+ m_scrolling = false;
+ } else if (theEvent.momentumPhase == NSEventPhaseBegan) {
+ Q_ASSERT(!pixelDelta.isNull() && !angleDelta.isNull());
+ phase = Qt::ScrollUpdate; // Send as update, it has a delta
+ } else if (theEvent.momentumPhase == NSEventPhaseChanged) {
+ phase = Qt::ScrollMomentum;
+ } else if (theEvent.phase == NSEventPhaseCancelled
+ || theEvent.momentumPhase == NSEventPhaseEnded
+ || theEvent.momentumPhase == NSEventPhaseCancelled) {
+ phase = Qt::ScrollEnd;
+ m_scrolling = false;
+ } else {
+ Q_ASSERT(theEvent.momentumPhase != NSEventPhaseStationary);
+ }
+
// Prevent keyboard modifier state from changing during scroll event streams.
// A two-finger trackpad flick generates a stream of scroll events. We want
// the keyboard modifier state to be the state at the beginning of the
@@ -573,34 +609,16 @@
// mid-stream. One example of this happening would be when pressing cmd
// after scrolling in Qt Creator: not taking the phase into account causes
// the end of the event stream to be interpreted as font size changes.
- NSEventPhase momentumPhase = [theEvent momentumPhase];
- if (momentumPhase == NSEventPhaseNone)
+ if (theEvent.momentumPhase == NSEventPhaseNone)
m_currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- NSEventPhase phase = [theEvent phase];
- Qt::ScrollPhase ph = Qt::ScrollUpdate;
-
- // MayBegin is likely to happen. We treat it the same as an actual begin.
- if (phase == NSEventPhaseMayBegin) {
- m_scrolling = true;
- ph = Qt::ScrollBegin;
- } else if (phase == NSEventPhaseBegan) {
- // If MayBegin did not happen, Began is the actual beginning.
- if (!m_scrolling)
- ph = Qt::ScrollBegin;
- m_scrolling = true;
- } else if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled ||
- momentumPhase == NSEventPhaseEnded || momentumPhase == NSEventPhaseCancelled) {
- ph = Qt::ScrollEnd;
- m_scrolling = false;
- } else if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) {
- ph = Qt::NoScrollPhase;
- }
// "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
bool isInverted = [theEvent isDirectionInvertedFromDevice];
- qCDebug(lcQpaMouse) << "scroll wheel @ window pos" << qt_windowPoint << "delta px" << pixelDelta << "angle" << angleDelta << "phase" << ph << (isInverted ? "inverted" : "");
- QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint, qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, ph, source, isInverted);
+ qCDebug(lcQpaMouse) << "scroll wheel @ window pos" << qt_windowPoint << "delta px" << pixelDelta
+ << "angle" << angleDelta << "phase" << phase << (isInverted ? "inverted" : "");
+ QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
+ qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
}
#endif // QT_CONFIG(wheelevent)