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>
This commit is contained in:
Dyami Caliri 2014-05-22 15:19:46 -07:00 committed by The Qt Project
parent 70e4428b6f
commit ac7bf97f51
3 changed files with 26 additions and 1 deletions

View File

@ -178,6 +178,8 @@ public:
void maybeCancelWaitForMoreEvents();
void ensureNSAppInitialized();
void removeQueuedUserInputEvents(int nsWinNumber);
QCFSocketNotifier cfSocketNotifier;
QList<void *> queuedUserInputEvents; // NSEvent *
CFRunLoopSourceRef postedEventsSource;

View File

@ -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)

View File

@ -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