Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qcocoaview_mac.mm

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    8282extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp
    8383extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm
    84 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp
    8584extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm
    8685extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp
    87 
    88 Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum)
    89 {
    90     if (buttonNum == 0)
    91         return Qt::LeftButton;
    92     if (buttonNum == 1)
    93         return Qt::RightButton;
    94     if (buttonNum == 2)
    95         return Qt::MidButton;
    96     if (buttonNum == 3)
    97         return Qt::XButton1;
    98     if (buttonNum == 4)
    99         return Qt::XButton2;
    100     return Qt::NoButton;
    101 }
     86extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
    10287
    10388struct dndenum_mapper
     
    201186}
    202187
     188#ifdef ALIEN_DEBUG
     189static int qCocoaViewCount = 0;
     190#endif
    203191
    204192@implementation QT_MANGLE_NAMESPACE(QCocoaView)
     
    210198        [self finishInitWithQWidget:widget widgetPrivate:widgetprivate];
    211199    }
     200    [self setFocusRingType:NSFocusRingTypeNone];
    212201    composingText = new QString();
     202
     203#ifdef ALIEN_DEBUG
     204    ++qCocoaViewCount;
     205    qDebug() << "init: qCocoaViewCount is" << qCocoaViewCount;
     206#endif
     207
    213208    composing = false;
    214209    sendKeyEvents = true;
    215     currentCustomTypes = 0;
    216210    [self setHidden:YES];
    217211    return self;
     
    228222}
    229223
    230 -(void)registerDragTypes
    231 {
    232     QMacCocoaAutoReleasePool pool;
    233     // Calling registerForDraggedTypes is slow, so only do it once for each widget
    234     // or when the custom types change.
    235     const QStringList& customTypes = qEnabledDraggedTypes();
    236     if (currentCustomTypes == 0 || *currentCustomTypes != customTypes) {
    237         if (currentCustomTypes == 0)
    238             currentCustomTypes = new QStringList();
    239         *currentCustomTypes = customTypes;
    240         const NSString* mimeTypeGeneric = @"com.trolltech.qt.MimeTypeName";
    241         NSMutableArray *supportedTypes = [NSMutableArray arrayWithObjects:NSColorPboardType,
    242                                    NSFilenamesPboardType, NSStringPboardType,
    243                                    NSFilenamesPboardType, NSPostScriptPboardType, NSTIFFPboardType,
    244                                    NSRTFPboardType, NSTabularTextPboardType, NSFontPboardType,
    245                                    NSRulerPboardType, NSFileContentsPboardType, NSColorPboardType,
    246                                    NSRTFDPboardType, NSHTMLPboardType, NSPICTPboardType,
    247                                    NSURLPboardType, NSPDFPboardType, NSVCardPboardType,
    248                                    NSFilesPromisePboardType, NSInkTextPboardType,
    249                                    NSMultipleTextSelectionPboardType, mimeTypeGeneric, nil];
    250         // Add custom types supported by the application.
    251         for (int i = 0; i < customTypes.size(); i++) {
    252            [supportedTypes addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(customTypes[i]))];
    253         }
    254         [self registerForDraggedTypes:supportedTypes];
    255     }
    256 }
    257 
    258224- (void)resetCursorRects
    259225{
     226    // [NSView addCursorRect] is slow, so bail out early if we can:
     227    if (NSIsEmptyRect([self visibleRect]))
     228        return;
     229
    260230    QWidget *cursorWidget = qwidget;
    261231
     
    273243    QRegion mask = qt_widget_private(cursorWidget)->extra->mask;
    274244    NSCursor *nscursor = static_cast<NSCursor *>(qt_mac_nsCursorForQCursor(cursorWidget->cursor()));
    275     if (mask.isEmpty()) {
     245    // The mask could have the WA_MouseNoMask attribute set and that means that we have to ignore the mask.
     246    if (mask.isEmpty() || cursorWidget->testAttribute(Qt::WA_MouseNoMask)) {
    276247        [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor];
    277248    } else {
     
    299270}
    300271
     272- (void)changeDraggingCursor:(NSDragOperation)newOperation
     273{
     274    static SEL action = nil;
     275    static bool operationSupported = false;
     276    if (action == nil) {
     277        action = NSSelectorFromString(@"operationNotAllowedCursor");
     278        if ([NSCursor respondsToSelector:action]) {
     279            operationSupported = true;
     280        }
     281    }
     282    if (operationSupported) {
     283        NSCursor *notAllowedCursor = [NSCursor performSelector:action];
     284        bool isNotAllowedCursor = ([NSCursor currentCursor] == notAllowedCursor);
     285        if (newOperation == NSDragOperationNone && !isNotAllowedCursor) {
     286            [notAllowedCursor push];
     287        } else if (newOperation != NSDragOperationNone && isNotAllowedCursor) {
     288            [notAllowedCursor pop];
     289        }
     290
     291    }
     292}
     293
    301294- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
    302295{
    303     if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false)
    304         return NSDragOperationNone;
     296    // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
     297    // from Cocoa. They modify the drag target, and might fake enter/leave events.
    305298    NSPoint windowPoint = [sender draggingLocation];
    306     if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
    307         // pass the drag enter event to the view underneath.
    308         NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
    309         if (candidateView && candidateView != self)
    310             return [candidateView draggingEntered:sender];
    311     }
    312299    dragEnterSequence = [sender draggingSequenceNumber];
    313300    [self addDropData:sender];
     
    336323        // widget is not interested in this drag, so ignore this drop data.
    337324        [self removeDropData];
     325        [self changeDraggingCursor:NSDragOperationNone];
    338326        return NSDragOperationNone;
    339327    } else {
     
    357345        }
    358346        QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
     347        [self changeDraggingCursor:nsActions];
    359348        return nsActions;
    360349    }
     
    362351- (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender
    363352{
     353    // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
     354    // from Cocoa. They modify the drag target, and might fake enter/leave events.
    364355    NSPoint windowPoint = [sender draggingLocation];
    365     if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
    366         // pass the drag move event to the view underneath.
    367         NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
    368         if (candidateView && candidateView != self)
    369             return [candidateView draggingUpdated:sender];
    370     }
    371356    // in cases like QFocusFrame, the view under the mouse might
    372357    // not have received the drag enter. Generate a synthetic
     
    375360        [self draggingEntered:sender];
    376361    // drag enter event was rejected, so ignore the move event.
    377     if (dropData == 0)
     362    if (dropData == 0) {
     363        [self changeDraggingCursor:NSDragOperationNone];
    378364        return NSDragOperationNone;
     365    }
    379366    // return last value, if we are still in the answerRect.
    380367    NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
     
    383370    QPoint posDrag(localPoint.x, localPoint.y);
    384371    if (qt_mac_mouse_inside_answer_rect(posDrag)
    385         && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions)
    386         return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
     372        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) {
     373        NSDragOperation operation = QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
     374        [self changeDraggingCursor:operation];
     375        return operation;
     376    }
    387377    // send drag move event to the widget
    388378    QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
     
    401391        mimeData = QDragManager::self()->dragPrivate()->data;
    402392    QDragMoveEvent qDMEvent(posDrag, qtAllowed, mimeData, QApplication::mouseButtons(), modifiers);
    403     qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
     393    if (QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction != Qt::IgnoreAction
     394        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).buttons == qDMEvent.mouseButtons()
     395        && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).modifiers == qDMEvent.keyboardModifiers())
     396        qDMEvent.setDropAction(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec).lastAction);
    404397    qDMEvent.accept();
    405398    QApplication::sendEvent(qwidget, &qDMEvent);
     
    413406    }
    414407    qt_mac_copy_answer_rect(qDMEvent);
     408    [self changeDraggingCursor:operation];
    415409    return operation;
    416410}
     
    418412- (void)draggingExited:(id < NSDraggingInfo >)sender
    419413{
     414    // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
     415    // from Cocoa. They modify the drag target, and might fake enter/leave events.
     416    Q_UNUSED(sender);
    420417    dragEnterSequence = -1;
    421     if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
    422         // try sending the leave event to the last view which accepted drag enter.
    423         DnDParams *dndParams = [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent];
    424         NSView *candidateView = [[[self window] contentView] hitTest:dndParams->activeDragEnterPos];
    425         if (candidateView && candidateView != self)
    426             return [candidateView draggingExited:sender];
    427     }
    428418    // drag enter event was rejected, so ignore the move event.
    429419    if (dropData) {
     
    432422        [self removeDropData];
    433423    }
     424    [self changeDraggingCursor:NSDragOperationEvery];
     425
    434426}
    435427
    436428- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
    437429{
     430    // NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
     431    // from Cocoa. They modify the drag target, and might fake enter/leave events.
    438432    NSPoint windowPoint = [sender draggingLocation];
    439433    dragEnterSequence = -1;
    440     if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) {
    441         // pass the drop event to the view underneath.
    442         NSView *candidateView = [[[self window] contentView] hitTest:windowPoint];
    443         if (candidateView && candidateView != self)
    444             return [candidateView performDragOperation:sender];
    445     }
    446434    [self addDropData:sender];
    447435
     
    473461    delete composingText;
    474462    [[NSNotificationCenter defaultCenter] removeObserver:self];
    475     delete currentCustomTypes;
    476     [self unregisterDraggedTypes];
     463
     464#ifdef ALIEN_DEBUG
     465    --qCocoaViewCount;
     466    qDebug() << "qCocoaViewCount is" << qCocoaViewCount;
     467#endif
     468
    477469    [super dealloc];
    478470}
     
    480472- (BOOL)isOpaque;
    481473{
     474    if (!qwidgetprivate)
     475        return [super isOpaque];
    482476    return qwidgetprivate->isOpaque;
    483477}
     
    488482}
    489483
    490 - (BOOL) preservesContentDuringLiveResize;
     484// We preserve the content of the view if WA_StaticContents is defined.
     485//
     486// More info in the Cocoa documentation:
     487// http://developer.apple.com/mac/library/documentation/cocoa/conceptual/CocoaViewsGuide/Optimizing/Optimizing.html
     488- (BOOL) preservesContentDuringLiveResize
    491489{
    492490    return qwidget->testAttribute(Qt::WA_StaticContents);
     
    511509
    512510    // Make sure the opengl context is updated on resize.
    513     if (qwidgetprivate->isGLWidget) {
     511    if (qwidgetprivate && qwidgetprivate->isGLWidget) {
    514512        qwidgetprivate->needWindowChange = true;
    515513        QEvent event(QEvent::MacGLWindowChange);
     
    518516}
    519517
     518// We catch the 'setNeedsDisplay:' message in order to avoid a useless full repaint.
     519// During the resize, the top of the widget is repainted, probably because of the
     520// change of coordinate space (Quartz vs Qt). This is then followed by this message:
     521// -[NSView _setNeedsDisplayIfTopLeftChanged]
     522// which force a full repaint by sending the message 'setNeedsDisplay:'.
     523// That is what we are preventing here.
     524- (void)setNeedsDisplay:(BOOL)flag {
     525    if (![self inLiveResize] || !(qwidget->testAttribute(Qt::WA_StaticContents))) {
     526        [super setNeedsDisplay:flag];
     527    }
     528}
     529
    520530- (void)drawRect:(NSRect)aRect
    521531{
     532    if (!qwidget)
     533        return;
     534
    522535    if (QApplicationPrivate::graphicsSystem() != 0) {
    523         if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
     536        if (qwidgetprivate->maybeBackingStore()) {
    524537            // Drawing is handled on the window level
    525             // See qcocoasharedwindowmethods_mac_p.
    526             return;
     538            // See qcocoasharedwindowmethods_mac_p.h
     539            if (!qwidget->testAttribute(Qt::WA_PaintOnScreen))
     540                return;
    527541        }
    528542    }
     
    536550
    537551        const QRect qrect = QRect(aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height);
    538         QRegion qrgn(qrect);
     552        QRegion qrgn;
     553
     554        const NSRect *rects;
     555        NSInteger count;
     556        [self getRectsBeingDrawn:&rects count:&count];
     557        for (int i = 0; i < count; ++i) {
     558            QRect tmpRect = QRect(rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
     559            qrgn += tmpRect;
     560        }
    539561
    540562        if (!qwidget->isWindow() && !qobject_cast<QAbstractScrollArea *>(qwidget->parent())) {
     
    570592        }
    571593
     594        // Check for alien widgets, use qwidgetPrivate->drawWidget() to draw the widget if this
     595        // is the case. This makes sure child widgets are drawn as well, Cocoa does not know about
     596        // those and wont send them drawRect calls.
     597        if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) {
    572598        if (engine && !qwidget->testAttribute(Qt::WA_NoSystemBackground)
    573599            && (qwidget->isWindow() || qwidget->autoFillBackground())
     
    589615#endif
    590616        qt_sendSpontaneousEvent(qwidget, &e);
     617        } else {
     618           qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false); // QWidgetPrivate::drawWidget sets this
     619           QWidgetPrivate *qwidgetPrivate = qt_widget_private(qwidget);
     620           qwidgetPrivate->drawWidget(qwidget, qrgn, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen | QWidgetPrivate::DrawRecursive, 0);
     621        }
     622
    591623        if (!redirectionOffset.isNull())
    592624            QPainter::restoreRedirected(qwidget);
     
    604636- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
    605637{
     638    if (!qwidget)
     639        return NO;
     640
    606641    Q_UNUSED(theEvent);
    607642    return !qwidget->testAttribute(Qt::WA_MacNoClickThrough);
     
    610645- (NSView *)hitTest:(NSPoint)aPoint
    611646{
     647    if (!qwidget)
     648        return [super hitTest:aPoint];
     649
    612650    if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents))
    613651        return nil; // You cannot hit a transparent for mouse event widget.
     
    617655- (void)updateTrackingAreas
    618656{
     657    if (!qwidget)
     658        return;
     659
     660    // [NSView addTrackingArea] is slow, so bail out early if we can:
     661    if (NSIsEmptyRect([self visibleRect]))
     662        return;
     663
    619664    QMacCocoaAutoReleasePool pool;
    620665    if (NSArray *trackingArray = [self trackingAreas]) {
     
    646691- (void)mouseEntered:(NSEvent *)event
    647692{
     693    if (!qwidget)
     694        return;
    648695    if (qwidgetprivate->data.in_destructor)
    649696        return;
    650     QEvent enterEvent(QEvent::Enter);
    651     NSPoint windowPoint = [event locationInWindow];
    652     NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
    653     NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil];
     697
    654698    if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) {
     699        QEvent enterEvent(QEvent::Enter);
     700        NSPoint windowPoint = [event locationInWindow];
     701        NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint];
     702        NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil];
    655703        QApplication::sendEvent(qwidget, &enterEvent);
    656704        qt_mouseover = qwidget;
    657705
    658         // Update cursor and dispatch hover events.
     706        // Update cursor icon:
    659707        qt_mac_update_cursor_at_global_pos(flipPoint(globalPoint).toPoint());
    660         if (qwidget->testAttribute(Qt::WA_Hover) &&
    661             (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window())) {
    662             QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1));
    663             QApplicationPrivate::instance()->notify_helper(qwidget, &he);
     708
     709        // Send mouse move and hover events as well:
     710        if (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window()) {
     711            // This mouse move event should be sendt, even when mouse
     712            // tracking is switched off (to trigger tooltips):
     713            NSEvent *mouseEvent = [NSEvent mouseEventWithType:NSMouseMoved
     714                location:windowPoint modifierFlags:[event modifierFlags] timestamp:[event timestamp]
     715                windowNumber:[event windowNumber] context:[event context] eventNumber:[event eventNumber]
     716                clickCount:0 pressure:0];
     717            qt_mac_handleMouseEvent(self, mouseEvent, QEvent::MouseMove, Qt::NoButton);
     718
     719            if (qwidget->testAttribute(Qt::WA_Hover)) {
     720                QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1));
     721                QApplicationPrivate::instance()->notify_helper(qwidget, &he);
     722            }
    664723        }
    665724    }
     
    668727- (void)mouseExited:(NSEvent *)event
    669728{
     729    if (!qwidget)
     730        return;
     731
    670732    QEvent leaveEvent(QEvent::Leave);
    671733    NSPoint globalPoint = [[event window] convertBaseToScreen:[event locationInWindow]];
     
    686748- (void)flagsChanged:(NSEvent *)theEvent
    687749{
     750    if (!qwidget)
     751        return;
     752
    688753    QWidget *widgetToGetKey = qwidget;
    689754
     
    697762- (void)mouseMoved:(NSEvent *)theEvent
    698763{
     764    if (!qwidget)
     765        return;
     766
    699767    // We always enable mouse tracking for all QCocoaView-s. In cases where we have
    700768    // child views, we will receive mouseMoved for both parent & the child (if
     
    816884        // Since deviceDelta is delivered as pixels rather than degrees, we need to
    817885        // convert from pixels to degrees in a sensible manner.
    818         // It looks like four degrees per pixel behaves most native.
    819         // Qt expects the unit for delta to be 1/8 of a degree:
    820         deltaX = [theEvent deviceDeltaX];
    821         deltaY = [theEvent deviceDeltaY];
    822         deltaZ = [theEvent deviceDeltaZ];
     886        // It looks like 1/4 degrees per pixel behaves most native.
     887        // (NB: Qt expects the unit for delta to be 8 per degree):
     888        const int pixelsToDegrees = 2; // 8 * 1/4
     889        deltaX = [theEvent deviceDeltaX] * pixelsToDegrees;
     890        deltaY = [theEvent deviceDeltaY] * pixelsToDegrees;
     891        deltaZ = [theEvent deviceDeltaZ] * pixelsToDegrees;
    823892    } else {
    824893        // carbonEventKind == kEventMouseWheelMoved
     
    871940    }
    872941#endif //QT_NO_WHEELEVENT
    873 
    874     if (!wheelOK) {
    875         return [super scrollWheel:theEvent];
    876     }
    877942}
    878943
     
    919984        return;
    920985
     986#ifndef QT_NO_GESTURES
    921987    QNativeGestureEvent qNGEvent;
    922988    qNGEvent.gestureType = QNativeGestureEvent::Zoom;
     
    925991    qNGEvent.percentage = [event magnification];
    926992    qt_sendSpontaneousEvent(qwidget, &qNGEvent);
     993#endif // QT_NO_GESTURES
    927994}
    928995
     
    932999        return;
    9331000
     1001#ifndef QT_NO_GESTURES
    9341002    QNativeGestureEvent qNGEvent;
    9351003    qNGEvent.gestureType = QNativeGestureEvent::Rotate;
     
    9381006    qNGEvent.percentage = -[event rotation];
    9391007    qt_sendSpontaneousEvent(qwidget, &qNGEvent);
     1008#endif // QT_NO_GESTURES
    9401009}
    9411010
     
    9451014        return;
    9461015
     1016#ifndef QT_NO_GESTURES
    9471017    QNativeGestureEvent qNGEvent;
    9481018    qNGEvent.gestureType = QNativeGestureEvent::Swipe;
     
    9581028        qNGEvent.angle = 270.0f;
    9591029    qt_sendSpontaneousEvent(qwidget, &qNGEvent);
     1030#endif // QT_NO_GESTURES
    9601031}
    9611032
     
    9651036        return;
    9661037
     1038#ifndef QT_NO_GESTURES
    9671039    QNativeGestureEvent qNGEvent;
    9681040    qNGEvent.gestureType = QNativeGestureEvent::GestureBegin;
     
    9701042    qNGEvent.position = flipPoint(p).toPoint();
    9711043    qt_sendSpontaneousEvent(qwidget, &qNGEvent);
     1044#endif // QT_NO_GESTURES
    9721045}
    9731046
     
    9771050        return;
    9781051
     1052#ifndef QT_NO_GESTURES
    9791053    QNativeGestureEvent qNGEvent;
    9801054    qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
     
    9821056    qNGEvent.position = flipPoint(p).toPoint();
    9831057    qt_sendSpontaneousEvent(qwidget, &qNGEvent);
     1058#endif // QT_NO_GESTURES
    9841059}
    9851060
     
    9871062{
    9881063    Q_UNUSED(note);
     1064    if (!qwidget)
     1065        return;
    9891066    if (qwidget->isWindow())
    9901067        return;
     
    10101087    QMacCocoaAutoReleasePool pool;
    10111088    [super setEnabled:flag];
    1012     if (qwidget->isEnabled() != flag)
     1089    if (qwidget && qwidget->isEnabled() != flag)
    10131090        qwidget->setEnabled(flag);
    10141091}
     
    10211098- (BOOL)acceptsFirstResponder
    10221099{
    1023     if (qwidget->isWindow())
     1100    if (!qwidget)
     1101        return NO;
     1102    // disabled widget shouldn't get focus even if it's a window.
     1103    // hence disabled windows will not get any key or mouse events.
     1104    if (!qwidget->isEnabled())
     1105        return NO;
     1106    // Before accepting the focus for a window, we check that
     1107    // the focusWidget (if any) is not contained in the same window.
     1108    if (qwidget->isWindow() && !qt_widget_private(qwidget)->topData()->embedded
     1109        && (!qApp->focusWidget() || qApp->focusWidget()->window() != qwidget)) {
    10241110        return YES;  // Always do it, so that windows can accept key press events.
     1111    }
    10251112    return qwidget->focusPolicy() != Qt::NoFocus;
    10261113}
     
    10281115- (BOOL)resignFirstResponder
    10291116{
     1117    if (!qwidget)
     1118        return NO;
    10301119    // Seems like the following test only triggers if this
    10311120    // view is inside a QMacNativeWidget:
    10321121    if (qwidget == QApplication::focusWidget())
    1033         QApplicationPrivate::setFocusWidget(0, Qt::OtherFocusReason);
     1122        qwidget->clearFocus();
     1123    return YES;
     1124}
     1125
     1126- (BOOL)becomeFirstResponder
     1127{
     1128    // see the comment in the acceptsFirstResponder - if the window "stole" focus
     1129    // let it become the responder, but don't tell Qt
     1130    if (qwidget && qt_widget_private(qwidget->window())->topData()->embedded
     1131        && !QApplication::focusWidget() && qwidget->focusPolicy() != Qt::NoFocus)
     1132        qwidget->setFocus(Qt::OtherFocusReason);
    10341133    return YES;
    10351134}
     
    10631162}
    10641163
     1164- (void) qt_clearQWidget
     1165{
     1166    qwidget = 0;
     1167    qwidgetprivate = 0;
     1168}
     1169
    10651170- (BOOL)qt_leftButtonIsRightButton
    10661171{
     
    10991204    if (sendKeyEvents && !composing) {
    11001205        bool keyOK = qt_dispatchKeyEvent(theEvent, widgetToGetKey);
    1101         if (!keyOK && !sendToPopup)
    1102             [super keyDown:theEvent];
     1206        if (!keyOK && !sendToPopup) {
     1207            // find the first responder that is not created by Qt and forward
     1208            // the event to it (for example if Qt widget is embedded into native).
     1209            QWidget *toplevel = qwidget->window();
     1210            if (toplevel && qt_widget_private(toplevel)->topData()->embedded) {
     1211                if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
     1212                    [w keyDown:theEvent];
     1213            }
     1214        }
    11031215    }
    11041216}
     
    11091221    if (sendKeyEvents) {
    11101222        bool keyOK = qt_dispatchKeyEvent(theEvent, qwidget);
    1111         if (!keyOK)
    1112             [super keyUp:theEvent];
     1223        if (!keyOK) {
     1224            QWidget *toplevel = qwidget->window();
     1225            if (toplevel && qt_widget_private(toplevel)->topData()->embedded) {
     1226                if (NSResponder *w = [qt_mac_nativeview_for(toplevel) superview])
     1227                    [w keyUp:theEvent];
     1228            }
     1229        }
    11131230    }
    11141231}
     
    11161233- (void)viewWillMoveToWindow:(NSWindow *)window
    11171234{
     1235    if (qwidget == 0)
     1236        return;
     1237
    11181238    if (qwidget->windowFlags() & Qt::MSWindowsOwnDC
    11191239          && (window != [self window])) { // OpenGL Widget
    1120         // Create a stupid ClearDrawable Event
    11211240        QEvent event(QEvent::MacGLClearDrawable);
    11221241        qApp->sendEvent(qwidget, &event);
     
    11261245- (void)viewDidMoveToWindow
    11271246{
     1247    if (qwidget == 0)
     1248        return;
     1249
    11281250    if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) {
    11291251        // call update paint event
     
    13211443- (NSArray*) validAttributesForMarkedText
    13221444{
     1445    if (qwidget == 0)
     1446        return nil;
     1447
    13231448    if (!qwidget->testAttribute(Qt::WA_InputMethodEnabled))
    13241449        return nil;  // Not sure if that's correct, but it's saves a malloc.
     
    14711596    [dndParams.view release];
    14721597    [image release];
    1473     dragPrivate()->executed_action = Qt::IgnoreAction;
     1598    if (dragPrivate())
     1599        dragPrivate()->executed_action = Qt::IgnoreAction;
    14741600    object = 0;
    14751601    Qt::DropAction performedAction(qt_mac_mapNSDragOperation(qMacDnDParams()->performedAction));
     
    14931619        }
    14941620    }
     1621    o->setMimeData(0);
     1622    o->deleteLater();
    14951623    return performedAction;
    14961624}
Note: See TracChangeset for help on using the changeset viewer.