diff options
author | Tor Arne Vestbø <[email protected]> | 2025-02-20 14:11:30 +0100 |
---|---|---|
committer | Tor Arne Vestbø <[email protected]> | 2025-03-18 15:43:28 +0100 |
commit | 16081f414d9cfd752c0e6152fbfa386bdbade7a4 (patch) | |
tree | 8069e5d51f8c2dfa09ca0c76f4d95f816e2d9ee6 | |
parent | fde232c855d59009503fe6dbaadd10346ab0830a (diff) |
Only default top levels to Qt::WA_ContentsMarginsRespectsSafeArea
When safe area margins are in play, such as on iOS and Android, or on
macOS in 6.8 and above when the NSWindowStyleMaskFullSizeContentView
styleMask has been set (manually or via Qt::ExpandedClientAreaHint in
6.9), then widgets with a layout will by default try to avoid the non-
safe areas.
This worked well as a safe default, ensuring widget applications filled
the entire window with its background color, while constraining the
layout of children to the safe area.
However, for those that explicitly want to put content in the non-safe
areas, by setting Qt::WA_ContentsMarginsRespectsSafeArea to false, the
story was a bit cumbersome, as we set the attribute to true by default
for all widgets. Meaning, any child widget put into the non-safe areas
that itself had a layout (such as a push button) would also need the
Qt::WA_ContentsMarginsRespectsSafeArea = false override.
We now default Qt::WA_ContentsMarginsRespectsSafeArea to true only for
top level widgets on creation, and leave it up to the user to manage the
attribute for the other use-cases, as they then need to be in full control.
[ChangeLog][QtWidgets] The Qt::WA_ContentsMarginsRespectsSafeArea attribute
is no longer set by default for non-top-level widgets. Top level widgets
still default to Qt::WA_ContentsMarginsRespectsSafeArea=true, so children
are laid out in the safe areas, but overriding the attribute for the top
level now allows placing widgets in the non-safe areas without also setting
the Qt::WA_ContentsMarginsRespectsSafeArea attribute to false for every
descendant widget that overlaps the non-safe area.
Task-number: QTBUG-133215
Pick-to: 6.9 6.8
Change-Id: I7b1d420d730ee896ec2fb61aadacd94473dc9681
Reviewed-by: Axel Spoerl <[email protected]>
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 24 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 04774da1b0f..eaf6d00942e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -103,6 +103,9 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2) extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp +static void setAttribute_internal(Qt::WidgetAttribute attribute, + bool on, QWidgetData *data, QWidgetPrivate *d); + QWidgetPrivate::QWidgetPrivate(decltype(QObjectPrivateVersion) version) : QObjectPrivate(version) , focus_next(nullptr) @@ -968,7 +971,6 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() adjustQuitOnCloseAttribute(); - q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea); q->setAttribute(Qt::WA_WState_Hidden); //give potential windows a bigger "pre-initial" size; create() will give them a new size later @@ -1195,6 +1197,15 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) if (QApplicationPrivate::testAttribute(Qt::AA_NativeWindows)) setAttribute(Qt::WA_NativeWindow); + if (isWindow()) { + // Make top levels automatically respect safe areas by default + auto *topExtra = d->maybeTopData(); + if (!topExtra || !topExtra->explicitContentsMarginsRespectsSafeArea) { + setAttribute_internal(Qt::WA_ContentsMarginsRespectsSafeArea, + true, data, d); + } + } + d->updateIsOpaque(); setAttribute(Qt::WA_WState_Created); // set created flag @@ -1613,6 +1624,7 @@ void QWidgetPrivate::createTLExtra() x->posIncludesFrame = 0; x->sizeAdjusted = false; x->embedded = 0; + x->explicitContentsMarginsRespectsSafeArea = 0; x->window = nullptr; x->initialScreen = nullptr; @@ -11359,10 +11371,18 @@ void QWidgetPrivate::macUpdateSizeAttribute() */ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) { + Q_D(QWidget); + + if (attribute == Qt::WA_ContentsMarginsRespectsSafeArea) { + if (isWindow()) { + auto *topExtra = d->topData(); + topExtra->explicitContentsMarginsRespectsSafeArea = true; + } + } + if (testAttribute(attribute) == on) return; - Q_D(QWidget); static_assert(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8), "QWidget::setAttribute(WidgetAttribute, bool): " "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute"); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 09b520a5746..9bd55d6e2de 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -119,6 +119,7 @@ struct QTLWExtra { uint posIncludesFrame : 1; uint sizeAdjusted : 1; uint embedded : 1; + uint explicitContentsMarginsRespectsSafeArea: 1; }; struct QWExtra { |