diff options
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qcocoaview_mac.mm | 52 | ||||
-rw-r--r-- | src/gui/kernel/qcocoaview_mac_p.h | 1 | ||||
-rw-r--r-- | src/gui/kernel/qgesture_p.h | 2 | ||||
-rw-r--r-- | src/gui/kernel/qgesturerecognizer.cpp | 1 | ||||
-rw-r--r-- | src/gui/kernel/qt_cocoa_helpers_mac.mm | 10 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 9 |
6 files changed, 71 insertions, 4 deletions
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index c347410..6a16403 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -419,6 +419,8 @@ extern "C" { - (BOOL)isOpaque; { + if (!qwidgetprivate) + return [super isOpaque]; return qwidgetprivate->isOpaque; } @@ -450,7 +452,7 @@ extern "C" { } // Make sure the opengl context is updated on resize. - if (qwidgetprivate->isGLWidget) { + if (qwidgetprivate && qwidgetprivate->isGLWidget) { qwidgetprivate->needWindowChange = true; QEvent event(QEvent::MacGLWindowChange); qApp->sendEvent(qwidget, &event); @@ -459,6 +461,9 @@ extern "C" { - (void)drawRect:(NSRect)aRect { + if (!qwidget) + return; + if (QApplicationPrivate::graphicsSystem() != 0) { if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) { // Drawing is handled on the window level @@ -552,12 +557,18 @@ extern "C" { - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { + if (!qwidget) + return NO; + Q_UNUSED(theEvent); return !qwidget->testAttribute(Qt::WA_MacNoClickThrough); } - (NSView *)hitTest:(NSPoint)aPoint { + if (!qwidget) + return [super hitTest:aPoint]; + if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) return nil; // You cannot hit a transparent for mouse event widget. return [super hitTest:aPoint]; @@ -565,6 +576,9 @@ extern "C" { - (void)updateTrackingAreas { + if (!qwidget) + return; + // [NSView addTrackingArea] is slow, so bail out early if we can: if (NSIsEmptyRect([self visibleRect])) return; @@ -598,6 +612,9 @@ extern "C" { - (void)mouseEntered:(NSEvent *)event { + if (!qwidget) + return; + if (qwidgetprivate->data.in_destructor) return; QEvent enterEvent(QEvent::Enter); @@ -620,6 +637,9 @@ extern "C" { - (void)mouseExited:(NSEvent *)event { + if (!qwidget) + return; + QEvent leaveEvent(QEvent::Leave); NSPoint globalPoint = [[event window] convertBaseToScreen:[event locationInWindow]]; if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) { @@ -638,6 +658,9 @@ extern "C" { - (void)flagsChanged:(NSEvent *)theEvent { + if (!qwidget) + return; + QWidget *widgetToGetKey = qwidget; QWidget *popup = qAppInstance()->activePopupWidget(); @@ -649,6 +672,9 @@ extern "C" { - (void)mouseMoved:(NSEvent *)theEvent { + if (!qwidget) + return; + // We always enable mouse tracking for all QCocoaView-s. In cases where we have // child views, we will receive mouseMoved for both parent & the child (if // mouse is over the child). We need to ignore the parent mouseMoved in such @@ -939,6 +965,8 @@ extern "C" { - (void)frameDidChange:(NSNotification *)note { Q_UNUSED(note); + if (!qwidget) + return; if (qwidget->isWindow()) return; NSRect newFrame = [self frame]; @@ -962,7 +990,7 @@ extern "C" { { QMacCocoaAutoReleasePool pool; [super setEnabled:flag]; - if (qwidget->isEnabled() != flag) + if (qwidget && qwidget->isEnabled() != flag) qwidget->setEnabled(flag); } @@ -973,6 +1001,8 @@ extern "C" { - (BOOL)acceptsFirstResponder { + if (!qwidget) + return NO; if (qwidget->isWindow()) return YES; // Always do it, so that windows can accept key press events. return qwidget->focusPolicy() != Qt::NoFocus; @@ -980,6 +1010,8 @@ extern "C" { - (BOOL)resignFirstResponder { + if (!qwidget) + return NO; // Seems like the following test only triggers if this // view is inside a QMacNativeWidget: if (qwidget == QApplication::focusWidget()) @@ -1015,6 +1047,12 @@ extern "C" { return qwidget; } +- (void) qt_clearQWidget +{ + qwidget = 0; + qwidgetprivate = 0; +} + - (BOOL)qt_leftButtonIsRightButton { return leftButtonIsRightButton; @@ -1068,9 +1106,11 @@ extern "C" { - (void)viewWillMoveToWindow:(NSWindow *)window { + if (qwidget == 0) + return; + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && (window != [self window])) { // OpenGL Widget - // Create a stupid ClearDrawable Event QEvent event(QEvent::MacGLClearDrawable); qApp->sendEvent(qwidget, &event); } @@ -1078,6 +1118,9 @@ extern "C" { - (void)viewDidMoveToWindow { + if (qwidget == 0) + return; + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) { // call update paint event qwidgetprivate->needWindowChange = true; @@ -1273,6 +1316,9 @@ extern "C" { - (NSArray*) validAttributesForMarkedText { + if (qwidget == 0) + return nil; + if (!qwidget->testAttribute(Qt::WA_InputMethodEnabled)) return nil; // Not sure if that's correct, but it's saves a malloc. diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 4bb10c5..33aaa24 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -103,6 +103,7 @@ Q_GUI_EXPORT - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation; - (BOOL)isComposing; - (QWidget *)qt_qwidget; +- (void) qt_clearQWidget; - (BOOL)qt_leftButtonIsRightButton; - (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped; + (DnDParams*)currentMouseEvent; diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index dee5592..649a310 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -69,13 +69,13 @@ public: QGesturePrivate() : gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false), gestureCancelPolicy(0) - { } Qt::GestureType gestureType; Qt::GestureState state; QPointF hotSpot; + QPointF sceneHotSpot; uint isHotSpotSet : 1; uint gestureCancelPolicy : 2; }; diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index 8735d27..c88a9a7 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -181,6 +181,7 @@ void QGestureRecognizer::reset(QGesture *gesture) QGesturePrivate *d = gesture->d_func(); d->state = Qt::NoGesture; d->hotSpot = QPointF(); + d->sceneHotSpot = QPointF(); d->isHotSpotSet = false; } } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index e9fdbda..9560952 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -369,6 +369,16 @@ QMacTabletHash *qt_mac_tablet_hash() } #ifdef QT_MAC_USE_COCOA + +// Clears the QWidget pointer that each QCocoaView holds. +void qt_mac_clearCocoaViewQWidgetPointers(QWidget *widget) +{ + QCocoaView *cocoaView = reinterpret_cast<QCocoaView *>(qt_mac_nativeview_for(widget)); + if (cocoaView && [cocoaView respondsToSelector:@selector(qt_qwidget)]) { + [cocoaView qt_clearQWidget]; + } +} + void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent) { NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index d433048..1e9b1d9 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1468,6 +1468,15 @@ QWidget::~QWidget() d->declarativeData = 0; // don't activate again in ~QObject } +#ifdef QT_MAC_USE_COCOA + // QCocoaView holds a pointer back to this widget. Clear it now + // to make sure it's not followed later on. The lifetime of the + // QCocoaView might exceed the lifetime of this widget in cases + // where Cocoa itself holds references to it. + extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *); + qt_mac_clearCocoaViewQWidgetPointers(this); +#endif + if (!d->children.isEmpty()) d->deleteChildren(); |