/****************************************************************************
**
** Copyright (C) 2016 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$
**
****************************************************************************/

/****************************************************************************
**
** Copyright (c) 2007-2008, Apple, Inc.
**
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
**   * Redistributions of source code must retain the above copyright notice,
**     this list of conditions and the following disclaimer.
**
**   * Redistributions in binary form must reproduce the above copyright notice,
**     this list of conditions and the following disclaimer in the documentation
**     and/or other materials provided with the distribution.
**
**   * Neither the name of Apple, Inc. nor the names of its contributors
**     may be used to endorse or promote products derived from this software
**     without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "qcocoaeventdispatcher.h"
#include "qcocoawindow.h"

#include "qcocoahelpers.h"
#include "qguiapplication.h"
#include "qevent.h"
#include "qmutex.h"
#include "qsocketnotifier.h"
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformnativeinterface.h>
#include "private/qthread_p.h"
#include "private/qguiapplication_p.h"
#include <qdebug.h>

#include <AppKit/AppKit.h>

QT_BEGIN_NAMESPACE

QT_USE_NAMESPACE

static inline CFRunLoopRef mainRunLoop()
{
    return CFRunLoopGetMain();
}

static Boolean runLoopSourceEqualCallback(const void *info1, const void *info2)
{
    return info1 == info2;
}

/*****************************************************************************
  Timers stuff
 *****************************************************************************/

/* timer call back */
void QCocoaEventDispatcherPrivate::runLoopTimerCallback(CFRunLoopTimerRef, void *info)
{
    QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
    if (d->processEventsCalled && (d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
        // processEvents() was called "manually," ignore this source for now
        d->maybeCancelWaitForMoreEvents();
        return;
    }
    CFRunLoopSourceSignal(d->activateTimersSourceRef);
}

void QCocoaEventDispatcherPrivate::activateTimersSourceCallback(void *info)
{
    QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
    d->processTimers();
    d->maybeCancelWaitForMoreEvents();
}

bool QCocoaEventDispatcherPrivate::processTimers()
{
    int activated = timerInfoList.activateTimers();
    maybeStartCFRunLoopTimer();
    return activated > 0;
}

void QCocoaEventDispatcherPrivate::maybeStartCFRunLoopTimer()
{
    if (timerInfoList.isEmpty()) {
        // no active timers, so the CFRunLoopTimerRef should not be active either
        Q_ASSERT(!runLoopTimerRef);
        return;
    }

    if (!runLoopTimerRef) {
        // start the CFRunLoopTimer
        CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent();
        CFTimeInterval interval;
        CFTimeInterval oneyear = CFTimeInterval(3600. * 24. * 365.);

        // Q: when should the CFRunLoopTimer fire for the first time?
        struct timespec tv;
        if (timerInfoList.timerWait(tv)) {
            // A: when we have timers to fire, of course
            interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001);
        } else {
            // this shouldn't really happen, but in case it does, set the timer to fire a some point in the distant future
            interval = oneyear;
        }

        ttf += interval;
        CFRunLoopTimerContext info = { 0, this, nullptr, nullptr, nullptr };
        // create the timer with a large interval, as recommended by the CFRunLoopTimerSetNextFireDate()
        // documentation, since we will adjust the timer's time-to-fire as needed to keep Qt timers working
        runLoopTimerRef = CFRunLoopTimerCreate(nullptr, ttf, oneyear, 0, 0, QCocoaEventDispatcherPrivate::runLoopTimerCallback, &info);
        Q_ASSERT(runLoopTimerRef);

        CFRunLoopAddTimer(mainRunLoop(), runLoopTimerRef, kCFRunLoopCommonModes);
    } else {
        // calculate when we need to wake up to process timers again
        CFAbsoluteTime ttf = CFAbsoluteTimeGetCurrent();
        CFTimeInterval interval;

        // Q: when should the timer first next?
        struct timespec tv;
        if (timerInfoList.timerWait(tv)) {
            // A: when we have timers to fire, of course
            interval = qMax(tv.tv_sec + tv.tv_nsec / 1000000000., 0.0000001);
        } else {
            // no timers can fire, but we cannot stop the CFRunLoopTimer, set the timer to fire at some
            // point in the distant future (the timer interval is one year)
            interval = CFRunLoopTimerGetInterval(runLoopTimerRef);
        }

        ttf += interval;
        CFRunLoopTimerSetNextFireDate(runLoopTimerRef, ttf);
    }
}

void QCocoaEventDispatcherPrivate::maybeStopCFRunLoopTimer()
{
    if (!runLoopTimerRef)
        return;

    CFRunLoopTimerInvalidate(runLoopTimerRef);
    CFRelease(runLoopTimerRef);
    runLoopTimerRef = nullptr;
}

void QCocoaEventDispatcher::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *obj)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1 || interval < 0 || !obj) {
        qWarning("QCocoaEventDispatcher::registerTimer: invalid arguments");
        return;
    } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::startTimer: timers cannot be started from another thread");
        return;
    }
#endif

    Q_D(QCocoaEventDispatcher);
    d->timerInfoList.registerTimer(timerId, interval, timerType, obj);
    d->maybeStartCFRunLoopTimer();
}

bool QCocoaEventDispatcher::unregisterTimer(int timerId)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1) {
        qWarning("QCocoaEventDispatcher::unregisterTimer: invalid argument");
        return false;
    } else if (thread() != QThread::currentThread()) {
        qWarning("QObject::killTimer: timers cannot be stopped from another thread");
        return false;
    }
#endif

    Q_D(QCocoaEventDispatcher);
    bool returnValue = d->timerInfoList.unregisterTimer(timerId);
    if (!d->timerInfoList.isEmpty())
        d->maybeStartCFRunLoopTimer();
    else
        d->maybeStopCFRunLoopTimer();
    return returnValue;
}

bool QCocoaEventDispatcher::unregisterTimers(QObject *obj)
{
#ifndef QT_NO_DEBUG
    if (!obj) {
        qWarning("QCocoaEventDispatcher::unregisterTimers: invalid argument");
        return false;
    } else if (obj->thread() != thread() || thread() != QThread::currentThread()) {
        qWarning("QObject::killTimers: timers cannot be stopped from another thread");
        return false;
    }
#endif

    Q_D(QCocoaEventDispatcher);
    bool returnValue = d->timerInfoList.unregisterTimers(obj);
    if (!d->timerInfoList.isEmpty())
        d->maybeStartCFRunLoopTimer();
    else
        d->maybeStopCFRunLoopTimer();
    return returnValue;
}

QList<QCocoaEventDispatcher::TimerInfo>
QCocoaEventDispatcher::registeredTimers(QObject *object) const
{
#ifndef QT_NO_DEBUG
    if (!object) {
        qWarning("QCocoaEventDispatcher:registeredTimers: invalid argument");
        return QList<TimerInfo>();
    }
#endif

    Q_D(const QCocoaEventDispatcher);
    return d->timerInfoList.registeredTimers(object);
}

/*
    Register a QSocketNotifier with the mac event system by creating a CFSocket with
    with a read/write callback.

    Qt has separate socket notifiers for reading and writing, but on the mac there is
    a limitation of one CFSocket object for each native socket.
*/
void QCocoaEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
{
    Q_D(QCocoaEventDispatcher);
    d->cfSocketNotifier.registerSocketNotifier(notifier);
}

void QCocoaEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
{
    Q_D(QCocoaEventDispatcher);
    d->cfSocketNotifier.unregisterSocketNotifier(notifier);
}

bool QCocoaEventDispatcher::hasPendingEvents()
{
    extern uint qGlobalPostedEventsCount();
    extern bool qt_is_gui_used; //qapplication.cpp
    return qGlobalPostedEventsCount() || (qt_is_gui_used && !CFRunLoopIsWaiting(CFRunLoopGetMain()));
}

static bool IsMouseOrKeyEvent( NSEvent* event )
{
    bool    result    = false;

    switch( [event type] )
    {
        case NSEventTypeLeftMouseDown:
        case NSEventTypeLeftMouseUp:
        case NSEventTypeRightMouseDown:
        case NSEventTypeRightMouseUp:
        case NSEventTypeMouseMoved:                // ??
        case NSEventTypeLeftMouseDragged:
        case NSEventTypeRightMouseDragged:
        case NSEventTypeMouseEntered:
        case NSEventTypeMouseExited:
        case NSEventTypeKeyDown:
        case NSEventTypeKeyUp:
        case NSEventTypeFlagsChanged:            // key modifiers changed?
        case NSEventTypeCursorUpdate:            // ??
        case NSEventTypeScrollWheel:
        case NSEventTypeTabletPoint:
        case NSEventTypeTabletProximity:
        case NSEventTypeOtherMouseDown:
        case NSEventTypeOtherMouseUp:
        case NSEventTypeOtherMouseDragged:
#ifndef QT_NO_GESTURES
        case NSEventTypeGesture: // touch events
        case NSEventTypeMagnify:
        case NSEventTypeSwipe:
        case NSEventTypeRotate:
        case NSEventTypeBeginGesture:
        case NSEventTypeEndGesture:
#endif // QT_NO_GESTURES
            result    = true;
        break;

        default:
        break;
    }
    return result;
}

static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode)
{
    // If no event exist in the cocoa event que, wait (and free up cpu time) until
    // at least one event occur. Setting 'dequeuing' to 'no' in the following call
    // causes it to hang under certain circumstances (QTBUG-28283), so we tell it
    // to dequeue instead, just to repost the event again:
    NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
        untilDate:[NSDate distantFuture]
        inMode:runLoopMode
        dequeue:YES];
    if (event)
        [NSApp postEvent:event atStart:YES];
}

bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QCocoaEventDispatcher);
    QBoolBlocker interruptBlocker(d->interrupt, false);

    bool interruptLater = false;
    QtCocoaInterruptDispatcher::cancelInterruptLater();

    emit awake();

    uint oldflags = d->processEventsFlags;
    d->processEventsFlags = flags;

    // Used to determine whether any eventloop has been exec'ed, and allow posted
    // and timer events to be processed even if this function has never been called
    // instead of being kept on hold for the next run of processEvents().
    ++d->processEventsCalled;

    bool excludeUserEvents = d->processEventsFlags & QEventLoop::ExcludeUserInputEvents;
    bool retVal = false;
    forever {
        if (d->interrupt)
            break;

        QMacAutoReleasePool pool;
        NSEvent* event = nil;

        // First, send all previously excluded input events, if any:
        if (d->sendQueuedUserInputEvents())
            retVal = true;


        // If Qt is used as a plugin, or as an extension in a native cocoa
        // application, we should not run or stop NSApplication; This will be
        // done from the application itself. And if processEvents is called
        // manually (rather than from a QEventLoop), we cannot enter a tight
        // loop and block this call, but instead we need to return after one flush.
        // Finally, if we are to exclude user input events, we cannot call [NSApp run]
        // as we then loose control over which events gets dispatched:
        const bool canExec_3rdParty = d->nsAppRunCalledByQt || ![NSApp isRunning];
        const bool canExec_Qt = (!excludeUserEvents
                                 && ((d->processEventsFlags & QEventLoop::DialogExec)
                                     || (d->processEventsFlags & QEventLoop::EventLoopExec)));

        if (canExec_Qt && canExec_3rdParty) {
            // We can use exec-mode, meaning that we can stay in a tight loop until
            // interrupted. This is mostly an optimization, but it allow us to use
            // [NSApp run], which is the normal code path for cocoa applications.
            if (NSModalSession session = d->currentModalSession()) {
                QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
                while ([NSApp runModalSession:session] == NSModalResponseContinue && !d->interrupt) {
                    qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
                    if (session != d->currentModalSessionCached) {
                        // It's possible to release the current modal session
                        // while we are in this loop, for example, by closing all
                        // windows from a slot via QApplication::closeAllWindows.
                        // In this case we cannot use 'session' anymore. A warning
                        // from Cocoa is: "Use of freed session detected. Do not
                        // call runModalSession: after calling endModalSesion:."
                        break;
                    }
                }

                if (!d->interrupt && session == d->currentModalSessionCached) {
                    // Someone called [NSApp stopModal:] from outside the event
                    // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
                    // 'session' as well. As a result, we need to restart all internal sessions:
                    d->temporarilyStopAllModalSessions();
                }

                // Clean up the modal session list, call endModalSession.
                if (d->cleanupModalSessionsNeeded)
                    d->cleanupModalSessions();

            } else {
                d->nsAppRunCalledByQt = true;
                QBoolBlocker execGuard(d->currentExecIsNSAppRun, true);
                [NSApp run];
            }
            retVal = true;
        } else {
            int lastSerialCopy = d->lastSerial;
            const bool hadModalSession = d->currentModalSessionCached;
            // We cannot block the thread (and run in a tight loop).
            // Instead we will process all current pending events and return.
            d->ensureNSAppInitialized();
            if (NSModalSession session = d->currentModalSession()) {
                // INVARIANT: a modal window is executing.
                if (!excludeUserEvents) {
                    // Since we can dispatch all kinds of events, we choose
                    // to use cocoa's native way of running modal sessions:
                    if (flags & QEventLoop::WaitForMoreEvents)
                        qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
                    NSInteger status = [NSApp runModalSession:session];
                    if (status != NSModalResponseContinue && session == d->currentModalSessionCached) {
                        // INVARIANT: Someone called [NSApp stopModal:] from outside the event
                        // dispatcher (e.g to stop a native dialog). But that call wrongly stopped
                        // 'session' as well. As a result, we need to restart all internal sessions:
                        d->temporarilyStopAllModalSessions();
                    }

                    // Clean up the modal session list, call endModalSession.
                    if (d->cleanupModalSessionsNeeded)
                        d->cleanupModalSessions();

                    retVal = true;
                } else do {
                    // Dispatch all non-user events (but que non-user events up for later). In
                    // this case, we need more control over which events gets dispatched, and
                    // cannot use [NSApp runModalSession:session]:
                    event = [NSApp nextEventMatchingMask:NSEventMaskAny
                    untilDate:nil
                    inMode:NSModalPanelRunLoopMode
                    dequeue: YES];

                    if (event) {
                        if (IsMouseOrKeyEvent(event)) {
                            [event retain];
                            d->queuedUserInputEvents.append(event);
                            continue;
                        }
                        if (!filterNativeEvent("NSEvent", event, nullptr)) {
                            [NSApp sendEvent:event];
                            retVal = true;
                        }
                    }
                } while (!d->interrupt && event);
            } else do {
                // INVARIANT: No modal window is executing.
                event = [NSApp nextEventMatchingMask:NSEventMaskAny
                untilDate:nil
                inMode:NSDefaultRunLoopMode
                dequeue: YES];

                if (event) {
                    if (flags & QEventLoop::ExcludeUserInputEvents) {
                        if (IsMouseOrKeyEvent(event)) {
                            [event retain];
                            d->queuedUserInputEvents.append(event);
                            continue;
                        }
                    }
                    if (!filterNativeEvent("NSEvent", event, nullptr)) {
                        [NSApp sendEvent:event];
                        retVal = true;
                    }
                }
            } while (!d->interrupt && event);

            if ((d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
                // When called "manually", always process posted events and timers
                d->processPostedEvents();
                retVal = d->processTimers() || retVal;
            }

            // be sure to return true if the posted event source fired
            retVal = retVal || lastSerialCopy != d->lastSerial;

            // Since the window that holds modality might have changed while processing
            // events, we we need to interrupt when we return back the previous process
            // event recursion to ensure that we spin the correct modal session.
            // We do the interruptLater at the end of the function to ensure that we don't
            // disturb the 'wait for more events' below (as deleteLater will post an event):
            if (hadModalSession && !d->currentModalSessionCached)
                interruptLater = true;
        }
        bool canWait = (d->threadData->canWait
                && !retVal
                && !d->interrupt
                && (d->processEventsFlags & QEventLoop::WaitForMoreEvents));
        if (canWait) {
            // INVARIANT: We haven't processed any events yet. And we're told
            // to stay inside this function until at least one event is processed.
            qt_mac_waitForMoreEvents();
            d->processEventsFlags &= ~QEventLoop::WaitForMoreEvents;
        } else {
            // Done with event processing for now.
            // Leave the function:
            break;
        }
    }

    d->processEventsFlags = oldflags;
    --d->processEventsCalled;

    // If we're interrupted, we need to interrupt the _current_
    // recursion as well to check if it is  still supposed to be
    // executing. This way we wind down the stack until we land
    // on a recursion that again calls processEvents (typically
    // from QEventLoop), and set interrupt to false:
    if (d->interrupt)
        interrupt();

    if (interruptLater)
        QtCocoaInterruptDispatcher::interruptLater();

    return retVal;
}

int QCocoaEventDispatcher::remainingTime(int timerId)
{
#ifndef QT_NO_DEBUG
    if (timerId < 1) {
        qWarning("QCocoaEventDispatcher::remainingTime: invalid argument");
        return -1;
    }
#endif

    Q_D(QCocoaEventDispatcher);
    return d->timerInfoList.timerRemainingTime(timerId);
}

void QCocoaEventDispatcher::wakeUp()
{
    Q_D(QCocoaEventDispatcher);
    d->serialNumber.ref();
    CFRunLoopSourceSignal(d->postedEventsSource);
    CFRunLoopWakeUp(mainRunLoop());
}

/*****************************************************************************
  QEventDispatcherMac Implementation
 *****************************************************************************/

void QCocoaEventDispatcherPrivate::ensureNSAppInitialized()
{
    // Some elements in Cocoa require NSApplication to be running before
    // they get fully initialized, in particular the menu bar. This
    // function is intended for cases where a dialog is told to execute before
    // QGuiApplication::exec is called, or the application spins the events loop
    // manually rather than calling QGuiApplication:exec.
    // The function makes sure that NSApplication starts running, but stops
    // it again as soon as the send posted events callback is called. That way
    // we let Cocoa finish the initialization it seems to need. We'll only
    // apply this trick at most once for any application, and we avoid doing it
    // for the common case where main just starts QGuiApplication::exec.
    if (nsAppRunCalledByQt || [NSApp isRunning])
        return;
    nsAppRunCalledByQt = true;
    QBoolBlocker block1(interrupt, true);
    QBoolBlocker block2(currentExecIsNSAppRun, true);
    [NSApp run];
}

void QCocoaEventDispatcherPrivate::temporarilyStopAllModalSessions()
{
    // Flush, and Stop, all created modal session, and as
    // such, make them pending again. The next call to
    // currentModalSession will recreate them again. The
    // reason to stop all session like this is that otherwise
    // a call [NSApp stop] would not stop NSApp, but rather
    // the current modal session. So if we need to stop NSApp
    // we need to stop all the modal session first. To avoid changing
    // the stacking order of the windows while doing so, we put
    // up a block that is used in QCocoaWindow and QCocoaPanel:
    int stackSize = cocoaModalSessionStack.size();
    for (int i=0; i<stackSize; ++i) {
        QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
        if (info.session) {
            [NSApp endModalSession:info.session];
            info.session = nullptr;
            [(NSWindow*) info.nswindow release];
        }
    }
    currentModalSessionCached = nullptr;
}

NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
{
    // If we have one or more modal windows, this function will create
    // a session for each of those, and return the one for the top.
    if (currentModalSessionCached)
        return currentModalSessionCached;

    if (cocoaModalSessionStack.isEmpty())
        return nullptr;

    int sessionCount = cocoaModalSessionStack.size();
    for (int i=0; i<sessionCount; ++i) {
        QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
        if (!info.window)
            continue;

        if (!info.session) {
            QMacAutoReleasePool pool;
            QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
            if (!cocoaWindow)
                continue;
            NSWindow *nswindow = cocoaWindow->nativeWindow();
            if (!nswindow)
                continue;

            ensureNSAppInitialized();
            QBoolBlocker block1(blockSendPostedEvents, true);
            info.nswindow = nswindow;
            [(NSWindow*) info.nswindow retain];
            QRect rect = cocoaWindow->geometry();
            info.session = [NSApp beginModalSessionForWindow:nswindow];

            // The call to beginModalSessionForWindow above processes events and may
            // have deleted or destroyed the window. Check if it's still valid.
            if (!info.window)
                continue;
            cocoaWindow = static_cast<QCocoaWindow *>(info.window->handle());
            if (!cocoaWindow)
                continue;

            if (rect != cocoaWindow->geometry())
                cocoaWindow->setGeometry(rect);
        }
        currentModalSessionCached = info.session;
        cleanupModalSessionsNeeded = false;
    }
    return currentModalSessionCached;
}

bool QCocoaEventDispatcherPrivate::hasModalSession() const
{
    return !cocoaModalSessionStack.isEmpty();
}

void QCocoaEventDispatcherPrivate::cleanupModalSessions()
{
    // Go through the list of modal sessions, and end those
    // that no longer has a window assosiated; no window means
    // the session has logically ended. The reason we wait like
    // this to actually end the sessions for real (rather than at the
    // point they were marked as stopped), is that ending a session
    // when no other session runs below it on the stack will make cocoa
    // drop some events on the floor.
    QMacAutoReleasePool pool;
    int stackSize = cocoaModalSessionStack.size();

    for (int i=stackSize-1; i>=0; --i) {
        QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
        if (info.window) {
            // This session has a window, and is therefore not marked
            // as stopped. So just make it current. There might still be other
            // stopped sessions on the stack, but those will be stopped on
            // a later "cleanup" call.
            currentModalSessionCached = info.session;
            break;
        }
        currentModalSessionCached = nullptr;
        if (info.session) {
            Q_ASSERT(info.nswindow);
            [NSApp endModalSession:info.session];
            [(NSWindow *)info.nswindow release];
        }
        // remove the info now that we are finished with it
        cocoaModalSessionStack.remove(i);
    }

    cleanupModalSessionsNeeded = false;
}

void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
{
    // We need to start spinning the modal session. Usually this is done with
    // QDialog::exec() for Qt Widgets based applications, but for others that
    // just call show(), we need to interrupt().
    Q_Q(QCocoaEventDispatcher);
    q->interrupt();

    // Add a new, empty (null), NSModalSession to the stack.
    // It will become active the next time QEventDispatcher::processEvents is called.
    // A QCocoaModalSessionInfo is considered pending to become active if the window pointer
    // is non-zero, and the session pointer is zero (it will become active upon a call to
    // currentModalSession). A QCocoaModalSessionInfo is considered pending to be stopped if
    // the window pointer is zero, and the session pointer is non-zero (it will be fully
    // stopped in cleanupModalSessions()).
    QCocoaModalSessionInfo info = {window, nullptr, nullptr};
    cocoaModalSessionStack.push(info);
    currentModalSessionCached = nullptr;
}

void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
{
    Q_Q(QCocoaEventDispatcher);

    // Mark all sessions attached to window as pending to be stopped. We do this
    // by setting the window pointer to zero, but leave the session pointer.
    // We don't tell cocoa to stop any sessions just yet, because cocoa only understands
    // when we stop the _current_ modal session (which is the session on top of
    // the stack, and might not belong to 'window').
    int stackSize = cocoaModalSessionStack.size();
    int endedSessions = 0;
    for (int i=stackSize-1; i>=0; --i) {
        QCocoaModalSessionInfo &info = cocoaModalSessionStack[i];
        if (!info.window)
            endedSessions++;
        if (info.window == window) {
            info.window = nullptr;
            if (i + endedSessions == stackSize-1) {
                // The top sessions ended. Interrupt the event dispatcher to
                // start spinning the correct session immediately.
                q->interrupt();
                currentModalSessionCached = nullptr;
                cleanupModalSessionsNeeded = true;
            }
        }
    }
}

QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
    : processEventsFlags(0),
      runLoopTimerRef(nullptr),
      blockSendPostedEvents(false),
      currentExecIsNSAppRun(false),
      nsAppRunCalledByQt(false),
      cleanupModalSessionsNeeded(false),
      processEventsCalled(0),
      currentModalSessionCached(nullptr),
      lastSerial(-1),
      interrupt(false)
{
}

void qt_mac_maybeCancelWaitForMoreEventsForwarder(QAbstractEventDispatcher *eventDispatcher)
{
    static_cast<QCocoaEventDispatcher *>(eventDispatcher)->d_func()->maybeCancelWaitForMoreEvents();
}

QCocoaEventDispatcher::QCocoaEventDispatcher(QObject *parent)
    : QAbstractEventDispatcher(*new QCocoaEventDispatcherPrivate, parent)
{
    Q_D(QCocoaEventDispatcher);

    d->cfSocketNotifier.setHostEventDispatcher(this);
    d->cfSocketNotifier.setMaybeCancelWaitForMoreEventsCallback(qt_mac_maybeCancelWaitForMoreEventsForwarder);

    // keep our sources running when modal loops are running
    CFRunLoopAddCommonMode(mainRunLoop(), (CFStringRef) NSModalPanelRunLoopMode);

    CFRunLoopSourceContext context;
    bzero(&context, sizeof(CFRunLoopSourceContext));
    context.info = d;
    context.equal = runLoopSourceEqualCallback;

    // source used to activate timers
    context.perform = QCocoaEventDispatcherPrivate::activateTimersSourceCallback;
    d->activateTimersSourceRef = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
    Q_ASSERT(d->activateTimersSourceRef);
    CFRunLoopAddSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes);

    // source used to send posted events
    context.perform = QCocoaEventDispatcherPrivate::postedEventsSourceCallback;
    d->postedEventsSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
    Q_ASSERT(d->postedEventsSource);
    CFRunLoopAddSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);

    // observer to emit aboutToBlock() and awake()
    CFRunLoopObserverContext observerContext;
    bzero(&observerContext, sizeof(CFRunLoopObserverContext));
    observerContext.info = this;
    d->waitingObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
                                                 kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting,
                                                 true, 0,
                                                 QCocoaEventDispatcherPrivate::waitingObserverCallback,
                                                 &observerContext);
    CFRunLoopAddObserver(mainRunLoop(), d->waitingObserver, kCFRunLoopCommonModes);

    /* The first cycle in the loop adds the source and the events of the source
       are not processed.
       We use an observer to process the posted events for the first
       execution of the loop. */
    CFRunLoopObserverContext firstTimeObserverContext;
    bzero(&firstTimeObserverContext, sizeof(CFRunLoopObserverContext));
    firstTimeObserverContext.info = d;
    d->firstTimeObserver = CFRunLoopObserverCreate(kCFAllocatorDefault,
                                                   kCFRunLoopEntry,
                                                   /* repeats = */ false,
                                                   0,
                                                   QCocoaEventDispatcherPrivate::firstLoopEntry,
                                                   &firstTimeObserverContext);
    CFRunLoopAddObserver(mainRunLoop(), d->firstTimeObserver, kCFRunLoopCommonModes);
}

void QCocoaEventDispatcherPrivate::waitingObserverCallback(CFRunLoopObserverRef,
                                                          CFRunLoopActivity activity, void *info)
{
    if (activity == kCFRunLoopBeforeWaiting)
        emit static_cast<QCocoaEventDispatcher*>(info)->aboutToBlock();
    else
        emit static_cast<QCocoaEventDispatcher*>(info)->awake();
}

bool QCocoaEventDispatcherPrivate::sendQueuedUserInputEvents()
{
    Q_Q(QCocoaEventDispatcher);
    if (processEventsFlags & QEventLoop::ExcludeUserInputEvents)
        return false;
    bool didSendEvent = false;
    while (!queuedUserInputEvents.isEmpty()) {
        NSEvent *event = static_cast<NSEvent *>(queuedUserInputEvents.takeFirst());
        if (!q->filterNativeEvent("NSEvent", event, nullptr)) {
            [NSApp sendEvent:event];
            didSendEvent = true;
        }
        [event release];
    }
    return didSendEvent;
}

void QCocoaEventDispatcherPrivate::processPostedEvents()
{
    if (blockSendPostedEvents) {
        // We're told to not send posted events (because the event dispatcher
        // is currently working on setting up the correct session to run). But
        // we still need to make sure that we don't fall asleep until pending events
        // are sendt, so we just signal this need, and return:
        CFRunLoopSourceSignal(postedEventsSource);
        return;
    }

    if (cleanupModalSessionsNeeded && currentExecIsNSAppRun)
        cleanupModalSessions();

    if (processEventsCalled > 0 && interrupt) {
        if (currentExecIsNSAppRun) {
            // The event dispatcher has been interrupted. But since
            // [NSApplication run] is running the event loop, we
            // delayed stopping it until now (to let cocoa process
            // pending cocoa events first).
            if (currentModalSessionCached)
                temporarilyStopAllModalSessions();
            [NSApp stop:NSApp];
            cancelWaitForMoreEvents();
        }
        return;
    }

    int serial = serialNumber.loadRelaxed();
    if (!threadData->canWait || (serial != lastSerial)) {
        lastSerial = serial;
        QCoreApplication::sendPostedEvents();
        QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::AllEvents);
    }
}

void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref,
                                                CFRunLoopActivity activity,
                                                void *info)
{
    Q_UNUSED(ref);
    Q_UNUSED(activity);
    static_cast<QCocoaEventDispatcherPrivate *>(info)->processPostedEvents();
}

void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info)
{
    QCocoaEventDispatcherPrivate *d = static_cast<QCocoaEventDispatcherPrivate *>(info);
    if (d->processEventsCalled && (d->processEventsFlags & QEventLoop::EventLoopExec) == 0) {
        // processEvents() was called "manually," ignore this source for now
        d->maybeCancelWaitForMoreEvents();
        return;
    }
    d->sendQueuedUserInputEvents();
    d->processPostedEvents();
    d->maybeCancelWaitForMoreEvents();
}

void QCocoaEventDispatcherPrivate::cancelWaitForMoreEvents()
{
    // In case the event dispatcher is waiting for more
    // events somewhere, we post a dummy event to wake it up:
    QMacAutoReleasePool pool;
    [NSApp postEvent:[NSEvent otherEventWithType:NSEventTypeApplicationDefined location:NSZeroPoint
        modifierFlags:0 timestamp:0. windowNumber:0 context:nil
        subtype:QtCocoaEventSubTypeWakeup data1:0 data2:0] atStart:NO];
}

void QCocoaEventDispatcherPrivate::maybeCancelWaitForMoreEvents()
{
    if ((processEventsFlags & (QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents)) == QEventLoop::WaitForMoreEvents) {
        // RunLoop sources are not NSEvents, but they do generate Qt events. If
        // WaitForMoreEvents was set, but EventLoopExec is not, processEvents()
        // should return after a source has sent some Qt events.
        cancelWaitForMoreEvents();
    }
}

void QCocoaEventDispatcher::interrupt()
{
    Q_D(QCocoaEventDispatcher);
    d->interrupt = true;
    wakeUp();

    // We do nothing more here than setting d->interrupt = true, and
    // poke the event loop if it is sleeping. Actually stopping
    // NSApp, or the current modal session, is done inside the send
    // posted events callback. We do this to ensure that all current pending
    // cocoa events gets delivered before we stop. Otherwise, if we now stop
    // the last event loop recursion, cocoa will just drop pending posted
    // events on the floor before we get a chance to reestablish a new session.
    d->cancelWaitForMoreEvents();
}

void QCocoaEventDispatcher::flush()
{ }

// QTBUG-56746: The behavior of processEvents() has been changed to not clear
// the interrupt flag. Use this function to clear it.
 void QCocoaEventDispatcher::clearCurrentThreadCocoaEventDispatcherInterruptFlag()
{
    QCocoaEventDispatcher *cocoaEventDispatcher =
            qobject_cast<QCocoaEventDispatcher *>(QThread::currentThread()->eventDispatcher());
    if (!cocoaEventDispatcher)
        return;
    QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate =
            static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
    cocoaEventDispatcherPrivate->interrupt = false;
}

QCocoaEventDispatcher::~QCocoaEventDispatcher()
{
    Q_D(QCocoaEventDispatcher);

    qDeleteAll(d->timerInfoList);
    d->maybeStopCFRunLoopTimer();
    CFRunLoopRemoveSource(mainRunLoop(), d->activateTimersSourceRef, kCFRunLoopCommonModes);
    CFRelease(d->activateTimersSourceRef);

    // end all modal sessions
    for (int i = 0; i < d->cocoaModalSessionStack.count(); ++i) {
        QCocoaModalSessionInfo &info = d->cocoaModalSessionStack[i];
        if (info.session) {
            [NSApp endModalSession:info.session];
            [(NSWindow *)info.nswindow release];
        }
    }

    // release all queued user input events
    for (int i = 0; i < d->queuedUserInputEvents.count(); ++i) {
        NSEvent *nsevent = static_cast<NSEvent *>(d->queuedUserInputEvents.at(i));
        [nsevent release];
    }

    d->cfSocketNotifier.removeSocketNotifiers();

    CFRunLoopRemoveSource(mainRunLoop(), d->postedEventsSource, kCFRunLoopCommonModes);
    CFRelease(d->postedEventsSource);

    CFRunLoopObserverInvalidate(d->waitingObserver);
    CFRelease(d->waitingObserver);

    CFRunLoopObserverInvalidate(d->firstTimeObserver);
    CFRelease(d->firstTimeObserver);
}

QtCocoaInterruptDispatcher* QtCocoaInterruptDispatcher::instance = nullptr;

QtCocoaInterruptDispatcher::QtCocoaInterruptDispatcher() : cancelled(false)
{
    // The whole point of this class is that we enable a way to interrupt
    // the event dispatcher when returning back to a lower recursion level
    // than where interruptLater was called. This is needed to detect if
    // [NSApp run] should still be running at the recursion level it is at.
    // Since the interrupt is canceled if processEvents is called before
    // this object gets deleted, we also avoid interrupting unnecessary.
    deleteLater();
}

QtCocoaInterruptDispatcher::~QtCocoaInterruptDispatcher()
{
    if (cancelled)
        return;
    instance = nullptr;
    QCocoaEventDispatcher::instance()->interrupt();
}

void QtCocoaInterruptDispatcher::cancelInterruptLater()
{
    if (!instance)
        return;
    instance->cancelled = true;
    delete instance;
    instance = nullptr;
}

void QtCocoaInterruptDispatcher::interruptLater()
{
    cancelInterruptLater();
    instance = new QtCocoaInterruptDispatcher;
}

QT_END_NAMESPACE

