Changeset 846 for trunk/src/gui/kernel/qcocoaview_mac.mm
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/kernel/qcocoaview_mac.mm
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 82 82 extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); // qapplication.cpp 83 83 extern OSViewRef qt_mac_nativeview_for(const QWidget *w); // qwidget_mac.mm 84 extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp85 84 extern QPointer<QWidget> qt_mouseover; //qapplication_mac.mm 86 85 extern 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 } 86 extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); 102 87 103 88 struct dndenum_mapper … … 201 186 } 202 187 188 #ifdef ALIEN_DEBUG 189 static int qCocoaViewCount = 0; 190 #endif 203 191 204 192 @implementation QT_MANGLE_NAMESPACE(QCocoaView) … … 210 198 [self finishInitWithQWidget:widget widgetPrivate:widgetprivate]; 211 199 } 200 [self setFocusRingType:NSFocusRingTypeNone]; 212 201 composingText = new QString(); 202 203 #ifdef ALIEN_DEBUG 204 ++qCocoaViewCount; 205 qDebug() << "init: qCocoaViewCount is" << qCocoaViewCount; 206 #endif 207 213 208 composing = false; 214 209 sendKeyEvents = true; 215 currentCustomTypes = 0;216 210 [self setHidden:YES]; 217 211 return self; … … 228 222 } 229 223 230 -(void)registerDragTypes231 {232 QMacCocoaAutoReleasePool pool;233 // Calling registerForDraggedTypes is slow, so only do it once for each widget234 // 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 258 224 - (void)resetCursorRects 259 225 { 226 // [NSView addCursorRect] is slow, so bail out early if we can: 227 if (NSIsEmptyRect([self visibleRect])) 228 return; 229 260 230 QWidget *cursorWidget = qwidget; 261 231 … … 273 243 QRegion mask = qt_widget_private(cursorWidget)->extra->mask; 274 244 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)) { 276 247 [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor]; 277 248 } else { … … 299 270 } 300 271 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 301 294 - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender 302 295 { 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. 305 298 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 }312 299 dragEnterSequence = [sender draggingSequenceNumber]; 313 300 [self addDropData:sender]; … … 336 323 // widget is not interested in this drag, so ignore this drop data. 337 324 [self removeDropData]; 325 [self changeDraggingCursor:NSDragOperationNone]; 338 326 return NSDragOperationNone; 339 327 } else { … … 357 345 } 358 346 QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent); 347 [self changeDraggingCursor:nsActions]; 359 348 return nsActions; 360 349 } … … 362 351 - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender 363 352 { 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. 364 355 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 }371 356 // in cases like QFocusFrame, the view under the mouse might 372 357 // not have received the drag enter. Generate a synthetic … … 375 360 [self draggingEntered:sender]; 376 361 // drag enter event was rejected, so ignore the move event. 377 if (dropData == 0) 362 if (dropData == 0) { 363 [self changeDraggingCursor:NSDragOperationNone]; 378 364 return NSDragOperationNone; 365 } 379 366 // return last value, if we are still in the answerRect. 380 367 NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; … … 383 370 QPoint posDrag(localPoint.x, localPoint.y); 384 371 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 } 387 377 // send drag move event to the widget 388 378 QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions; … … 401 391 mimeData = QDragManager::self()->dragPrivate()->data; 402 392 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); 404 397 qDMEvent.accept(); 405 398 QApplication::sendEvent(qwidget, &qDMEvent); … … 413 406 } 414 407 qt_mac_copy_answer_rect(qDMEvent); 408 [self changeDraggingCursor:operation]; 415 409 return operation; 416 410 } … … 418 412 - (void)draggingExited:(id < NSDraggingInfo >)sender 419 413 { 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); 420 417 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 }428 418 // drag enter event was rejected, so ignore the move event. 429 419 if (dropData) { … … 432 422 [self removeDropData]; 433 423 } 424 [self changeDraggingCursor:NSDragOperationEvery]; 425 434 426 } 435 427 436 428 - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 437 429 { 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. 438 432 NSPoint windowPoint = [sender draggingLocation]; 439 433 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 }446 434 [self addDropData:sender]; 447 435 … … 473 461 delete composingText; 474 462 [[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 477 469 [super dealloc]; 478 470 } … … 480 472 - (BOOL)isOpaque; 481 473 { 474 if (!qwidgetprivate) 475 return [super isOpaque]; 482 476 return qwidgetprivate->isOpaque; 483 477 } … … 488 482 } 489 483 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 491 489 { 492 490 return qwidget->testAttribute(Qt::WA_StaticContents); … … 511 509 512 510 // Make sure the opengl context is updated on resize. 513 if (qwidgetprivate ->isGLWidget) {511 if (qwidgetprivate && qwidgetprivate->isGLWidget) { 514 512 qwidgetprivate->needWindowChange = true; 515 513 QEvent event(QEvent::MacGLWindowChange); … … 518 516 } 519 517 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 520 530 - (void)drawRect:(NSRect)aRect 521 531 { 532 if (!qwidget) 533 return; 534 522 535 if (QApplicationPrivate::graphicsSystem() != 0) { 523 if ( QWidgetBackingStore *bs =qwidgetprivate->maybeBackingStore()) {536 if (qwidgetprivate->maybeBackingStore()) { 524 537 // 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; 527 541 } 528 542 } … … 536 550 537 551 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 } 539 561 540 562 if (!qwidget->isWindow() && !qobject_cast<QAbstractScrollArea *>(qwidget->parent())) { … … 570 592 } 571 593 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) { 572 598 if (engine && !qwidget->testAttribute(Qt::WA_NoSystemBackground) 573 599 && (qwidget->isWindow() || qwidget->autoFillBackground()) … … 589 615 #endif 590 616 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 591 623 if (!redirectionOffset.isNull()) 592 624 QPainter::restoreRedirected(qwidget); … … 604 636 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 605 637 { 638 if (!qwidget) 639 return NO; 640 606 641 Q_UNUSED(theEvent); 607 642 return !qwidget->testAttribute(Qt::WA_MacNoClickThrough); … … 610 645 - (NSView *)hitTest:(NSPoint)aPoint 611 646 { 647 if (!qwidget) 648 return [super hitTest:aPoint]; 649 612 650 if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents)) 613 651 return nil; // You cannot hit a transparent for mouse event widget. … … 617 655 - (void)updateTrackingAreas 618 656 { 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 619 664 QMacCocoaAutoReleasePool pool; 620 665 if (NSArray *trackingArray = [self trackingAreas]) { … … 646 691 - (void)mouseEntered:(NSEvent *)event 647 692 { 693 if (!qwidget) 694 return; 648 695 if (qwidgetprivate->data.in_destructor) 649 696 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 654 698 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]; 655 703 QApplication::sendEvent(qwidget, &enterEvent); 656 704 qt_mouseover = qwidget; 657 705 658 // Update cursor and dispatch hover events.706 // Update cursor icon: 659 707 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 } 664 723 } 665 724 } … … 668 727 - (void)mouseExited:(NSEvent *)event 669 728 { 729 if (!qwidget) 730 return; 731 670 732 QEvent leaveEvent(QEvent::Leave); 671 733 NSPoint globalPoint = [[event window] convertBaseToScreen:[event locationInWindow]]; … … 686 748 - (void)flagsChanged:(NSEvent *)theEvent 687 749 { 750 if (!qwidget) 751 return; 752 688 753 QWidget *widgetToGetKey = qwidget; 689 754 … … 697 762 - (void)mouseMoved:(NSEvent *)theEvent 698 763 { 764 if (!qwidget) 765 return; 766 699 767 // We always enable mouse tracking for all QCocoaView-s. In cases where we have 700 768 // child views, we will receive mouseMoved for both parent & the child (if … … 816 884 // Since deviceDelta is delivered as pixels rather than degrees, we need to 817 885 // 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; 823 892 } else { 824 893 // carbonEventKind == kEventMouseWheelMoved … … 871 940 } 872 941 #endif //QT_NO_WHEELEVENT 873 874 if (!wheelOK) {875 return [super scrollWheel:theEvent];876 }877 942 } 878 943 … … 919 984 return; 920 985 986 #ifndef QT_NO_GESTURES 921 987 QNativeGestureEvent qNGEvent; 922 988 qNGEvent.gestureType = QNativeGestureEvent::Zoom; … … 925 991 qNGEvent.percentage = [event magnification]; 926 992 qt_sendSpontaneousEvent(qwidget, &qNGEvent); 993 #endif // QT_NO_GESTURES 927 994 } 928 995 … … 932 999 return; 933 1000 1001 #ifndef QT_NO_GESTURES 934 1002 QNativeGestureEvent qNGEvent; 935 1003 qNGEvent.gestureType = QNativeGestureEvent::Rotate; … … 938 1006 qNGEvent.percentage = -[event rotation]; 939 1007 qt_sendSpontaneousEvent(qwidget, &qNGEvent); 1008 #endif // QT_NO_GESTURES 940 1009 } 941 1010 … … 945 1014 return; 946 1015 1016 #ifndef QT_NO_GESTURES 947 1017 QNativeGestureEvent qNGEvent; 948 1018 qNGEvent.gestureType = QNativeGestureEvent::Swipe; … … 958 1028 qNGEvent.angle = 270.0f; 959 1029 qt_sendSpontaneousEvent(qwidget, &qNGEvent); 1030 #endif // QT_NO_GESTURES 960 1031 } 961 1032 … … 965 1036 return; 966 1037 1038 #ifndef QT_NO_GESTURES 967 1039 QNativeGestureEvent qNGEvent; 968 1040 qNGEvent.gestureType = QNativeGestureEvent::GestureBegin; … … 970 1042 qNGEvent.position = flipPoint(p).toPoint(); 971 1043 qt_sendSpontaneousEvent(qwidget, &qNGEvent); 1044 #endif // QT_NO_GESTURES 972 1045 } 973 1046 … … 977 1050 return; 978 1051 1052 #ifndef QT_NO_GESTURES 979 1053 QNativeGestureEvent qNGEvent; 980 1054 qNGEvent.gestureType = QNativeGestureEvent::GestureEnd; … … 982 1056 qNGEvent.position = flipPoint(p).toPoint(); 983 1057 qt_sendSpontaneousEvent(qwidget, &qNGEvent); 1058 #endif // QT_NO_GESTURES 984 1059 } 985 1060 … … 987 1062 { 988 1063 Q_UNUSED(note); 1064 if (!qwidget) 1065 return; 989 1066 if (qwidget->isWindow()) 990 1067 return; … … 1010 1087 QMacCocoaAutoReleasePool pool; 1011 1088 [super setEnabled:flag]; 1012 if (qwidget ->isEnabled() != flag)1089 if (qwidget && qwidget->isEnabled() != flag) 1013 1090 qwidget->setEnabled(flag); 1014 1091 } … … 1021 1098 - (BOOL)acceptsFirstResponder 1022 1099 { 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)) { 1024 1110 return YES; // Always do it, so that windows can accept key press events. 1111 } 1025 1112 return qwidget->focusPolicy() != Qt::NoFocus; 1026 1113 } … … 1028 1115 - (BOOL)resignFirstResponder 1029 1116 { 1117 if (!qwidget) 1118 return NO; 1030 1119 // Seems like the following test only triggers if this 1031 1120 // view is inside a QMacNativeWidget: 1032 1121 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); 1034 1133 return YES; 1035 1134 } … … 1063 1162 } 1064 1163 1164 - (void) qt_clearQWidget 1165 { 1166 qwidget = 0; 1167 qwidgetprivate = 0; 1168 } 1169 1065 1170 - (BOOL)qt_leftButtonIsRightButton 1066 1171 { … … 1099 1204 if (sendKeyEvents && !composing) { 1100 1205 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 } 1103 1215 } 1104 1216 } … … 1109 1221 if (sendKeyEvents) { 1110 1222 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 } 1113 1230 } 1114 1231 } … … 1116 1233 - (void)viewWillMoveToWindow:(NSWindow *)window 1117 1234 { 1235 if (qwidget == 0) 1236 return; 1237 1118 1238 if (qwidget->windowFlags() & Qt::MSWindowsOwnDC 1119 1239 && (window != [self window])) { // OpenGL Widget 1120 // Create a stupid ClearDrawable Event1121 1240 QEvent event(QEvent::MacGLClearDrawable); 1122 1241 qApp->sendEvent(qwidget, &event); … … 1126 1245 - (void)viewDidMoveToWindow 1127 1246 { 1247 if (qwidget == 0) 1248 return; 1249 1128 1250 if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) { 1129 1251 // call update paint event … … 1321 1443 - (NSArray*) validAttributesForMarkedText 1322 1444 { 1445 if (qwidget == 0) 1446 return nil; 1447 1323 1448 if (!qwidget->testAttribute(Qt::WA_InputMethodEnabled)) 1324 1449 return nil; // Not sure if that's correct, but it's saves a malloc. … … 1471 1596 [dndParams.view release]; 1472 1597 [image release]; 1473 dragPrivate()->executed_action = Qt::IgnoreAction; 1598 if (dragPrivate()) 1599 dragPrivate()->executed_action = Qt::IgnoreAction; 1474 1600 object = 0; 1475 1601 Qt::DropAction performedAction(qt_mac_mapNSDragOperation(qMacDnDParams()->performedAction)); … … 1493 1619 } 1494 1620 } 1621 o->setMimeData(0); 1622 o->deleteLater(); 1495 1623 return performedAction; 1496 1624 }
Note:
See TracChangeset
for help on using the changeset viewer.