diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoawindow.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 142 |
1 files changed, 48 insertions, 94 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 3366e5bc3c..6656212457 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -107,26 +107,6 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow) } } - -@interface NSWindow (CocoaWindowCategory) -- (NSRect) legacyConvertRectFromScreen:(NSRect) rect; -@end - -@implementation NSWindow (CocoaWindowCategory) -- (NSRect) legacyConvertRectFromScreen:(NSRect) rect -{ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - return [self convertRectFromScreen: rect]; - } -#endif - NSRect r = rect; - r.origin = [self convertScreenToBase:rect.origin]; - return r; -} -@end - - @implementation QNSWindowHelper @synthesize window = _window; @@ -197,7 +177,7 @@ static void selectNextKeyWindow(NSWindow *currentKeyWindow) if (pw && pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { NSPoint loc = [theEvent locationInWindow]; - NSRect windowFrame = [self.window legacyConvertRectFromScreen:[self.window frame]]; + NSRect windowFrame = [self.window convertRectFromScreen:[self.window frame]]; NSRect contentFrame = [[self.window contentView] frame]; if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO)) @@ -401,6 +381,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_windowUnderMouse(false) , m_inConstructor(true) , m_inSetVisible(false) + , m_inSetGeometry(false) #ifndef QT_NO_OPENGL , m_glContext(0) #endif @@ -432,19 +413,16 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) } else { m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this]; m_contentView = m_qtView; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 // Enable high-dpi OpenGL for retina displays. Enabling has the side // effect that Cocoa will start calling glViewport(0, 0, width, height), // overriding any glViewport calls in application code. This is usually not a // problem, except if the appilcation wants to have a "custom" viewport. // (like the hellogl example) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 - && tlw->supportsOpenGL()) { + if (tlw->supportsOpenGL()) { BOOL enable = qt_mac_resolveOption(YES, tlw, "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); [m_contentView setWantsBestResolutionOpenGLSurface:enable]; } -#endif BOOL enable = qt_mac_resolveOption(NO, tlw, "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER"); [m_contentView setWantsLayer:enable]; @@ -493,6 +471,8 @@ QSurfaceFormat QCocoaWindow::format() const void QCocoaWindow::setGeometry(const QRect &rectIn) { + QBoolBlocker inSetGeometry(m_inSetGeometry, true); + QRect rect = rectIn; // This means it is a call from QWindow::setFramePosition() and // the coordinates include the frame (size is still the contents rectangle). @@ -516,7 +496,8 @@ QRect QCocoaWindow::geometry() const // of view. Embedded QWindows get global (screen) geometry. if (m_contentViewIsEmbedded) { NSPoint windowPoint = [m_contentView convertPoint:NSMakePoint(0, 0) toView:nil]; - NSPoint screenPoint = [[m_contentView window] convertBaseToScreen:windowPoint]; // ### use convertRectToScreen after 10.6 removal + NSRect screenRect = [[m_contentView window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)]; + NSPoint screenPoint = screenRect.origin; QPoint position = qt_mac_flipPoint(screenPoint).toPoint(); QSize size = qt_mac_toQRect([m_contentView bounds]).size(); return QRect(position, size); @@ -681,11 +662,7 @@ void QCocoaWindow::setVisible(bool visible) // Since this isn't a native popup, the window manager doesn't close the popup when you click outside NSUInteger parentStyleMask = [parentCocoaWindow->m_nsWindow styleMask]; if ((m_resizableTransientParent = (parentStyleMask & NSResizableWindowMask)) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 - && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask) -#endif - ) + && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)) [parentCocoaWindow->m_nsWindow setStyleMask:parentStyleMask & ~NSResizableWindowMask]; } @@ -784,11 +761,7 @@ void QCocoaWindow::setVisible(bool visible) if (parentCocoaWindow && window()->type() == Qt::Popup) { parentCocoaWindow->m_activePopupWindow = 0; if (m_resizableTransientParent -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - && QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7 - && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask) -#endif - ) + && !([parentCocoaWindow->m_nsWindow styleMask] & NSFullScreenWindowMask)) // QTBUG-30266: a window should not be resizable while a transient popup is open [parentCocoaWindow->m_nsWindow setStyleMask:[parentCocoaWindow->m_nsWindow styleMask] | NSResizableWindowMask]; } @@ -903,19 +876,15 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) setWindowTitle(window()->title()); } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - Qt::WindowType type = window()->type(); - if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) { - NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior]; - if (flags & Qt::WindowFullscreenButtonHint) - behavior |= NSWindowCollectionBehaviorFullScreenPrimary; - else - behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; - [m_nsWindow setCollectionBehavior:behavior]; - } + Qt::WindowType type = window()->type(); + if ((type & Qt::Popup) != Qt::Popup && (type & Qt::Dialog) != Qt::Dialog) { + NSWindowCollectionBehavior behavior = [m_nsWindow collectionBehavior]; + if (flags & Qt::WindowFullscreenButtonHint) + behavior |= NSWindowCollectionBehaviorFullScreenPrimary; + else + behavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; + [m_nsWindow setCollectionBehavior:behavior]; } -#endif setWindowZoomButton(flags); } @@ -1340,13 +1309,9 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow) m_nsWindow.hasShadow = NO; m_nsWindow.level = NSNormalWindowLevel; NSWindowCollectionBehavior collectionBehavior = - NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary; - m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone; - } -#endif + NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle + | NSWindowCollectionBehaviorFullScreenAuxiliary; + m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone; m_nsWindow.collectionBehavior = collectionBehavior; setCocoaGeometry(window()->geometry()); @@ -1438,17 +1403,17 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() if ((type & Qt::Popup) == Qt::Popup) [window setHasShadow:YES]; - [window setHidesOnDeactivate:(type & Qt::Tool) == Qt::Tool]; + // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set. + QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow"); + bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) && + !(showWithoutActivating.isValid() && showWithoutActivating.toBool()); + [window setHidesOnDeactivate: shouldHideOnDeactivate]; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - // Make popup winows show on the same desktop as the parent full-screen window. - [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; + // Make popup windows show on the same desktop as the parent full-screen window. + [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; + if ((type & Qt::Popup) == Qt::Popup) + [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow]; - if ((type & Qt::Popup) == Qt::Popup) - [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow]; - } -#endif createdWindow = window; } else { QNSWindow *window; @@ -1458,10 +1423,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow() createdWindow = window; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if ([createdWindow respondsToSelector:@selector(setRestorable:)]) [createdWindow setRestorable: NO]; -#endif NSInteger level = windowLevel(flags); [createdWindow setLevel:level]; @@ -1562,18 +1525,11 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) } if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) { - bool fakeFullScreen = true; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - if (window()->flags() & Qt::WindowFullscreenButtonHint) { - fakeFullScreen = false; - if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen) - predictedState = Qt::WindowMaximized; - [m_nsWindow toggleFullScreen : m_nsWindow]; - } - } -#endif - if (fakeFullScreen) { + if (window()->flags() & Qt::WindowFullscreenButtonHint) { + if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen) + predictedState = Qt::WindowMaximized; + [m_nsWindow toggleFullScreen : m_nsWindow]; + } else { if (newState & Qt::WindowFullScreen) { QScreen *screen = window()->screen(); if (screen) { @@ -1747,20 +1703,13 @@ bool QCocoaWindow::testContentBorderAreaPosition(int position) const qreal QCocoaWindow::devicePixelRatio() const { -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) { - // The documented way to observe the relationship between device-independent - // and device pixels is to use one for the convertToBacking functions. Other - // methods such as [NSWindow backingScaleFacor] might not give the correct - // result, for example if setWantsBestResolutionOpenGLSurface is not set or - // or ignored by the OpenGL driver. - NSSize backingSize = [m_contentView convertSizeToBacking:NSMakeSize(1.0, 1.0)]; - return backingSize.height; - } else -#endif - { - return 1.0; - } + // The documented way to observe the relationship between device-independent + // and device pixels is to use one for the convertToBacking functions. Other + // methods such as [NSWindow backingScaleFacor] might not give the correct + // result, for example if setWantsBestResolutionOpenGLSurface is not set or + // or ignored by the OpenGL driver. + NSSize backingSize = [m_contentView convertSizeToBacking:NSMakeSize(1.0, 1.0)]; + return backingSize.height; } // Returns whether the window can be expose, which it can @@ -1808,10 +1757,15 @@ void QCocoaWindow::updateExposedGeometry() if (!m_geometryUpdateExposeAllowed) return; + // Do not send incorrect exposes in case the window is not even visible yet. + // We might get here as a result of a resize() from QWidget's show(), for instance. + if (!window()->isVisible()) + return; + if (!isWindowExposable()) return; - if (m_exposedGeometry == geometry() && m_exposedDevicePixelRatio == devicePixelRatio()) + if (m_exposedGeometry.size() == geometry().size() && m_exposedDevicePixelRatio == devicePixelRatio()) return; m_isExposed = true; |