diff options
author | Dyami Caliri <dyami@dragonframe.com> | 2014-05-22 15:19:46 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-06-03 17:25:36 +0200 |
commit | ac7bf97f51837eecc5e5570d5d62996746f378ed (patch) | |
tree | 3284c7d949df84469e15fb2567b02e09455e9fa9 /src/plugins | |
parent | 70e4428b6f1c6a4bad112203f67ee7d22107616c (diff) |
Cocoa: clear queued user input events when window is destroyed
QCocoaEventDispatcher stores user input events in a queue in certain
cases. If the target of those events is destroyed, the events are later
sent to the stale window, causing a crash.
Task-number: QTBUG-39211
Change-Id: Ie55d2df5697c742bcb644ebf8c5028015a0b8148
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 15 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 10 |
3 files changed, 26 insertions, 1 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 33d7dcbcf4..dc0b8fcc18 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -178,6 +178,8 @@ public: void maybeCancelWaitForMoreEvents(); void ensureNSAppInitialized(); + void removeQueuedUserInputEvents(int nsWinNumber); + QCFSocketNotifier cfSocketNotifier; QList<void *> queuedUserInputEvents; // NSEvent * CFRunLoopSourceRef postedEventsSource; diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index 45c0714b6b..e7f8992c6d 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -892,6 +892,21 @@ void QCocoaEventDispatcherPrivate::processPostedEvents() } } +void QCocoaEventDispatcherPrivate::removeQueuedUserInputEvents(int nsWinNumber) +{ + if (nsWinNumber) { + int eventIndex = queuedUserInputEvents.size(); + + while (--eventIndex >= 0) { + NSEvent * nsevent = static_cast<NSEvent *>(queuedUserInputEvents.at(eventIndex)); + if ([nsevent windowNumber] == nsWinNumber) { + queuedUserInputEvents.removeAt(eventIndex); + [nsevent release]; + } + } + } +} + void QCocoaEventDispatcherPrivate::firstLoopEntry(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 7ab7486ce9..c8ca494b33 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -189,7 +189,15 @@ static bool isMouseEvent(NSEvent *ev) - (void)clearWindow { - _window = nil; + if (_window) { + QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); + if (cocoaEventDispatcher) { + QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); + cocoaEventDispatcherPrivate->removeQueuedUserInputEvents([_window windowNumber]); + } + + _window = nil; + } } - (void)dealloc |