From 5b54c352edbc597ec5283bc9cfdd77906350161f Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 21 Apr 2016 10:02:17 +0200 Subject: [PATCH] Cocoa integration - add a protection against dangling pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport watcher-sentinel trick (QPointer->QObject) from dev. Task-number: QTBUG-42059 Change-Id: I9b2c7cde635c2ed9a3f667f216da62870d0b5ccb Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.h | 6 ++++++ src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 05e6cf3c9e..e60ca196ac 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -66,6 +66,7 @@ typedef NSWindow QCocoaNSWindow; QCocoaWindow *_platformWindow; BOOL _grabbingMouse; BOOL _releaseOnMouseUp; + QPointer _watcher; } @property (nonatomic, readonly) QCocoaNSWindow *window; @@ -315,6 +316,11 @@ public: // for QNSView }; QHash m_contentBorderAreas; // identifer -> uppper/lower QHash m_enabledContentBorderAreas; // identifer -> enabled state (true/false) + + // This object is tracked by a 'watcher' + // object in a window helper, preventing use of dangling + // pointers. + QObject sentinel; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e4cd57a115..12e85c5205 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -94,6 +94,7 @@ static bool isMouseEvent(NSEvent *ev) // make sure that m_nsWindow stays valid until the // QCocoaWindow is deleted by Qt. [_window setReleasedWhenClosed:NO]; + _watcher = &_platformWindow->sentinel; } return self; @@ -102,7 +103,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)handleWindowEvent:(NSEvent *)theEvent { QCocoaWindow *pw = self.platformWindow; - if (pw && pw->m_forwardWindow) { + if (_watcher && pw && pw->m_forwardWindow) { if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) { QNSView *forwardView = pw->m_qtView; if (theEvent.type == NSLeftMouseUp) { @@ -141,7 +142,7 @@ static bool isMouseEvent(NSEvent *ev) if (!self.window.delegate) return; // Already detached, pending NSAppKitDefined event - if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + if (_watcher && pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { NSPoint loc = [theEvent locationInWindow]; NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]]; NSRect contentFrame = [[self.window contentView] frame]; @@ -157,6 +158,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)detachFromPlatformWindow { _platformWindow = 0; + _watcher.clear(); [self.window.delegate release]; self.window.delegate = nil; }