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()) { |
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 } |
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(); |
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()); |