summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorDyami Caliri <dyami@dragonframe.com>2014-05-22 15:19:46 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-06-03 17:25:36 +0200
commitac7bf97f51837eecc5e5570d5d62996746f378ed (patch)
tree3284c7d949df84469e15fb2567b02e09455e9fa9 /src/plugins
parent70e4428b6f1c6a4bad112203f67ee7d22107616c (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.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm10
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