diff options
author | Norwegian Rock Cat <qt-info@nokia.com> | 2009-05-20 09:25:32 (GMT) |
---|---|---|
committer | Norwegian Rock Cat <qt-info@nokia.com> | 2009-05-20 09:36:17 (GMT) |
commit | 4a8c7e432931b27e7a5440a6d15bde999e962f35 (patch) | |
tree | e5f0a37b68c6fa8a9b0c992f35d8f0c4c4e6ca61 | |
parent | d5348b5fc3a6efe13fd1dbe585b28addfa4344b3 (diff) | |
download | Qt-4a8c7e432931b27e7a5440a6d15bde999e962f35.zip Qt-4a8c7e432931b27e7a5440a6d15bde999e962f35.tar.gz Qt-4a8c7e432931b27e7a5440a6d15bde999e962f35.tar.bz2 |
Fix a crash where QCocoaWindow get events after its widget is dead
The invariant that QCocoaWindow's lifetime is contained in a QWidget is
simply not true.
A top-level QWidget gets associated with a QCocoaWindow (which is
reference counted). However, it can be the case that we've destroyed our
QWidget, the link is removed, the window is hidden, but the window still
gets an event. In that case we would crash with an eventual null pointer
access. However, we don't really need to do anything in this case, so
just call super and return.
Task-number: 253402
Reviewed-by: Morten Sørvig
-rw-r--r-- | src/gui/kernel/qcocoapanel_mac.mm | 11 | ||||
-rw-r--r-- | src/gui/kernel/qcocoawindow_mac.mm | 13 |
2 files changed, 19 insertions, 5 deletions
diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index c69826f..b2941fe 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -107,9 +107,16 @@ QT_USE_NAMESPACE - (void)sendEvent:(NSEvent *)event { - [self retain]; - QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + + // Cocoa can hold onto the window after we've disavowed its knowledge. So, + // if we get sent an event afterwards just have it go through the super's + // version and don't do any stuff with Qt. + if (!widget) { + [super sendEvent:event]; + return; + } + [self retain]; QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 89f481f..8e62f02 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -128,12 +128,19 @@ QT_USE_NAMESPACE - (void)sendEvent:(NSEvent *)event { - [self retain]; - QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + + // Cocoa can hold onto the window after we've disavowed its knowledge. So, + // if we get sent an event afterwards just have it go through the super's + // version and don't do any stuff with Qt. + if (!widget) { + [super sendEvent:event]; + return; + } + + [self retain]; QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); - // sometimes need to redirect mouse events to the popup. QWidget *popup = qAppInstance()->activePopupWidget(); if (popup && popup != widget) { |