diff -r 41300fa6a67c -r f7bc934e204c src/gui/kernel/qwidget_mac.mm --- a/src/gui/kernel/qwidget_mac.mm Tue Feb 02 00:43:10 2010 +0200 +++ b/src/gui/kernel/qwidget_mac.mm Wed Mar 31 11:06:36 2010 +0300 @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -110,6 +110,7 @@ #include "qevent_p.h" #include "qdnd_p.h" #include +#include "qmainwindow.h" QT_BEGIN_NAMESPACE @@ -151,6 +152,7 @@ static OSWindowRef qt_root_win = 0; QWidget *mac_mouse_grabber = 0; QWidget *mac_keyboard_grabber = 0; +extern QPointer qt_button_down; //qapplication_mac.cpp #ifndef QT_MAC_USE_COCOA #ifdef QT_NAMESPACE @@ -403,7 +405,7 @@ return; qt_mac_app_fullscreen = b; if (b) { - SetSystemUIMode(kUIModeAllSuppressed, 0); + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); } else { SetSystemUIMode(kUIModeNormal, 0); } @@ -564,6 +566,25 @@ } #endif +#ifdef QT_MAC_USE_COCOA +void qt_mac_set_needs_display(QWidget *widget, QRegion region) +{ + NSView *theNSView = qt_mac_nativeview_for(widget); + if (region.isEmpty()) { + [theNSView setNeedsDisplay:YES]; + return; + } + + QVector rects = region.rects(); + for (int i = 0; i qt_button_down; //qapplication_mac.cpp qt_button_down = 0; } else if(ekind == kEventWindowCollapsed) { if (!widget->isMinimized()) { @@ -874,7 +894,6 @@ //we send a hide to be like X11/Windows QEvent e(QEvent::Hide); QApplication::sendSpontaneousEvent(widget, &e); - extern QPointer qt_button_down; //qapplication_mac.cpp qt_button_down = 0; } else if(ekind == kEventWindowToolbarSwitchMode) { macSendToolbarChangeEvent(widget); @@ -1248,6 +1267,11 @@ if (widget->isVisible() && widget->updatesEnabled()) { //process the actual paint event. if(widget->testAttribute(Qt::WA_WState_InPaintEvent)) qWarning("QWidget::repaint: Recursive repaint detected"); + if (widget->isWindow() && !widget->d_func()->isOpaque + && !widget->testAttribute(Qt::WA_MacBrushedMetal)) { + QRect qrgnRect = qrgn.boundingRect(); + CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height())); + } QPoint redirectionOffset(0, 0); QWidget *tl = widget->window(); @@ -1298,13 +1322,6 @@ widget->d_func()->restoreRedirected(); } - if (widget->isWindow() && !widget->d_func()->isOpaque - && !widget->testAttribute(Qt::WA_MacBrushedMetal)) { - QRect qrgnRect = qrgn.boundingRect(); - CGContextClearRect(cg, CGRectMake(qrgnRect.x(), qrgnRect.y(), qrgnRect.width(), qrgnRect.height())); - } - - if(!HIObjectIsOfClass((HIObjectRef)hiview, kObjectQWidget)) CallNextEventHandler(er, event); @@ -1501,7 +1518,6 @@ if (widget) { qt_event_request_window_change(widget); if (!HIViewIsVisible(HIViewRef(widget->winId()))) { - extern QPointer qt_button_down; //qapplication_mac.cpp if (widget == qt_button_down) qt_button_down = 0; } @@ -1510,7 +1526,6 @@ break; } case kEventClassMouse: { bool send_to_app = false; - extern QPointer qt_button_down; //qapplication_mac.cpp if(qt_button_down) send_to_app = true; if(send_to_app) { @@ -1721,6 +1736,15 @@ void QWidgetPrivate::determineWindowClass() { Q_Q(QWidget); +#if !defined(QT_NO_MAINWINDOW) && !defined(QT_NO_TOOLBAR) + // Make sure that QMainWindow has the MacWindowToolBarButtonHint when the + // unifiedTitleAndToolBarOnMac property is ON. This is to avoid reentry of + // setParent() triggered by the QToolBar::event(QEvent::ParentChange). + QMainWindow *mainWindow = qobject_cast(q); + if (mainWindow && mainWindow->unifiedTitleAndToolBarOnMac()) { + data.window_flags |= Qt::MacWindowToolBarButtonHint; + } +#endif #ifndef QT_MAC_USE_COCOA // ### COCOA:Interleave these better! @@ -2743,7 +2767,9 @@ } if (wasWindow) { oldToolbar = [oldWindow toolbar]; + [oldToolbar retain]; oldToolbarVisible = [oldToolbar isVisible]; + [oldWindow setToolbar:nil]; } #endif } @@ -2787,6 +2813,7 @@ if (oldToolbar && !(f & Qt::FramelessWindowHint)) { OSWindowRef newWindow = qt_mac_window_for(q); [newWindow setToolbar:oldToolbar]; + [oldToolbar release]; [oldToolbar setVisible:oldToolbarVisible]; } #endif @@ -3375,7 +3402,6 @@ Q_Q(QWidget); if((q->windowType() == Qt::Desktop)) //you can't hide the desktop! return; - QMacCocoaAutoReleasePool pool; if(q->isWindow()) { OSWindowRef window = qt_mac_window_for(q); @@ -3401,6 +3427,38 @@ ShowHide(window, false); #else [window orderOut:window]; + // Unfortunately it is not as easy as just hiding the window, we need + // to find out if we were in full screen mode. If we were and this is + // the last window in full screen mode then we need to unset the full screen + // mode. If this is not the last visible window in full screen mode then we + // don't change the full screen mode. + if(q->isFullScreen()) + { + bool keepFullScreen = false; + QWidgetList windowList = qApp->topLevelWidgets(); + int windowCount = windowList.count(); + for(int i = 0; i < windowCount; i++) + { + QWidget *w = windowList[i]; + // If it is the same window, we don't need to check :-) + if(q == w) + continue; + // If they are not visible or if they are minimized then + // we just ignore them. + if(!w->isVisible() || w->isMinimized()) + continue; + // Is it full screen? + // Notice that if there is one window in full screen mode then we + // cannot switch the full screen mode off, therefore we just abort. + if(w->isFullScreen()) { + keepFullScreen = true; + break; + } + } + // No windows in full screen mode, so let just unset that flag. + if(!keepFullScreen) + qt_mac_set_fullscreen_mode(false); + } #endif toggleDrawers(false); #ifndef QT_MAC_USE_COCOA @@ -3465,6 +3523,8 @@ if (!QWidget::mouseGrabber()){ QWidget *enterWidget = QApplication::widgetAt(QCursor::pos()); + if (enterWidget && enterWidget->data->in_destructor) + enterWidget = 0; QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover); qt_mouseover = enterWidget; } @@ -3671,6 +3731,7 @@ return; #if QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; if (isRealWindow()) { // Calling orderFront shows the window on Cocoa too. if (!q->testAttribute(Qt::WA_DontShowOnScreen) && q->isVisible()) { @@ -4408,8 +4469,20 @@ } } + // ### Scroll the dirty regions as well, the following is not correct. + QRegion displayRegion = r.isNull() ? dirtyOnWidget : (dirtyOnWidget & r); + const QVector &rects = dirtyOnWidget.rects(); + const QVector::const_iterator end = rects.end(); + QVector::const_iterator it = rects.begin(); + while (it != end) { + const QRect rect = *it; + const NSRect dirtyRect = NSMakeRect(rect.x() + dx, rect.y() + dy, + rect.width(), rect.height()); + [view setNeedsDisplayInRect:dirtyRect]; + ++it; + } + NSSize deltaSize = NSMakeSize(dx, dy); - [view translateRectsNeedingDisplayInRect:scrollRect by:deltaSize]; [view scrollRect:scrollRect by:deltaSize]; [view setNeedsDisplayInRect:deltaXRect]; [view setNeedsDisplayInRect:deltaYRect]; @@ -4493,10 +4566,14 @@ void QWidgetPrivate::deleteTLSysExtra() { #ifndef QT_MAC_USE_COCOA - if(extra->topextra->group) { + if (extra->topextra->group) { qt_mac_release_window_group(extra->topextra->group); extra->topextra->group = 0; } + if (extra->topextra->windowIcon) { + ReleaseIconRef(extra->topextra->windowIcon); + extra->topextra->windowIcon = 0; + } #endif } @@ -4605,8 +4682,10 @@ if (!q->testAttribute(Qt::WA_WState_Created) || !extra) return; - if (extra->hasMask && extra->maskBits.size() != q->size()) { - extra->maskBits = QImage(q->size(), QImage::Format_Mono); + if (extra->hasMask) { + if(extra->maskBits.size() != q->size()) { + extra->maskBits = QImage(q->size(), QImage::Format_Mono); + } extra->maskBits.fill(QColor(Qt::color1).rgba()); extra->maskBits.setNumColors(2); extra->maskBits.setColor(0, QColor(Qt::color0).rgba());