diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 6e1f00eebe..34ec142d90 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -252,6 +252,7 @@ public: // for QNSView QList m_childWindows; Qt::WindowFlags m_windowFlags; + bool m_effectivelyMaximized; Qt::WindowState m_synchedWindowState; Qt::WindowModality m_windowModality; QPointer m_activePopupWindow; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index c7fba4eef0..f25aea67fa 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -352,6 +352,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_contentViewIsToBeEmbedded(false) , m_parentCocoaWindow(0) , m_isNSWindowChild(false) + , m_effectivelyMaximized(false) , m_synchedWindowState(Qt::WindowActive) , m_windowModality(Qt::NonModal) , m_windowUnderMouse(false) @@ -1436,7 +1437,6 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) { if (!m_nsWindow) return; - // if content view width or height is 0 then the window animations will crash so // do nothing except set the new state NSRect contentRect = [contentView() frame]; @@ -1446,9 +1446,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) return; } - if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) { - [m_nsWindow performZoom : m_nsWindow]; // toggles - } + Qt::WindowState predictedState = newState; if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) { if (newState & Qt::WindowMinimized) { @@ -1458,12 +1456,26 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) } } + if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) { + if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) { + [m_nsWindow performZoom : m_nsWindow]; // toggles + m_effectivelyMaximized = !m_effectivelyMaximized; + } else if (!(newState & Qt::WindowMaximized)) { + // it would be nice to change the target geometry that toggleFullScreen will animate toward + // but there is no known way, so the maximized state is not possible at this time + predictedState = static_cast(static_cast(newState) | Qt::WindowMaximized); + m_effectivelyMaximized = true; + } + } + 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]; } } @@ -1490,8 +1502,12 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState) } } +#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG + qDebug() << "QCocoaWindow::syncWindowState" << newState << "actual" << predictedState << "was" << m_synchedWindowState << "effectively maximized" << m_effectivelyMaximized; +#endif + // New state is now the current synched state - m_synchedWindowState = newState; + m_synchedWindowState = predictedState; } bool QCocoaWindow::setWindowModified(bool modified) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 47081ab890..1197aa9148 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -281,6 +281,12 @@ static QTouchDevice *touchDevice = 0; - (void)notifyWindowStateChanged:(Qt::WindowState)newState { + // If the window was maximized, then fullscreen, then tried to go directly to "normal" state, + // this notification will say that it is "normal", but it will still look maximized, and + // if you called performZoom it would actually take it back to "normal". + // So we should say that it is maximized because it actually is. + if (newState == Qt::WindowNoState && m_platformWindow->m_effectivelyMaximized) + newState = Qt::WindowMaximized; QWindowSystemInterface::handleWindowStateChanged(m_window, newState); // We want to read the window state back from the window, // but the event we just sent may be asynchronous. @@ -346,6 +352,8 @@ static QTouchDevice *touchDevice = 0; - (void)notifyWindowWillZoom:(BOOL)willZoom { Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState; + if (!willZoom) + m_platformWindow->m_effectivelyMaximized = false; [self notifyWindowStateChanged:newState]; }