Fix crash in tst_qfiledialog on OS X

The test aggressively shows and hides dialogs and popups, and we would end up
installing this global event monitor frequently. However we never cleaned up
properly, for example if the window didn't get hidden properly or if the
monitor was already installed for some reason.

Change-Id: I6fa28eaeb03e089ced735912dbe29b0b8ad75d58
Reviewed-by: Andy Shaw <andy.shaw@theqtcompany.com>
This commit is contained in:
Simon Hausmann 2015-06-03 15:55:39 +02:00
parent 80bc743406
commit bf0bdc5fbb
2 changed files with 14 additions and 4 deletions

View File

@ -245,6 +245,8 @@ public: // for QNSView
friend class QCocoaBackingStore;
friend class QCocoaNativeInterface;
void removeMonitor();
NSView *m_contentView;
QNSView *m_qtView;
QCocoaNSWindow *m_nsWindow;

View File

@ -419,6 +419,8 @@ QCocoaWindow::~QCocoaWindow()
[m_contentView removeFromSuperview];
}
removeMonitor();
// Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
if (m_qtView) {
@ -696,6 +698,7 @@ void QCocoaWindow::setVisible(bool visible)
&& [m_nsWindow isKindOfClass:[NSPanel class]]) {
[(NSPanel *)m_nsWindow setWorksWhenModal:YES];
if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) {
removeMonitor();
monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDownMask|NSRightMouseDownMask|NSOtherMouseDownMask|NSMouseMovedMask handler:^(NSEvent *e) {
QPointF localPoint = qt_mac_flipPoint([NSEvent mouseLocation]);
QWindowSystemInterface::handleMouseEvent(window(), window()->mapFromGlobal(localPoint.toPoint()), localPoint,
@ -744,10 +747,7 @@ void QCocoaWindow::setVisible(bool visible)
} else {
[m_contentView setHidden:YES];
}
if (monitor && window()->type() == Qt::Popup) {
[NSEvent removeMonitor:monitor];
monitor = nil;
}
removeMonitor();
if (window()->type() == Qt::Popup)
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
@ -1480,6 +1480,14 @@ void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
[m_nsWindow removeChildWindow:child->m_nsWindow];
}
void QCocoaWindow::removeMonitor()
{
if (!monitor)
return;
[NSEvent removeMonitor:monitor];
monitor = nil;
}
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::windowGeometry() const
{