Expanded Client Areas and Safe Areas
March 27, 2025 by Tor Arne Vestbø | Comments
A staple of modern application design on desktop and mobile is that the content is front and center — with application and system UI elements seamlessly blending into the content in non-intrusive ways. We're now going to look at two new features of Qt 6.9 that help achieve this: expanded client areas, and safe areas.
Expanded client areas
Let's say we're building an application for dog lovers, showcasing our favorite photos. A minimal application might look something like this:
import QtQuick
Window {
visible: true
width: 800; height: 600
Image {
anchors.fill: parent
source: "https://placedog.net/800/600?r"
fillMode: Image.PreserveAspectCrop
}
}
Which would give us the following on macOS and iOS:
So far so good, our dog is mostly front and center. But there are a few UI elements competing for the attention, namely the window titlebar and controls on macOS; and the clock, WiFI and battery status on iOS. We can do better!
By adding the Qt.ExpandedClientAreaHint window flag, we can ask that the window's client area is expanded into areas that would normally be reserved for system UI elements.
Window {
flags: Qt.ExpandedClientAreaHint | Qt.NoTitleBarBackgroundHint
// ...
}
To hide the titlebar on macOS, we've also added the Qt.NoTitleBarBackgroundHint, which together gives us:
. .
Much better! The content now stretches edge to edge, giving full focus to the golden fur of our friend.
Safe Areas
Now, with expanded client areas comes expanded responsibilities. Our application is now fighting for the same screen real-estate as system UI and controls, and the system UI will typically win. This means we need to take care not place important content in the areas where the system UI may potentially overlap it, as this would prevent the user from seeing or interacting with our content.
For example, we might want to introduce functionality to interact with our dog while we're away:
Window {
// ...
Item {
anchors {
left: parent.left; right: parent.right; top: parent.top
margins: 10
}
Text {
text: "🎾 Throw Ball"; color: "white"; font.pointSize: 18
anchors. left: parent.left
}
Text {
text: "Give Bone 🦴"; color: "white"; font.pointSize: 18
anchors. right: parent.right
}
}
}
But this would clash with the system UI on both macOS and iOS:
To handle this, we use the new SafeArea attached property, which tells us how much we need to inset our content to stay away from the "non-safe" areas of the window:
anchors {
left: parent.left; right: parent.right; top: parent.top
topMargin: 10 + parent.SafeArea.margins.top
leftMargin: 10 + parent.SafeArea.margins.left
rightMargin: 10 + parent.SafeArea.margins.right
}
This safely puts our buttons below the titlebar on macOS:
And away from the status bar on iOS:
As you may have noticed, we also accounted for landscape mode, by including the left and right safe area margins:
Qt Quick Controls
So far our examples have used a plain Qt Quick Window, but a more realistic example will likely use ApplicationWindow from Qt Quick Controls, which comes with some additional bells and whistles for safe area handling.
If the Qt.ExpandedClientAreaHint window flag is set we will automatically extend the window's background to cover the entire window, while keeping content added to the content item within the safe areas of the window.
For the window's header, footer, and menu bar you are generally responsible for handling safe areas yourself. But, we've taught the built-in ToolBar and MenuBar types a few tricks, so the following code will automatically extend the toolbar's background to the top of the screen, while keeping the toolbar content in the safe area:
ApplicationWindow {
visible: true
width: 500; height: 700
flags: Qt.ExpandedClientAreaHint | Qt.NoTitleBarBackgroundHint
header: ToolBar {
background: Rectangle {
gradient: Gradient.PremiumDark
opacity: 0.7
}
RowLayout {
anchors.fill: parent
Text {
text: "🎾 Throw Ball"; color: "white"; font.pointSize: 18
Layout.margins: 10
}
Text {
text: "Give Bone 🦴"; color: "white"; font.pointSize: 18
Layout.alignment: Qt.AlignRight; Layout.margins: 10
}
}
}
// ...
}
Finally, if you have content in your application window that you knowingly want to extend into the non-safe areas of the window, you can do so by overriding the padding properties of the window, for example:
ApplicationWindow {
// ...
topPadding: 0
ListView {
id: listView
anchors.fill: parent
model: 10
delegate: Image {
required property int index
width: listView.width; height: 250
source: "https://placedog.net/500/250?id=" + (index + 1)
}
topMargin: SafeArea.margins.top
onTopMarginChanged: {
// Keep content position stable
if (!dragging && atYBeginning)
contentY = -topMargin
}
}
}
Which extends the list view underneath the toolbar and into the non-safe areas, but accounts for the safe area margins by making sure the list view's origin is placed directly below the toolbar.
This works because the toolbar itself reports additional safe area margins for any part of the toolbar that extends beyond the safe-area margins reported by the system, and these additional margins are taken into account when the ListView queries for the safe area margins. In effect the list view is agnostic to where the safe area margins are coming from.
You can use this technique to build container components that reflect the non-safe areas of the container to its children — letting the children decide if and how to respect the safe area margins in their layout —instead of putting explicit constraints on how the children are laid out.
Looking ahead
With the changes in 6.9 we have hopefully taken a good step towards enabling these UI paradigms in Qt applications.
The features are available and supported on macOS, Windows, iOS, visionOS, and Android, and we're looking to add support for the rest of our supported platforms.
.
The plan is also, once the dust settles, to automatically enable Qt.ExpandedClientAreaHint on some platforms, such as Android and iOS.
Please test and let us know of any issues you find, or if your use-case is not covered by the existing APIs.
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.8 Now!
Download the latest release here: www.qt.io/download.
Qt 6.8 release focuses on technology trends like spatial computing & XR, complex data visualization in 2D & 3D, and ARM-based development for desktop.
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.