diff options
authorTor Arne Vestbø <>2018-05-18 01:08:21 +0200
committerTor Arne Vestbø <>2018-05-29 10:54:21 +0000
commitdd8e73504edbf71808d6585b7a08daddcdcbf18e (patch)
parent0b1342f374308f9d820153f694e75334b39780f6 (diff)
macOS: Respect maximum window size when computing zoomed state geometry
AppKit will normally compute this automatically based on the contentMaxSize property of the NSWindow, which we set correctly based on the window's maximum size, but since we ignore the frame proposed by AppKit (due to not working for borderless windows), we need to take the maximum size into account ourselves. We follow the lead of QCocoaWindow::propagateSizeHints(), and interpret the window's maximum size as referring to the client area size, not including the frame geometry, but AppKit expects the NSWindow's frame, so we need to manually add the frame. In addition, AppKit expects the frame in the native coordinate system, so we need to map to it. This was an existing bug, that never manifested before taking the maximum size into account. Task-number: QTBUG-67376 Change-Id: Id4cf6ff5640610f809472e5b1d591b4ec17df602 Reviewed-by: Morten Johan Sørvig <>
1 files changed, 17 insertions, 7 deletions
diff --git a/src/plugins/platforms/cocoa/ b/src/plugins/platforms/cocoa/
index 6e5623d679..15c141448d 100644
--- a/src/plugins/platforms/cocoa/
+++ b/src/plugins/platforms/cocoa/
@@ -39,6 +39,7 @@
#include "qnswindowdelegate.h"
#include "qcocoahelpers.h"
+#include "qcocoascreen.h"
#include <QDebug>
#include <qpa/qplatformscreen.h>
@@ -69,15 +70,24 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*"));
Overridden to ensure that the zoomed state always results in a maximized
window, which would otherwise not be the case for borderless windows.
-- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame
+- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)proposedFrame
- Q_UNUSED(newFrame);
- // We explicitly go through the QScreen API here instead of just using
- // window.screen.visibleFrame directly, as that ensures we have the same
- // behavior for both use-cases/APIs.
+ Q_UNUSED(proposedFrame);
Q_ASSERT(window == m_cocoaWindow->nativeWindow());
- return NSRectFromCGRect(m_cocoaWindow->screen()->availableGeometry().toCGRect());
+ // We compute the maximized state based on the maximum size, and
+ // the current position of the window. This may result in the window
+ // geometry falling outside of the current screen's available geometry,
+ // e.g. when there is not maximize size set, but this is okey, AppKit
+ // will then shift and possibly clip the geometry for us.
+ const QWindow *w = m_cocoaWindow->window();
+ QRect maximizedRect = QRect(w->framePosition(), w->maximumSize());
+ // QWindow::maximumSize() refers to the client size,
+ // but AppKit expects the full frame size.
+ maximizedRect.adjust(0, 0, 0, w->frameMargins().top());
+ return QCocoaScreen::mapToNative(maximizedRect);
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu