summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <[email protected]>2025-02-20 14:11:30 +0100
committerTor Arne Vestbø <[email protected]>2025-03-18 15:43:28 +0100
commit16081f414d9cfd752c0e6152fbfa386bdbade7a4 (patch)
tree8069e5d51f8c2dfa09ca0c76f4d95f816e2d9ee6
parentfde232c855d59009503fe6dbaadd10346ab0830a (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.cpp24
-rw-r--r--src/widgets/kernel/qwidget_p.h1
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 {