src/gui/kernel/qwidget_mac.mm
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
child 18 2f34d5167611
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   723             qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
   723             qWarning("QWidget: Internal error (%s:%d)", __FILE__, __LINE__);
   724     }
   724     }
   725     return window;
   725     return window;
   726 }
   726 }
   727 
   727 
       
   728 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
       
   729 /* We build the release package against the 10.4 SDK.
       
   730    So, to enable gestures for applications running on
       
   731    10.6+, we define the missing constants here: */
       
   732 enum {
       
   733     kEventClassGesture              = 'gest',
       
   734     kEventGestureStarted            = 1,
       
   735     kEventGestureEnded              = 2,
       
   736     kEventGestureMagnify            = 4,
       
   737     kEventGestureSwipe              = 5,
       
   738     kEventGestureRotate             = 6,
       
   739     kEventParamRotationAmount       = 'rota',
       
   740     kEventParamSwipeDirection       = 'swip',
       
   741     kEventParamMagnificationAmount  = 'magn'
       
   742 };
       
   743 #endif
       
   744 
   728 // window events
   745 // window events
   729 static EventTypeSpec window_events[] = {
   746 static EventTypeSpec window_events[] = {
   730     { kEventClassWindow, kEventWindowClose },
   747     { kEventClassWindow, kEventWindowClose },
   731     { kEventClassWindow, kEventWindowExpanded },
   748     { kEventClassWindow, kEventWindowExpanded },
   732     { kEventClassWindow, kEventWindowHidden },
   749     { kEventClassWindow, kEventWindowHidden },
       
   750     { kEventClassWindow, kEventWindowZoom },
   733     { kEventClassWindow, kEventWindowZoomed },
   751     { kEventClassWindow, kEventWindowZoomed },
   734     { kEventClassWindow, kEventWindowCollapsed },
   752     { kEventClassWindow, kEventWindowCollapsed },
   735     { kEventClassWindow, kEventWindowToolbarSwitchMode },
   753     { kEventClassWindow, kEventWindowToolbarSwitchMode },
   736     { kEventClassWindow, kEventWindowProxyBeginDrag },
   754     { kEventClassWindow, kEventWindowProxyBeginDrag },
   737     { kEventClassWindow, kEventWindowProxyEndDrag },
   755     { kEventClassWindow, kEventWindowProxyEndDrag },
   738     { kEventClassWindow, kEventWindowResizeCompleted },
   756     { kEventClassWindow, kEventWindowResizeCompleted },
   739     { kEventClassWindow, kEventWindowBoundsChanging },
   757     { kEventClassWindow, kEventWindowBoundsChanging },
   740     { kEventClassWindow, kEventWindowGetRegion },
   758     { kEventClassWindow, kEventWindowGetRegion },
   741     { kEventClassWindow, kEventWindowGetClickModality },
   759     { kEventClassWindow, kEventWindowGetClickModality },
   742     { kEventClassWindow, kEventWindowTransitionCompleted },
   760     { kEventClassWindow, kEventWindowTransitionCompleted },
   743 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
   744     { kEventClassGesture, kEventGestureStarted },
   761     { kEventClassGesture, kEventGestureStarted },
   745     { kEventClassGesture, kEventGestureEnded },
   762     { kEventClassGesture, kEventGestureEnded },
   746     { kEventClassGesture, kEventGestureMagnify },
   763     { kEventClassGesture, kEventGestureMagnify },
   747     { kEventClassGesture, kEventGestureSwipe },
   764     { kEventClassGesture, kEventGestureSwipe },
   748     { kEventClassGesture, kEventGestureRotate },
   765     { kEventClassGesture, kEventGestureRotate },
   749 #endif
       
   750     { kEventClassMouse, kEventMouseDown }
   766     { kEventClassMouse, kEventMouseDown }
   751 };
   767 };
   752 static EventHandlerUPP mac_win_eventUPP = 0;
   768 static EventHandlerUPP mac_win_eventUPP = 0;
   753 static void cleanup_win_eventUPP()
   769 static void cleanup_win_eventUPP()
   754 {
   770 {
   810                 QApplication::sendSpontaneousEvent(widget, &e);
   826                 QApplication::sendSpontaneousEvent(widget, &e);
   811             }
   827             }
   812 
   828 
   813             QShowEvent qse;
   829             QShowEvent qse;
   814             QApplication::sendSpontaneousEvent(widget, &qse);
   830             QApplication::sendSpontaneousEvent(widget, &qse);
       
   831         } else if(ekind == kEventWindowZoom) {
       
   832             widget->d_func()->topData()->normalGeometry = widget->geometry();
       
   833             handled_event = false;
   815         } else if(ekind == kEventWindowZoomed) {
   834         } else if(ekind == kEventWindowZoomed) {
   816             WindowPartCode windowPart;
   835             WindowPartCode windowPart;
   817             GetEventParameter(event, kEventParamWindowPartCode,
   836             GetEventParameter(event, kEventParamWindowPartCode,
   818                               typeWindowPartCode, 0, sizeof(windowPart), 0, &windowPart);
   837                               typeWindowPartCode, 0, sizeof(windowPart), 0, &windowPart);
   819             if(windowPart == inZoomIn && widget->isMaximized()) {
   838             if(windowPart == inZoomIn && widget->isMaximized()) {
  1030         if(send_to_app)
  1049         if(send_to_app)
  1031             return SendEventToApplication(event);
  1050             return SendEventToApplication(event);
  1032         handled_event = false;
  1051         handled_event = false;
  1033         break; }
  1052         break; }
  1034 
  1053 
  1035 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
       
  1036     case kEventClassGesture: {
  1054     case kEventClassGesture: {
  1037         // First, find the widget that was under
  1055         // First, find the widget that was under
  1038         // the mouse when the gesture happened:
  1056         // the mouse when the gesture happened:
  1039         HIPoint screenLocation;
  1057         HIPoint screenLocation;
  1040         if (GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0,
  1058         if (GetEventParameter(event, kEventParamMouseLocation, typeHIPoint, 0,
  1058             case kEventGestureEnded:
  1076             case kEventGestureEnded:
  1059                 qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
  1077                 qNGEvent.gestureType = QNativeGestureEvent::GestureEnd;
  1060                 break;
  1078                 break;
  1061             case kEventGestureRotate: {
  1079             case kEventGestureRotate: {
  1062                 CGFloat amount;
  1080                 CGFloat amount;
  1063                 if (GetEventParameter(event, kEventParamRotationAmount, typeCGFloat, 0,
  1081                 if (GetEventParameter(event, kEventParamRotationAmount, 'cgfl', 0,
  1064                             sizeof(amount), 0, &amount) != noErr) {
  1082                             sizeof(amount), 0, &amount) != noErr) {
  1065                     handled_event = false;
  1083                     handled_event = false;
  1066                     break;
  1084                     break;
  1067                 }
  1085                 }
  1068                 qNGEvent.gestureType = QNativeGestureEvent::Rotate;
  1086                 qNGEvent.gestureType = QNativeGestureEvent::Rotate;
  1085                 else if (swipeDirection.y == -1)
  1103                 else if (swipeDirection.y == -1)
  1086                     qNGEvent.angle = 270.0f;
  1104                     qNGEvent.angle = 270.0f;
  1087                 break; }
  1105                 break; }
  1088             case kEventGestureMagnify: {
  1106             case kEventGestureMagnify: {
  1089                 CGFloat amount;
  1107                 CGFloat amount;
  1090                 if (GetEventParameter(event, kEventParamMagnificationAmount, typeCGFloat, 0,
  1108                 if (GetEventParameter(event, kEventParamMagnificationAmount, 'cgfl', 0,
  1091                             sizeof(amount), 0, &amount) != noErr) {
  1109                             sizeof(amount), 0, &amount) != noErr) {
  1092                     handled_event = false;
  1110                     handled_event = false;
  1093                     break;
  1111                     break;
  1094                 }
  1112                 }
  1095                 qNGEvent.gestureType = QNativeGestureEvent::Zoom;
  1113                 qNGEvent.gestureType = QNativeGestureEvent::Zoom;
  1097                 break; }
  1115                 break; }
  1098         }
  1116         }
  1099 
  1117 
  1100         QApplication::sendSpontaneousEvent(widget, &qNGEvent);
  1118         QApplication::sendSpontaneousEvent(widget, &qNGEvent);
  1101     break; }
  1119     break; }
  1102 #endif // gestures
       
  1103 
  1120 
  1104     default:
  1121     default:
  1105         handled_event = false;
  1122         handled_event = false;
  1106     }
  1123     }
  1107     if(!handled_event) //let the event go through
  1124     if(!handled_event) //let the event go through
  2598         }
  2615         }
  2599         if(mac_mouse_grabber == this)
  2616         if(mac_mouse_grabber == this)
  2600             releaseMouse();
  2617             releaseMouse();
  2601         if(mac_keyboard_grabber == this)
  2618         if(mac_keyboard_grabber == this)
  2602             releaseKeyboard();
  2619             releaseKeyboard();
  2603         if(acceptDrops())
       
  2604             setAcceptDrops(false);
       
  2605 
  2620 
  2606         if(testAttribute(Qt::WA_ShowModal))          // just be sure we leave modal
  2621         if(testAttribute(Qt::WA_ShowModal))          // just be sure we leave modal
  2607             QApplicationPrivate::leaveModal(this);
  2622             QApplicationPrivate::leaveModal(this);
  2608         else if((windowType() == Qt::Popup))
  2623         else if((windowType() == Qt::Popup))
  2609             qApp->d_func()->closePopup(this);
  2624             qApp->d_func()->closePopup(this);
  2667                     // access the window later and get a crash (becasue our
  2682                     // access the window later and get a crash (becasue our
  2668                     // widget is dead). Work around this be having the drop
  2683                     // widget is dead). Work around this be having the drop
  2669                     // site disabled until it is part of the new hierarchy.
  2684                     // site disabled until it is part of the new hierarchy.
  2670                     bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
  2685                     bool oldRegistered = w->testAttribute(Qt::WA_DropSiteRegistered);
  2671                     w->setAttribute(Qt::WA_DropSiteRegistered, false);
  2686                     w->setAttribute(Qt::WA_DropSiteRegistered, false);
       
  2687                     [qt_mac_nativeview_for(w) retain];
       
  2688                     [qt_mac_nativeview_for(w) removeFromSuperview];
  2672                     [qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
  2689                     [qt_mac_nativeview_for(q) addSubview:qt_mac_nativeview_for(w)];
       
  2690                     [qt_mac_nativeview_for(w) release];
  2673                     w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
  2691                     w->setAttribute(Qt::WA_DropSiteRegistered, oldRegistered);
  2674 #endif
  2692 #endif
  2675                 }
  2693                 }
  2676             }
  2694             }
  2677         }
  2695         }
  2894 #ifndef QT_MAC_USE_COCOA
  2912 #ifndef QT_MAC_USE_COCOA
  2895     qt_mac_update_cursor();
  2913     qt_mac_update_cursor();
  2896 #else
  2914 #else
  2897      Q_Q(QWidget);
  2915      Q_Q(QWidget);
  2898     if (q->testAttribute(Qt::WA_WState_Created)) {
  2916     if (q->testAttribute(Qt::WA_WState_Created)) {
       
  2917         QMacCocoaAutoReleasePool pool;
  2899         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
  2918         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
  2900     }
  2919     }
  2901 #endif
  2920 #endif
  2902 }
  2921 }
  2903 
  2922 
  2906 #ifndef QT_MAC_USE_COCOA
  2925 #ifndef QT_MAC_USE_COCOA
  2907     qt_mac_update_cursor();
  2926     qt_mac_update_cursor();
  2908 #else
  2927 #else
  2909      Q_Q(QWidget);
  2928      Q_Q(QWidget);
  2910     if (q->testAttribute(Qt::WA_WState_Created)) {
  2929     if (q->testAttribute(Qt::WA_WState_Created)) {
       
  2930         QMacCocoaAutoReleasePool pool;
  2911         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
  2931         [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)];
  2912     }
  2932     }
  2913 #endif
  2933 #endif
  2914 }
  2934 }
  2915 
  2935 
  3013         if (previousIcon != 0)
  3033         if (previousIcon != 0)
  3014             ReleaseIconRef(previousIcon);
  3034             ReleaseIconRef(previousIcon);
  3015 #else
  3035 #else
  3016         QMacCocoaAutoReleasePool pool;
  3036         QMacCocoaAutoReleasePool pool;
  3017         NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
  3037         NSButton *iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
       
  3038         if (iconButton == nil) {
       
  3039             QCFString string(q->windowTitle());
       
  3040             const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
       
  3041             [qt_mac_window_for(q) setRepresentedURL:[NSURL fileURLWithPath:tmpString]];
       
  3042             iconButton = [qt_mac_window_for(q) standardWindowButton:NSWindowDocumentIconButton];
       
  3043         }
  3018         if (icon.isNull()) {
  3044         if (icon.isNull()) {
  3019             [iconButton setImage:nil];
  3045             [iconButton setImage:nil];
  3020         } else {
  3046         } else {
  3021             NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(*pm));
  3047             QPixmap scaled = pm->scaled(QSize(16,16), Qt::KeepAspectRatio, Qt::SmoothTransformation);
       
  3048             NSImage *image = static_cast<NSImage *>(qt_mac_create_nsimage(scaled));
  3022             [iconButton setImage:image];
  3049             [iconButton setImage:image];
  3023             [image release];
  3050             [image release];
  3024         }
  3051         }
  3025 #endif
  3052 #endif
  3026     }
  3053     }
  3046             mac_mouse_grabber->releaseMouse();
  3073             mac_mouse_grabber->releaseMouse();
  3047         mac_mouse_grabber=this;
  3074         mac_mouse_grabber=this;
  3048     }
  3075     }
  3049 }
  3076 }
  3050 
  3077 
       
  3078 #ifndef QT_NO_CURSOR
  3051 void QWidget::grabMouse(const QCursor &)
  3079 void QWidget::grabMouse(const QCursor &)
  3052 {
  3080 {
  3053     if(isVisible() && !qt_nograb()) {
  3081     if(isVisible() && !qt_nograb()) {
  3054         if(mac_mouse_grabber)
  3082         if(mac_mouse_grabber)
  3055             mac_mouse_grabber->releaseMouse();
  3083             mac_mouse_grabber->releaseMouse();
  3056         mac_mouse_grabber=this;
  3084         mac_mouse_grabber=this;
  3057     }
  3085     }
  3058 }
  3086 }
       
  3087 #endif
  3059 
  3088 
  3060 void QWidget::releaseMouse()
  3089 void QWidget::releaseMouse()
  3061 {
  3090 {
  3062     if(!qt_nograb() && mac_mouse_grabber == this)
  3091     if(!qt_nograb() && mac_mouse_grabber == this)
  3063         mac_mouse_grabber = 0;
  3092         mac_mouse_grabber = 0;
  3386             QWidget *w = 0;
  3415             QWidget *w = 0;
  3387             if(q->parentWidget())
  3416             if(q->parentWidget())
  3388                 w = q->parentWidget()->window();
  3417                 w = q->parentWidget()->window();
  3389             if(!w || (!w->isVisible() && !w->isMinimized())) {
  3418             if(!w || (!w->isVisible() && !w->isMinimized())) {
  3390 #ifndef QT_MAC_USE_COCOA
  3419 #ifndef QT_MAC_USE_COCOA
  3391                 for(WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
  3420                 for (WindowPtr wp = GetFrontWindowOfClass(kMovableModalWindowClass, true);
  3392                     wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
  3421                     wp; wp = GetNextWindowOfClass(wp, kMovableModalWindowClass, true)) {
  3393                     if((w = qt_mac_find_window(wp)))
  3422                     if((w = qt_mac_find_window(wp)))
  3394                         break;
  3423                         break;
       
  3424                 }
       
  3425                 if (!w){
       
  3426                     for (WindowPtr wp = GetFrontWindowOfClass(kDocumentWindowClass, true);
       
  3427                             wp; wp = GetNextWindowOfClass(wp, kDocumentWindowClass, true)) {
       
  3428                         if((w = qt_mac_find_window(wp)))
       
  3429                             break;
       
  3430                     }
  3395                 }
  3431                 }
  3396                 if (!w){
  3432                 if (!w){
  3397                     for(WindowPtr wp = GetFrontWindowOfClass(kSimpleWindowClass, true);
  3433                     for(WindowPtr wp = GetFrontWindowOfClass(kSimpleWindowClass, true);
  3398                         wp; wp = GetNextWindowOfClass(wp, kSimpleWindowClass, true)) {
  3434                         wp; wp = GetNextWindowOfClass(wp, kSimpleWindowClass, true)) {
  3399                         if((w = qt_mac_find_window(wp)))
  3435                         if((w = qt_mac_find_window(wp)))
  3467                 setGeometry(fullscreen);
  3503                 setGeometry(fullscreen);
  3468                 if(!qApp->desktop()->screenNumber(this))
  3504                 if(!qApp->desktop()->screenNumber(this))
  3469                     qt_mac_set_fullscreen_mode(true);
  3505                     qt_mac_set_fullscreen_mode(true);
  3470             } else {
  3506             } else {
  3471                 needShow = isVisible();
  3507                 needShow = isVisible();
       
  3508                 if(!qApp->desktop()->screenNumber(this))
       
  3509                     qt_mac_set_fullscreen_mode(false);
  3472                 setParent(parentWidget(), d->topData()->savedFlags);
  3510                 setParent(parentWidget(), d->topData()->savedFlags);
  3473                 setGeometry(d->topData()->normalGeometry);
  3511                 setGeometry(d->topData()->normalGeometry);
  3474                 if(!qApp->desktop()->screenNumber(this))
       
  3475                     qt_mac_set_fullscreen_mode(false);
       
  3476                 d->topData()->normalGeometry.setRect(0, 0, -1, -1);
  3512                 d->topData()->normalGeometry.setRect(0, 0, -1, -1);
  3477             }
  3513             }
  3478         }
  3514         }
  3479 
  3515 
  3480         d->createWinId();
  3516         d->createWinId();
  3572                 }
  3608                 }
  3573                 // Everything should be handled by Cocoa.
  3609                 // Everything should be handled by Cocoa.
  3574                 [window zoom:window];
  3610                 [window zoom:window];
  3575 #endif
  3611 #endif
  3576                 needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
  3612                 needSendStateChange = oldstate == windowState(); // Zoom didn't change flags.
  3577             } else if(oldstate & Qt::WindowMaximized) {
  3613             } else if(oldstate & Qt::WindowMaximized && !(oldstate & Qt::WindowFullScreen)) {
  3578 #ifndef QT_MAC_USE_COCOA
  3614 #ifndef QT_MAC_USE_COCOA
  3579                 Point idealSize;
  3615                 Point idealSize;
  3580                 ZoomWindowIdeal(window, inZoomIn, &idealSize);
  3616                 ZoomWindowIdeal(window, inZoomIn, &idealSize);
  3581 #else
  3617 #else
  3582                 [window zoom:window];
  3618                 [window zoom:window];
  3616         SetKeyboardFocus(qt_mac_window_for(q), qt_mac_nativeview_for(q), 1);
  3652         SetKeyboardFocus(qt_mac_window_for(q), qt_mac_nativeview_for(q), 1);
  3617 #endif
  3653 #endif
  3618     }
  3654     }
  3619 }
  3655 }
  3620 
  3656 
       
  3657 NSComparisonResult compareViews2Raise(id view1, id view2, void *context)
       
  3658 {
       
  3659     id topView = reinterpret_cast<id>(context);
       
  3660     if (view1 == topView)
       
  3661         return NSOrderedDescending;
       
  3662     if (view2 == topView)
       
  3663         return NSOrderedAscending;
       
  3664     return NSOrderedSame;
       
  3665 }
       
  3666 
  3621 void QWidgetPrivate::raise_sys()
  3667 void QWidgetPrivate::raise_sys()
  3622 {
  3668 {
  3623     Q_Q(QWidget);
  3669     Q_Q(QWidget);
  3624     if((q->windowType() == Qt::Desktop))
  3670     if((q->windowType() == Qt::Desktop))
  3625         return;
  3671         return;
  3626 
  3672 
  3627 #if QT_MAC_USE_COCOA
  3673 #if QT_MAC_USE_COCOA
  3628     QMacCocoaAutoReleasePool pool;
       
  3629     if (isRealWindow()) {
  3674     if (isRealWindow()) {
  3630         // Calling orderFront shows the window on Cocoa too.
  3675         // Calling orderFront shows the window on Cocoa too.
  3631         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
  3676         if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) {
  3632             [qt_mac_window_for(q) orderFront:qt_mac_window_for(q)];
  3677             [qt_mac_window_for(q) orderFront:qt_mac_window_for(q)];
  3633         }
  3678         }
  3635             ProcessSerialNumber psn;
  3680             ProcessSerialNumber psn;
  3636             GetCurrentProcess(&psn);
  3681             GetCurrentProcess(&psn);
  3637             SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
  3682             SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
  3638         }
  3683         }
  3639     } else {
  3684     } else {
  3640         // Cocoa doesn't really have an idea of Z-ordering, but you can
       
  3641         // fake it by changing the order of it. But beware, removing an
       
  3642         // NSView will also remove it as the first responder. So we re-set
       
  3643         // the first responder just in case:
       
  3644         NSView *view = qt_mac_nativeview_for(q);
  3685         NSView *view = qt_mac_nativeview_for(q);
  3645         NSView *parentView = [view superview];
  3686         NSView *parentView = [view superview];
  3646         NSResponder *firstResponder = [[view window] firstResponder];
  3687         [parentView sortSubviewsUsingFunction:compareViews2Raise context:reinterpret_cast<void *>(view)];
  3647         [view removeFromSuperview];
       
  3648         [parentView addSubview:view];
       
  3649         [[view window] makeFirstResponder:firstResponder];
       
  3650     }
  3688     }
  3651 #else
  3689 #else
  3652     if(q->isWindow()) {
  3690     if(q->isWindow()) {
  3653         //raise this window
  3691         //raise this window
  3654         BringToFront(qt_mac_window_for(q));
  3692         BringToFront(qt_mac_window_for(q));
  3662         qt_event_request_window_change(q);
  3700         qt_event_request_window_change(q);
  3663     }
  3701     }
  3664 #endif
  3702 #endif
  3665 }
  3703 }
  3666 
  3704 
       
  3705 NSComparisonResult compareViews2Lower(id view1, id view2, void *context)
       
  3706 {
       
  3707     id topView = reinterpret_cast<id>(context);
       
  3708     if (view1 == topView)
       
  3709         return NSOrderedAscending;
       
  3710     if (view2 == topView)
       
  3711         return NSOrderedDescending;
       
  3712     return NSOrderedSame;
       
  3713 }
       
  3714 
  3667 void QWidgetPrivate::lower_sys()
  3715 void QWidgetPrivate::lower_sys()
  3668 {
  3716 {
  3669     Q_Q(QWidget);
  3717     Q_Q(QWidget);
  3670     if((q->windowType() == Qt::Desktop))
  3718     if((q->windowType() == Qt::Desktop))
  3671         return;
  3719         return;
  3672 #ifdef QT_MAC_USE_COCOA
  3720 #ifdef QT_MAC_USE_COCOA
  3673     QMacCocoaAutoReleasePool pool;
       
  3674     if (isRealWindow()) {
  3721     if (isRealWindow()) {
  3675         OSWindowRef window = qt_mac_window_for(q);
  3722         OSWindowRef window = qt_mac_window_for(q);
  3676         [window orderBack:window];
  3723         [window orderBack:window];
  3677     } else {
  3724     } else {
  3678         // Cocoa doesn't really have an idea of Z-ordering, but you can
  3725         NSView *view = qt_mac_nativeview_for(q);
  3679         // fake it by changing the order of it. In this case
  3726         NSView *parentView = [view superview];
  3680         // we put the item at the beginning of the list, but that means
  3727         [parentView sortSubviewsUsingFunction:compareViews2Lower context:reinterpret_cast<void *>(view)];
  3681         // we must re-insert everything since we cannot modify the list directly.
       
  3682         NSView *myview = qt_mac_nativeview_for(q);
       
  3683         NSView *parentView = [myview superview];
       
  3684         NSArray *tmpViews = [parentView subviews];
       
  3685         NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
       
  3686         [subviews addObjectsFromArray:tmpViews];
       
  3687         NSResponder *firstResponder = [[myview window] firstResponder];
       
  3688         // Implicit assumption that myViewIndex is included in subviews, that's why I'm not checking
       
  3689         // myViewIndex.
       
  3690         NSUInteger index = 0;
       
  3691         NSUInteger myViewIndex = 0;
       
  3692         bool foundMyView = false;
       
  3693         for (NSView *subview in subviews) {
       
  3694             [subview removeFromSuperview];
       
  3695             if (subview == myview) {
       
  3696                 foundMyView = true;
       
  3697                 myViewIndex = index;
       
  3698             }
       
  3699             ++index;
       
  3700         }
       
  3701         [parentView addSubview:myview];
       
  3702         if (foundMyView)
       
  3703             [subviews removeObjectAtIndex:myViewIndex];
       
  3704         for (NSView *subview in subviews)
       
  3705             [parentView addSubview:subview];
       
  3706         [subviews release];
       
  3707         [[myview window] makeFirstResponder:firstResponder];
       
  3708     }
  3728     }
  3709 #else
  3729 #else
  3710     if(q->isWindow()) {
  3730     if(q->isWindow()) {
  3711         SendBehind(qt_mac_window_for(q), 0);
  3731         SendBehind(qt_mac_window_for(q), 0);
  3712     } else if(q->parentWidget()) {
  3732     } else if(q->parentWidget()) {
  3715         qt_event_request_window_change(q);
  3735         qt_event_request_window_change(q);
  3716     }
  3736     }
  3717 #endif
  3737 #endif
  3718 }
  3738 }
  3719 
  3739 
       
  3740 NSComparisonResult compareViews2StackUnder(id view1, id view2, void *context)
       
  3741 {
       
  3742     const QHash<NSView *, int> &viewOrder = *reinterpret_cast<QHash<NSView *, int> *>(context);
       
  3743     if (viewOrder[view1] < viewOrder[view2])
       
  3744         return NSOrderedAscending;
       
  3745     if (viewOrder[view1] > viewOrder[view2])
       
  3746         return NSOrderedDescending;
       
  3747     return NSOrderedSame;
       
  3748 }
       
  3749 
  3720 void QWidgetPrivate::stackUnder_sys(QWidget *w)
  3750 void QWidgetPrivate::stackUnder_sys(QWidget *w)
  3721 {
  3751 {
  3722     // stackUnder
  3752     // stackUnder
  3723     Q_Q(QWidget);
  3753     Q_Q(QWidget);
  3724     if(!w || q->isWindow() || (q->windowType() == Qt::Desktop))
  3754     if(!w || q->isWindow() || (q->windowType() == Qt::Desktop))
  3725         return;
  3755         return;
  3726 #ifdef QT_MAC_USE_COCOA
  3756 #ifdef QT_MAC_USE_COCOA
  3727     // Do the same trick as lower_sys() and put this widget before the widget passed in.
  3757     // Do the same trick as lower_sys() and put this widget before the widget passed in.
  3728     QMacCocoaAutoReleasePool pool;
  3758     NSView *myView = qt_mac_nativeview_for(q);
  3729     NSView *myview = qt_mac_nativeview_for(q);
       
  3730     NSView *wView = qt_mac_nativeview_for(w);
  3759     NSView *wView = qt_mac_nativeview_for(w);
  3731     NSView *parentView = [myview superview];
  3760 
  3732     NSArray *tmpViews = [parentView subviews];
  3761     QHash<NSView *, int> viewOrder;
  3733     NSMutableArray *subviews = [[NSMutableArray alloc] initWithCapacity:[tmpViews count]];
  3762     NSView *parentView = [myView superview];
  3734     [subviews addObjectsFromArray:tmpViews];
  3763     NSArray *subviews = [parentView subviews];
  3735     // Implicit assumption that myViewIndex and wViewIndex is included in subviews,
  3764     NSUInteger index = 1;
  3736     // that's why I'm not checking myViewIndex.
  3765     // make a hash of view->zorderindex and make sure z-value is always odd,
  3737     NSUInteger index = 0;
  3766     // so that when we modify the order we create a new (even) z-value which
  3738     NSUInteger myViewIndex = 0;
  3767     // will not interfere with others.
  3739     NSUInteger wViewIndex = 0;
       
  3740     for (NSView *subview in subviews) {
  3768     for (NSView *subview in subviews) {
  3741         [subview removeFromSuperview];
  3769         viewOrder.insert(subview, index * 2);
  3742         if (subview == myview)
       
  3743             myViewIndex = index;
       
  3744         else if (subview == wView)
       
  3745             wViewIndex = index;
       
  3746         ++index;
  3770         ++index;
  3747     }
  3771     }
  3748 
  3772     viewOrder[myView] = viewOrder[wView] - 1;
  3749     index = 0;
  3773 
  3750     for (NSView *subview in subviews) {
  3774     [parentView sortSubviewsUsingFunction:compareViews2StackUnder context:reinterpret_cast<void *>(&viewOrder)];
  3751         if (index == myViewIndex)
       
  3752             continue;
       
  3753         if (index == wViewIndex)
       
  3754             [parentView addSubview:myview];
       
  3755         [parentView addSubview:subview];
       
  3756         ++index;
       
  3757     }
       
  3758     [subviews release];
       
  3759 #else
  3775 #else
  3760     QWidget *p = q->parentWidget();
  3776     QWidget *p = q->parentWidget();
  3761     if(!p || p != w->parentWidget())
  3777     if(!p || p != w->parentWidget())
  3762         return;
  3778         return;
  3763     invalidateBuffer(q->rect());
  3779     invalidateBuffer(q->rect());
  3767 }
  3783 }
  3768 
  3784 
  3769 /*
  3785 /*
  3770     Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
  3786     Modifies the bounds for a widgets backing HIView during moves and resizes. Also updates the
  3771     widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
  3787     widget, either by scrolling its contents or repainting, depending on the WA_StaticContents
  3772     and QWidgetPrivate::isOpaque flags.
  3788     flag
  3773 */
  3789 */
  3774 static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
  3790 static void qt_mac_update_widget_posisiton(QWidget *q, QRect oldRect, QRect newRect)
  3775 {
  3791 {
  3776 #ifndef QT_MAC_USE_COCOA
  3792 #ifndef QT_MAC_USE_COCOA
  3777     HIRect bounds = CGRectMake(newRect.x(), newRect.y(),
  3793     HIRect bounds = CGRectMake(newRect.x(), newRect.y(),
  3784 //    qDebug() << oldRect << newRect << isMove << isResize << q->testAttribute(Qt::WA_OpaquePaintEvent) << q->testAttribute(Qt::WA_StaticContents);
  3800 //    qDebug() << oldRect << newRect << isMove << isResize << q->testAttribute(Qt::WA_OpaquePaintEvent) << q->testAttribute(Qt::WA_StaticContents);
  3785     QWidgetPrivate *qd = qt_widget_private(q);
  3801     QWidgetPrivate *qd = qt_widget_private(q);
  3786 
  3802 
  3787     // Perform a normal (complete repaint) update in some cases:
  3803     // Perform a normal (complete repaint) update in some cases:
  3788     if (
  3804     if (
  3789         // move-by-scroll requires QWidgetPrivate::isOpaque set
  3805         // always repaint on move.
  3790         (isMove && q->testAttribute(Qt::WA_OpaquePaintEvent) == false) ||
  3806         (isMove) ||
  3791 
  3807 
  3792         // limited update on resize requires WA_StaticContents.
  3808         // limited update on resize requires WA_StaticContents.
  3793         (isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
  3809         (isResize && q->testAttribute(Qt::WA_StaticContents) == false) ||
  3794 
  3810 
  3795         // one of the rects are invalid
  3811         // one of the rects are invalid