Cocoa integration - avoid using dangling pointers
While re-parenting a widget on a mouse down, it's possible that NSWindow lives longer than QCocoaWindow (because self.grabbingMouse == YES), on mouse release event self.platformWindow is not nil yet, but is not a valid pointer already. Bail out early before touching it. Change-Id: Iea1025a82386d4b9dc21b3cbd3a5b248b2dd3620 Task-number: QTBUG-42059 Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
This commit is contained in:
parent
9132d1516a
commit
aeb169a488
@ -72,6 +72,7 @@ typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow;
|
|||||||
QCocoaWindow *_platformWindow;
|
QCocoaWindow *_platformWindow;
|
||||||
BOOL _grabbingMouse;
|
BOOL _grabbingMouse;
|
||||||
BOOL _releaseOnMouseUp;
|
BOOL _releaseOnMouseUp;
|
||||||
|
QPointer<QObject> _watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (nonatomic, readonly) QCocoaNSWindow *window;
|
@property (nonatomic, readonly) QCocoaNSWindow *window;
|
||||||
@ -321,6 +322,11 @@ public: // for QNSView
|
|||||||
};
|
};
|
||||||
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
|
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
|
||||||
QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
|
QHash<quintptr, bool> 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
|
QT_END_NAMESPACE
|
||||||
|
@ -99,6 +99,7 @@ static bool isMouseEvent(NSEvent *ev)
|
|||||||
// make sure that m_nsWindow stays valid until the
|
// make sure that m_nsWindow stays valid until the
|
||||||
// QCocoaWindow is deleted by Qt.
|
// QCocoaWindow is deleted by Qt.
|
||||||
[_window setReleasedWhenClosed:NO];
|
[_window setReleasedWhenClosed:NO];
|
||||||
|
_watcher = &_platformWindow->sentinel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@ -107,7 +108,7 @@ static bool isMouseEvent(NSEvent *ev)
|
|||||||
- (void)handleWindowEvent:(NSEvent *)theEvent
|
- (void)handleWindowEvent:(NSEvent *)theEvent
|
||||||
{
|
{
|
||||||
QCocoaWindow *pw = self.platformWindow;
|
QCocoaWindow *pw = self.platformWindow;
|
||||||
if (pw && pw->m_forwardWindow) {
|
if (_watcher && pw && pw->m_forwardWindow) {
|
||||||
if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
|
if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
|
||||||
QNSView *forwardView = pw->m_qtView;
|
QNSView *forwardView = pw->m_qtView;
|
||||||
if (theEvent.type == NSLeftMouseUp) {
|
if (theEvent.type == NSLeftMouseUp) {
|
||||||
@ -146,7 +147,7 @@ static bool isMouseEvent(NSEvent *ev)
|
|||||||
if (!self.window.delegate)
|
if (!self.window.delegate)
|
||||||
return; // Already detached, pending NSAppKitDefined event
|
return; // Already detached, pending NSAppKitDefined event
|
||||||
|
|
||||||
if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
|
if (_watcher && pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) {
|
||||||
NSPoint loc = [theEvent locationInWindow];
|
NSPoint loc = [theEvent locationInWindow];
|
||||||
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
|
NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]];
|
||||||
NSRect contentFrame = [[self.window contentView] frame];
|
NSRect contentFrame = [[self.window contentView] frame];
|
||||||
@ -162,6 +163,7 @@ static bool isMouseEvent(NSEvent *ev)
|
|||||||
- (void)detachFromPlatformWindow
|
- (void)detachFromPlatformWindow
|
||||||
{
|
{
|
||||||
_platformWindow = 0;
|
_platformWindow = 0;
|
||||||
|
_watcher.clear();
|
||||||
[self.window.delegate release];
|
[self.window.delegate release];
|
||||||
self.window.delegate = nil;
|
self.window.delegate = nil;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user