diff options
author | Tor Arne Vestbø <[email protected]> | 2024-11-11 22:55:36 +0100 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2024-11-25 16:41:08 +0100 |
commit | 90fe9874d22f0c4b809a3e493766ef852c72cc39 (patch) | |
tree | 8f75873ca766f3608ff8d00e94fbd303213c383d | |
parent | 7707ab210fa0f1a478639e2bd05669697bb828e8 (diff) |
Introduce Qt::ExpandedClientAreaHint
The hint requests that the window's client area is expanded to fill
parts of the window that might be (partially) covered by, or
conflicting with, other (system) UI elements, such as the window's
title bar, resize controls, or a status bar.
The safe area margins of the window will reflect any areas that
may have conflicting UI elements.
If the client area is expanded into the area previously covered
by the frame margins, the frame margins are reduced accordingly,
as the frame margins represent the non-client-area parts of the
window.
This new flag replaces, and overlaps in value, with the existing
Qt::MaximizeUsingFullscreenGeometryHint, as the latter was added
to cover this exact use-case for mobile platforms. Now that we
have the use-case on desktop platforms as well we want to use a
more generic flag, so the old flag has been deprecated.
Semantically, on iOS and Android, without the flags set, the
window can be seen as being maximized to take up the entire
screen, but with a frameMargin() that reflects the system
status bar and resize controls. That's not technically how
we implement things right now, but this is an implementation
detail that will be changed in a follow-up.
On macOS the flag maps to NSWindowStyleMaskFullSizeContentView,
and on Windows we have an implementation cooking that uses the
DwmExtendFrameIntoClientArea function.
Task-number: QTBUG-127634
Change-Id: I9b6863b1550ccc056c16bce235d87b26a7d239b9
Reviewed-by: Assam Boudjelthia <[email protected]>
Reviewed-by: Wladimir Leuschner <[email protected]>
-rw-r--r-- | src/corelib/global/qnamespace.h | 6 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 15 | ||||
-rw-r--r-- | src/gui/kernel/qplatformscreen.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/android/qandroidplatformwindow.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoawindow.mm | 5 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosviewcontroller.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 2 | ||||
-rw-r--r-- | tests/auto/corelib/platform/android/tst_android.cpp | 2 | ||||
-rw-r--r-- | tests/manual/windowflags/controls.cpp | 7 | ||||
-rw-r--r-- | tests/manual/windowflags/controls.h | 1 | ||||
-rw-r--r-- | tests/manual/windowflags/previewwindow.cpp | 4 |
12 files changed, 33 insertions, 21 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 2f454a442df..7f8c70f78e9 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -235,7 +235,11 @@ namespace Qt { WindowTransparentForInput = 0x00080000, WindowOverridesSystemGestures = 0x00100000, WindowDoesNotAcceptFocus = 0x00200000, - MaximizeUsingFullscreenGeometryHint = 0x00400000, +#if QT_DEPRECATED_SINCE(6, 9) + MaximizeUsingFullscreenGeometryHint Q_DECL_ENUMERATOR_DEPRECATED_X( + "Use Qt::ExpandedClientAreaHint instead") = 0x00400000, +#endif + ExpandedClientAreaHint = 0x00400000, CustomizeWindowHint = 0x02000000, WindowStaysOnBottomHint = 0x04000000, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 38f5db2a207..5a0abb22624 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2345,14 +2345,13 @@ \value WindowDoesNotAcceptFocus Informs the window system that this window should not receive the input focus. - \value MaximizeUsingFullscreenGeometryHint Informs the window system that when - maximizing the window it should use as much of the available screen geometry - as possible, including areas that may be covered by system UI such as status - bars or application launchers. This may result in the window being placed - under these system UIs, but does not guarantee it, depending on whether or - not the platform supports it. When the flag is enabled the user is responsible - for taking QScreen::availableGeometry() into account, so that any UI elements - in the application that require user interaction are not covered by system UI. + \value MaximizeUsingFullscreenGeometryHint Deprecated alias for Qt::ExpandedClientAreaHint + + \value [since 6.9] ExpandedClientAreaHint Requests that the window's client area is + expanded to areas where it might be obscured by, or conflicting with other UI + elements, such as the window's titlebar controls or other system UIs. The + window's \l{QWindow::safeAreaMargins()}{safe area margins} will reflect any + areas that may have conflicting UI elements. \value WindowType_Mask A mask for extracting the window type part of the window flags. diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index 0369a0b12a5..6497486ed14 100644 --- a/src/gui/kernel/qplatformscreen.cpp +++ b/src/gui/kernel/qplatformscreen.cpp @@ -338,7 +338,7 @@ void QPlatformScreen::resizeMaximizedWindows() // QWindow and QScreen sizes. if (supportsMaximizeUsingFullscreen && w->windowState() & Qt::WindowMaximized - && w->flags() & Qt::MaximizeUsingFullscreenGeometryHint) { + && w->flags() & Qt::ExpandedClientAreaHint) { w->handle()->setGeometry(newNativeGeometry); } else if (w->windowState() & Qt::WindowMaximized || w->geometry() == oldAvailableGeometry) { w->handle()->setGeometry(newNativeAvailableGeometry); diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 5559a897596..698d025503e 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -124,7 +124,7 @@ void QAndroidPlatformWindow::raise() QMargins QAndroidPlatformWindow::safeAreaMargins() const { - if ((m_windowState & Qt::WindowMaximized) && (window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint)) { + if ((m_windowState & Qt::WindowMaximized) && (window()->flags() & Qt::ExpandedClientAreaHint)) { QRect availableGeometry = platformScreen()->availableGeometry(); return QMargins(availableGeometry.left(), availableGeometry.top(), availableGeometry.right(), availableGeometry.bottom()); @@ -166,7 +166,7 @@ void QAndroidPlatformWindow::setVisible(bool visible) if (window()->isTopLevel()) { updateSystemUiVisibility(); if ((m_windowState & Qt::WindowFullScreen) - || ((m_windowState & Qt::WindowMaximized) && (window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint))) { + || ((m_windowState & Qt::WindowMaximized) && (window()->flags() & Qt::ExpandedClientAreaHint))) { setGeometry(platformScreen()->geometry()); } else if (m_windowState & Qt::WindowMaximized) { setGeometry(platformScreen()->availableGeometry()); @@ -259,7 +259,7 @@ void QAndroidPlatformWindow::updateSystemUiVisibility() if (!isNonRegularWindow) { if (m_windowState & Qt::WindowFullScreen) QtAndroid::setSystemUiVisibility(QtAndroid::SYSTEM_UI_VISIBILITY_FULLSCREEN); - else if (flags & Qt::MaximizeUsingFullscreenGeometryHint) + else if (flags & Qt::ExpandedClientAreaHint) QtAndroid::setSystemUiVisibility(QtAndroid::SYSTEM_UI_VISIBILITY_TRANSLUCENT); else QtAndroid::setSystemUiVisibility(QtAndroid::SYSTEM_UI_VISIBILITY_NORMAL); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5d78d66485b..68c4ccce959 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -627,11 +627,12 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (m_drawContentBorderGradient) styleMask |= NSWindowStyleMaskTexturedBackground; + if (flags & Qt::ExpandedClientAreaHint) + styleMask |= NSWindowStyleMaskFullSizeContentView; + // Don't wipe existing states if (m_view.window.styleMask & NSWindowStyleMaskFullScreen) styleMask |= NSWindowStyleMaskFullScreen; - if (m_view.window.styleMask & NSWindowStyleMaskFullSizeContentView) - styleMask |= NSWindowStyleMaskFullSizeContentView; return styleMask; } diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 436d1e7bedf..4e3766c38a3 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -430,7 +430,7 @@ // -------------- Status bar style and visbility --------------- UIStatusBarStyle oldStatusBarStyle = self.preferredStatusBarStyle; - if (focusWindow->flags() & Qt::MaximizeUsingFullscreenGeometryHint) + if (focusWindow->flags() & Qt::ExpandedClientAreaHint) self.preferredStatusBarStyle = UIStatusBarStyleDefault; else self.preferredStatusBarStyle = UIStatusBarStyleLightContent; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index b11d9992529..3e2b6b0102a 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -268,7 +268,7 @@ void QIOSWindow::setWindowState(Qt::WindowStates state) QRect maximizedGeometry = fullscreenGeometry; #if !defined(Q_OS_VISIONOS) - if (!(window()->flags() & Qt::MaximizeUsingFullscreenGeometryHint)) { + if (!(window()->flags() & Qt::ExpandedClientAreaHint)) { // If the safe area margins reflect the screen's outer edges, // then reduce the maximized geometry accordingly. Otherwise // leave it as is, and assume the client will take the safe diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 4d351fe893d..dc1abe70cc4 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1303,7 +1303,7 @@ void QWidgetPrivate::create() #if defined(QT_PLATFORM_UIKIT) if (q->testAttribute(Qt::WA_ContentsMarginsRespectsSafeArea)) - flags |= Qt::MaximizeUsingFullscreenGeometryHint; + flags |= Qt::ExpandedClientAreaHint; #endif if (q->testAttribute(Qt::WA_ShowWithoutActivating)) diff --git a/tests/auto/corelib/platform/android/tst_android.cpp b/tests/auto/corelib/platform/android/tst_android.cpp index f4b685fb860..94f0d1a8fff 100644 --- a/tests/auto/corelib/platform/android/tst_android.cpp +++ b/tests/auto/corelib/platform/android/tst_android.cpp @@ -284,7 +284,7 @@ void tst_Android::testFullScreenDimensions() { // Translucent // available geometry == full display size (system bars visible but drawable under) - widget.setWindowFlags(widget.windowFlags() | Qt::MaximizeUsingFullscreenGeometryHint); + widget.setWindowFlags(widget.windowFlags() | Qt::ExpandedClientAreaHint); widget.show(); QCoreApplication::processEvents(); QTRY_COMPARE(screen->availableGeometry().width(), realSize.getField<jint>("x")); diff --git a/tests/manual/windowflags/controls.cpp b/tests/manual/windowflags/controls.cpp index 9262eb8bc60..dd96eea5069 100644 --- a/tests/manual/windowflags/controls.cpp +++ b/tests/manual/windowflags/controls.cpp @@ -32,6 +32,7 @@ HintControl::HintControl(QWidget *parent) , customizeWindowGroup(new QGroupBox(tr("Customize window title bar controls"))) , transparentForInputCheckBox(new QCheckBox(tr("Transparent for input"))) , noDropShadowCheckBox(new QCheckBox(tr("No drop shadow"))) + , expandedClientAreaCheckBox(new QCheckBox(tr("Expanded client area"))) { connect(msWindowsFixedSizeDialogCheckBox, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); connect(x11BypassWindowManagerCheckBox, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); @@ -49,6 +50,8 @@ HintControl::HintControl(QWidget *parent) connect(customizeWindowGroup, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); connect(transparentForInputCheckBox, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); connect(noDropShadowCheckBox, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); + connect(expandedClientAreaCheckBox, SIGNAL(clicked()), this, SLOT(slotCheckBoxChanged())); + auto *layout = new QHBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(ControlLayoutMargin, ControlLayoutMargin, @@ -66,6 +69,7 @@ HintControl::HintControl(QWidget *parent) basicHintsLayout->addWidget(transparentForInputCheckBox); basicHintsLayout->addWidget(msWindowsFixedSizeDialogCheckBox); basicHintsLayout->addWidget(x11BypassWindowManagerCheckBox); + basicHintsLayout->addWidget(expandedClientAreaCheckBox); layout->addLayout(basicHintsLayout); customizeWindowGroup->setCheckable(true); @@ -122,6 +126,8 @@ Qt::WindowFlags HintControl::hints() const flags |= Qt::WindowTransparentForInput; if (noDropShadowCheckBox->isChecked()) flags |= Qt::NoDropShadowWindowHint; + if (expandedClientAreaCheckBox->isChecked()) + flags |= Qt::ExpandedClientAreaHint; return flags; } @@ -143,6 +149,7 @@ void HintControl::setHints(Qt::WindowFlags flags) customizeWindowGroup->setChecked(flags & Qt::CustomizeWindowHint); transparentForInputCheckBox->setChecked(flags & Qt::WindowTransparentForInput); noDropShadowCheckBox->setChecked(flags & Qt::NoDropShadowWindowHint); + expandedClientAreaCheckBox->setChecked(flags & Qt::ExpandedClientAreaHint); } void HintControl::slotCheckBoxChanged() diff --git a/tests/manual/windowflags/controls.h b/tests/manual/windowflags/controls.h index 8435a5a4f58..04b5f48adda 100644 --- a/tests/manual/windowflags/controls.h +++ b/tests/manual/windowflags/controls.h @@ -47,6 +47,7 @@ private: QGroupBox *customizeWindowGroup; QCheckBox *transparentForInputCheckBox; QCheckBox *noDropShadowCheckBox; + QCheckBox *expandedClientAreaCheckBox; }; // Control for the Qt::WindowState enum, optional with a "visible" QCheckbox diff --git a/tests/manual/windowflags/previewwindow.cpp b/tests/manual/windowflags/previewwindow.cpp index 3164745281f..0771e54cd13 100644 --- a/tests/manual/windowflags/previewwindow.cpp +++ b/tests/manual/windowflags/previewwindow.cpp @@ -99,8 +99,8 @@ static void formatWindowFlags(QTextStream &str, Qt::WindowFlags flags) str << "\n| Qt::WindowOverridesSystemGestures"; if (flags & Qt::WindowDoesNotAcceptFocus) str << "\n| Qt::WindowDoesNotAcceptFocus"; - if (flags & Qt::MaximizeUsingFullscreenGeometryHint) - str << "\n| Qt::MaximizeUsingFullscreenGeometryHint"; + if (flags & Qt::ExpandedClientAreaHint) + str << "\n| Qt::ExpandedClientAreaHint"; if (flags & Qt::NoDropShadowWindowHint) str << "\n| Qt::NoDropShadowWindowHint"; } |