/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

// This file is included from qnsview.mm, and only used to organize the code

/*
    The reason for using this helper is to ensure that QNSView doesn't implement
    the NSResponder callbacks for mouseEntered, mouseExited, and mouseMoved.

    If it did, we would get mouse events though the responder chain as well,
    for example if a subview has a tracking area of its own and calls super
    in the handler, which results in forwarding the event though the responder
    chain. The same applies if NSWindow.acceptsMouseMovedEvents is YES.

    By having a helper as the target for our tracking areas, we know for sure
    that the events we are getting stem from our own tracking areas.

    FIXME: Ideally we wouldn't need this workaround, and would correctly
    interact with the responder chain by e.g. calling super if Qt does not
    accept the mouse event
*/
@implementation QNSViewMouseMoveHelper {
    QNSView *view;
}

- (instancetype)initWithView:(QNSView *)theView
{
    if ((self = [super init]))
        view = theView;

    return self;
}

- (void)mouseMoved:(NSEvent *)theEvent
{
    [view mouseMovedImpl:theEvent];
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    [view mouseEnteredImpl:theEvent];
}

- (void)mouseExited:(NSEvent *)theEvent
{
    [view mouseExitedImpl:theEvent];
}

- (void)cursorUpdate:(NSEvent *)theEvent
{
    [view cursorUpdate:theEvent];
}

@end

@implementation QNSView (MouseAPI)

- (void)resetMouseButtons
{
    qCDebug(lcQpaMouse) << "Reseting mouse buttons";
    m_buttons = Qt::NoButton;
    m_frameStrutButtons = Qt::NoButton;
}

- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
{
    if (!m_platformWindow)
        return;

    // get m_buttons in sync
    // Don't send frme strut events if we are in the middle of a mouse drag.
    if (m_buttons != Qt::NoButton)
        return;

    switch (theEvent.type) {
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseDragged:
        m_frameStrutButtons |= Qt::LeftButton;
        break;
    case NSEventTypeLeftMouseUp:
         m_frameStrutButtons &= ~Qt::LeftButton;
         break;
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseDragged:
        m_frameStrutButtons |= Qt::RightButton;
        break;
    case NSEventTypeRightMouseUp:
        m_frameStrutButtons &= ~Qt::RightButton;
        break;
    case NSEventTypeOtherMouseDown:
        m_frameStrutButtons |= cocoaButton2QtButton(theEvent.buttonNumber);
        break;
    case NSEventTypeOtherMouseUp:
        m_frameStrutButtons &= ~cocoaButton2QtButton(theEvent.buttonNumber);
    default:
        break;
    }

    NSWindow *window = [self window];
    NSPoint windowPoint = [theEvent locationInWindow];

    int windowScreenY = [window frame].origin.y + [window frame].size.height;
    NSPoint windowCoord = [self convertPoint:[self frame].origin toView:nil];
    int viewScreenY = [window convertRectToScreen:NSMakeRect(windowCoord.x, windowCoord.y, 0, 0)].origin.y;
    int titleBarHeight = windowScreenY - viewScreenY;

    NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil];
    QPoint qtWindowPoint = QPoint(nsViewPoint.x, titleBarHeight + nsViewPoint.y);
    NSPoint screenPoint = [window convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 0, 0)].origin;
    QPoint qtScreenPoint = QCocoaScreen::mapFromNative(screenPoint).toPoint();

    ulong timestamp = [theEvent timestamp] * 1000;

    const auto button = cocoaButton2QtButton(theEvent);
    auto eventType = [&]() {
        switch (theEvent.type) {
        case NSEventTypeLeftMouseDown:
        case NSEventTypeRightMouseDown:
        case NSEventTypeOtherMouseDown:
            return QEvent::NonClientAreaMouseButtonPress;

        case NSEventTypeLeftMouseUp:
        case NSEventTypeRightMouseUp:
        case NSEventTypeOtherMouseUp:
            return QEvent::NonClientAreaMouseButtonRelease;

        case NSEventTypeLeftMouseDragged:
        case NSEventTypeRightMouseDragged:
        case NSEventTypeOtherMouseDragged:
            return QEvent::NonClientAreaMouseMove;

        default:
            break;
        }

        return QEvent::None;
    }();

    qCInfo(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << m_frameStrutButtons << "in" << self.window;
    QWindowSystemInterface::handleFrameStrutMouseEvent(m_platformWindow->window(),
        timestamp, qtWindowPoint, qtScreenPoint, m_frameStrutButtons, button, eventType);
}
@end

@implementation QNSView (Mouse)

- (void)initMouse
{
    m_buttons = Qt::NoButton;
    m_acceptedMouseDowns = Qt::NoButton;
    m_frameStrutButtons = Qt::NoButton;

    m_scrolling = false;
    self.cursor = nil;

    m_sendUpAsRightButton = false;
    m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, m_platformWindow->window(),
            "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB");

    m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];

    NSUInteger trackingOptions = NSTrackingActiveInActiveApp
        | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate;

    // Ideally, NSTrackingMouseMoved should be turned on only if QWidget::mouseTracking
    // is enabled, hover is on, or a tool tip is set. Unfortunately, Qt will send "tooltip"
    // events on mouse moves, so we need to turn it on in ALL case. That means EVERY QWindow
    // gets to pay the cost of mouse moves delivered to it (Apple recommends keeping it OFF
    // because there is a performance hit).
    trackingOptions |= NSTrackingMouseMoved;

    // Using NSTrackingInVisibleRect means AppKit will automatically synchronize the
    // tracking rect with changes in the view's visible area, so leave it undefined.
    trackingOptions |= NSTrackingInVisibleRect;
    static const NSRect trackingRect = NSZeroRect;

    QMacAutoReleasePool pool;
    [self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect
        options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]];
}

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
    Q_UNUSED(theEvent)
    if (!m_platformWindow)
        return NO;
    if ([self isTransparentForUserInput])
        return NO;
    QPointF windowPoint;
    QPointF screenPoint;
    [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint: &windowPoint andScreenPoint: &screenPoint];
    if (!qt_window_private(m_platformWindow->window())->allowClickThrough(screenPoint.toPoint()))
        return NO;
    return YES;
}

- (NSPoint)screenMousePoint:(NSEvent *)theEvent
{
    NSPoint screenPoint;
    if (theEvent) {
        NSPoint windowPoint = [theEvent locationInWindow];
        if (qIsNaN(windowPoint.x) || qIsNaN(windowPoint.y)) {
            screenPoint = [NSEvent mouseLocation];
        } else {
            NSRect screenRect = [[theEvent window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
            screenPoint = screenRect.origin;
        }
    } else {
        screenPoint = [NSEvent mouseLocation];
    }
    return screenPoint;
}

- (void)handleMouseEvent:(NSEvent *)theEvent
{
    if (!m_platformWindow)
        return;

#ifndef QT_NO_TABLETEVENT
    // Tablet events may come in via the mouse event handlers,
    // check if this is a valid tablet event first.
    if ([self handleTabletEvent: theEvent])
        return;
#endif

    QPointF qtWindowPoint;
    QPointF qtScreenPoint;
    QNSView *targetView = self;
    if (!targetView.platformWindow)
        return;

    // Popups implicitly grap mouse events; forward to the active popup if there is one
    if (QCocoaWindow *popup = QCocoaIntegration::instance()->activePopupWindow()) {
        // Tooltips must be transparent for mouse events
        // The bug reference is QTBUG-46379
        if (!popup->window()->flags().testFlag(Qt::ToolTip)) {
            if (QNSView *popupView = qnsview_cast(popup->view()))
                targetView = popupView;
        }
    }

    [targetView convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
    ulong timestamp = [theEvent timestamp] * 1000;

    QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
    nativeDrag->setLastMouseEvent(theEvent, self);

    const auto modifiers = [QNSView convertKeyModifiers:theEvent.modifierFlags];
    auto button = cocoaButton2QtButton(theEvent);
    if (button == Qt::LeftButton && m_sendUpAsRightButton)
        button = Qt::RightButton;
    const auto eventType = cocoaEvent2QtMouseEvent(theEvent);

    if (eventType == QEvent::MouseMove)
        qCDebug(lcQpaMouse) << eventType << "at" << qtWindowPoint << "with" << m_buttons;
    else
        qCInfo(lcQpaMouse) << eventType << "of" << button << "at" << qtWindowPoint << "with" << m_buttons;

    QWindowSystemInterface::handleMouseEvent(targetView->m_platformWindow->window(),
                                             timestamp, qtWindowPoint, qtScreenPoint,
                                             m_buttons, button, eventType, modifiers);
}

- (bool)handleMouseDownEvent:(NSEvent *)theEvent
{
    if ([self isTransparentForUserInput])
        return false;

    const auto button = cocoaButton2QtButton(theEvent);

    QPointF qtWindowPoint;
    QPointF qtScreenPoint;
    [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
    Q_UNUSED(qtScreenPoint);

    // Maintain masked state for the button for use by MouseDragged and MouseUp.
    QRegion mask = m_platformWindow->window()->mask();
    const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
    if (masked)
        m_acceptedMouseDowns &= ~button;
    else
        m_acceptedMouseDowns |= button;

    // Forward masked out events to the next responder
    if (masked)
        return false;

    m_buttons |= button;

    [self handleMouseEvent:theEvent];
    return true;
}

- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent
{
    if ([self isTransparentForUserInput])
        return false;

    const auto button = cocoaButton2QtButton(theEvent);

    // Forward the event to the next responder if Qt did not accept the
    // corresponding mouse down for this button
    if (!(m_acceptedMouseDowns & button) == button)
        return false;

    [self handleMouseEvent:theEvent];
    return true;
}

- (bool)handleMouseUpEvent:(NSEvent *)theEvent
{
    if ([self isTransparentForUserInput])
        return false;

    auto button = cocoaButton2QtButton(theEvent);

    // Forward the event to the next responder if Qt did not accept the
    // corresponding mouse down for this button
    if (!(m_acceptedMouseDowns & button) == button)
        return false;

    if (m_sendUpAsRightButton && button == Qt::LeftButton)
        button = Qt::RightButton;

    m_buttons &= ~button;

    [self handleMouseEvent:theEvent];

    if (button == Qt::RightButton)
        m_sendUpAsRightButton = false;

    return true;
}

- (void)mouseDown:(NSEvent *)theEvent
{
    if ([self isTransparentForUserInput])
        return [super mouseDown:theEvent];
    m_sendUpAsRightButton = false;

    // Handle any active poup windows; clicking outisde them should close them
    // all. Don't do anything or clicks inside one of the menus, let Cocoa
    // handle that case. Note that in practice many windows of the Qt::Popup type
    // will actually close themselves in this case using logic implemented in
    // that particular poup type (for example context menus). However, Qt expects
    // that plain popup QWindows will also be closed, so we implement the logic
    // here as well.
    QList<QCocoaWindow *> *popups = QCocoaIntegration::instance()->popupWindowStack();
    if (!popups->isEmpty()) {
        // Check if the click is outside all popups.
        bool inside = false;
        QPointF qtScreenPoint = QCocoaScreen::mapFromNative([self screenMousePoint:theEvent]);
        for (QList<QCocoaWindow *>::const_iterator it = popups->begin(); it != popups->end(); ++it) {
            if ((*it)->geometry().contains(qtScreenPoint.toPoint())) {
                inside = true;
                break;
            }
        }
        // Close the popups if the click was outside.
        if (!inside) {
            bool selfClosed = false;
            Qt::WindowType type = QCocoaIntegration::instance()->activePopupWindow()->window()->type();
            while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
                selfClosed = self == popup->view();
                QWindowSystemInterface::handleCloseEvent(popup->window());
                QWindowSystemInterface::flushWindowSystemEvents();
            }
            // Consume the mouse event when closing the popup, except for tool tips
            // were it's expected that the event is processed normally.
            if (type != Qt::ToolTip || selfClosed)
                 return;
        }
    }

    QPointF qtWindowPoint;
    QPointF qtScreenPoint;
    [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
    Q_UNUSED(qtScreenPoint);

    QRegion mask = m_platformWindow->window()->mask();
    const bool masked = !mask.isEmpty() && !mask.contains(qtWindowPoint.toPoint());
    // Maintain masked state for the button for use by MouseDragged and Up.
    if (masked)
        m_acceptedMouseDowns &= ~Qt::LeftButton;
    else
        m_acceptedMouseDowns |= Qt::LeftButton;

    // Forward masked out events to the next responder
    if (masked) {
        [super mouseDown:theEvent];
        return;
    }

    if ([self hasMarkedText]) {
        [[NSTextInputContext currentInputContext] handleEvent:theEvent];
    } else {
        auto ctrlOrMetaModifier = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ? Qt::ControlModifier : Qt::MetaModifier;
        if (!m_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & ctrlOrMetaModifier) {
            m_buttons |= Qt::RightButton;
            m_sendUpAsRightButton = true;
        } else {
            m_buttons |= Qt::LeftButton;
        }
        [self handleMouseEvent:theEvent];
    }
}

- (void)mouseDragged:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseDraggedEvent:theEvent];
    if (!accepted)
        [super mouseDragged:theEvent];
}

- (void)mouseUp:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseUpEvent:theEvent];
    if (!accepted)
        [super mouseUp:theEvent];
}

- (void)rightMouseDown:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseDownEvent:theEvent];
    if (!accepted)
        [super rightMouseDown:theEvent];
}

- (void)rightMouseDragged:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseDraggedEvent:theEvent];
    if (!accepted)
        [super rightMouseDragged:theEvent];
}

- (void)rightMouseUp:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseUpEvent:theEvent];
    if (!accepted)
        [super rightMouseUp:theEvent];
}

- (void)otherMouseDown:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseDownEvent:theEvent];
    if (!accepted)
        [super otherMouseDown:theEvent];
}

- (void)otherMouseDragged:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseDraggedEvent:theEvent];
    if (!accepted)
        [super otherMouseDragged:theEvent];
}

- (void)otherMouseUp:(NSEvent *)theEvent
{
    const bool accepted = [self handleMouseUpEvent:theEvent];
    if (!accepted)
        [super otherMouseUp:theEvent];
}

- (void)cursorUpdate:(NSEvent *)theEvent
{
    // Note: We do not get this callback when moving from a subview that
    // uses the legacy cursorRect API, so the cursor is reset to the arrow
    // cursor. See rdar://34183708

    auto previousCursor = NSCursor.currentCursor;

    if (self.cursor)
        [self.cursor set];
    else
        [super cursorUpdate:theEvent];

    if (NSCursor.currentCursor != previousCursor)
        qCInfo(lcQpaMouse) << "Cursor update for" << self << "resulted in new cursor" << NSCursor.currentCursor;
}

- (void)mouseMovedImpl:(NSEvent *)theEvent
{
    if (!m_platformWindow)
        return;

    if ([self isTransparentForUserInput])
        return;

    QPointF windowPoint;
    QPointF screenPoint;
    [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
    QWindow *childWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());

    // Top-level windows generate enter-leave events for sub-windows.
    // Qt wants to know which window (if any) will be entered at the
    // the time of the leave. This is dificult to accomplish by
    // handling mouseEnter and mouseLeave envents, since they are sent
    // individually to different views.
    if (m_platformWindow->isContentView() && childWindow) {
        if (childWindow != m_platformWindow->m_enterLeaveTargetWindow) {
            QWindowSystemInterface::handleEnterLeaveEvent(childWindow, m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
            m_platformWindow->m_enterLeaveTargetWindow = childWindow;
        }
    }

    // Cocoa keeps firing mouse move events for obscured parent views. Qt should not
    // send those events so filter them out here.
    if (childWindow != m_platformWindow->window())
        return;

    [self handleMouseEvent: theEvent];
}

- (void)mouseEnteredImpl:(NSEvent *)theEvent
{
    Q_UNUSED(theEvent)
    if (!m_platformWindow)
        return;

    m_platformWindow->m_windowUnderMouse = true;

    if ([self isTransparentForUserInput])
        return;

    // Top-level windows generate enter events for sub-windows.
    if (!m_platformWindow->isContentView())
        return;

    QPointF windowPoint;
    QPointF screenPoint;
    [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
    m_platformWindow->m_enterLeaveTargetWindow = m_platformWindow->childWindowAt(windowPoint.toPoint());

    qCInfo(lcQpaMouse) << QEvent::Enter << self << "at" << windowPoint << "with" << currentlyPressedMouseButtons();
    QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
}

- (void)mouseExitedImpl:(NSEvent *)theEvent
{
    Q_UNUSED(theEvent);
    if (!m_platformWindow)
        return;

    m_platformWindow->m_windowUnderMouse = false;

    if ([self isTransparentForUserInput])
        return;

    // Top-level windows generate leave events for sub-windows.
    if (!m_platformWindow->isContentView())
        return;

    qCInfo(lcQpaMouse) << QEvent::Leave << self;
    QWindowSystemInterface::handleLeaveEvent(m_platformWindow->m_enterLeaveTargetWindow);
    m_platformWindow->m_enterLeaveTargetWindow = 0;
}

#if QT_CONFIG(wheelevent)
- (void)scrollWheel:(NSEvent *)theEvent
{
    if (!m_platformWindow)
        return;

    if ([self isTransparentForUserInput])
        return [super scrollWheel:theEvent];

    QPoint angleDelta;
    Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
    if ([theEvent hasPreciseScrollingDeltas]) {
        // The mouse device contains pixel scroll wheel support (Mighty Mouse, Trackpad).
        // Since deviceDelta is delivered as pixels rather than degrees, we need to
        // convert from pixels to degrees in a sensible manner.
        // It looks like 1/4 degrees per pixel behaves most native.
        // (NB: Qt expects the unit for delta to be 8 per degree):
        const int pixelsToDegrees = 2; // 8 * 1/4
        angleDelta.setX([theEvent scrollingDeltaX] * pixelsToDegrees);
        angleDelta.setY([theEvent scrollingDeltaY] * pixelsToDegrees);
        source = Qt::MouseEventSynthesizedBySystem;
    } else {
        // Remove acceleration, and use either -120 or 120 as delta:
        angleDelta.setX(qBound(-120, int([theEvent deltaX] * 10000), 120));
        angleDelta.setY(qBound(-120, int([theEvent deltaY] * 10000), 120));
    }

    QPoint pixelDelta;
    if ([theEvent hasPreciseScrollingDeltas]) {
        pixelDelta.setX([theEvent scrollingDeltaX]);
        pixelDelta.setY([theEvent scrollingDeltaY]);
    } else {
        // docs: "In the case of !hasPreciseScrollingDeltas, multiply the delta with the line width."
        // scrollingDeltaX seems to return a minimum value of 0.1 in this case, map that to two pixels.
        const CGFloat lineWithEstimate = 20.0;
        pixelDelta.setX([theEvent scrollingDeltaX] * lineWithEstimate);
        pixelDelta.setY([theEvent scrollingDeltaY] * lineWithEstimate);
    }

    QPointF qt_windowPoint;
    QPointF qt_screenPoint;
    [self convertFromScreen:[self screenMousePoint:theEvent] toWindowPoint:&qt_windowPoint andScreenPoint:&qt_screenPoint];
    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:NSEventMaskScrollWheel 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
    // flick in order to avoid changing the interpretation of the events
    // 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.
    if (theEvent.momentumPhase == NSEventPhaseNone)
        m_currentWheelModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];

    // "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective.
    bool isInverted  = [theEvent isDirectionInvertedFromDevice];

    qCInfo(lcQpaMouse).nospace() << phase << " at " << qt_windowPoint
        << " pixelDelta=" << pixelDelta << " angleDelta=" << angleDelta
        << (isInverted ? " inverted=true" : "");

    QWindowSystemInterface::handleWheelEvent(m_platformWindow->window(), qt_timestamp, qt_windowPoint,
            qt_screenPoint, pixelDelta, angleDelta, m_currentWheelModifiers, phase, source, isInverted);
}
#endif // QT_CONFIG(wheelevent)

@end
