From 4a8c7e432931b27e7a5440a6d15bde999e962f35 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 20 May 2009 11:25:32 +0200 Subject: Fix a crash where QCocoaWindow get events after its widget is dead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- src/gui/kernel/qcocoapanel_mac.mm | 11 +++++++++-- 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_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_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) { -- cgit v0.12