Getting Android and iOS safe areas in Qt/QML


Many devices nowadays come with a notch at the top of the screen. You can clearly avoid drawing where cutouts are placed and ask the system to create a window that does not extend on those elements.

For aesthetic reasons, you may want, instead, to extend your app on the entire screen, and handle the situation inside your app. To do this, you’ll have to know where the safe area is, and avoid creating relevant elements outside of it. Doing this in Android and iOS is not difficult.

The same can be done in Qt/QML, but apparently an immediate call does not currently exist in the Qt SDK.

As I have to do this pretty frequently, I wrote the code for in in my collection of extras for Qt: https://github.com/carlonluca/lqtutils.

How to Get the Values

You can get the margins by simply calling these four methods:

Q_INVOKABLE static double safeAreaBottomInset();
Q_INVOKABLE static double safeAreaTopInset();
Q_INVOKABLE static double safeAreaRightInset();
Q_INVOKABLE static double safeAreaLeftInset();

The result is the number of pixels of margin in logical coordinates. These functions are always 0 for any desktop OS. You can call these functions both from C++ and from QML.

To get these functions, simply include lqtutils (https://github.com/carlonluca/lqtutils) as a dependency of your project, and include the header lqtutils_ui.h.

As an example, you can refer to this demo app: https://github.com/carlonluca/Fall/blob/master/main.qml#L218.

NOTE: if you also handle different orientations, remember to call those functions again to re-evaluate the margins every time the orientation changes.

How it Works

There are two implementations of those two functions. For iOS, Objective-C++ is used to request the value. For Android, JNI is used to query the values using the regular Android SDK.

You can find the code here to know more:

How to Draw in Fullscreen

If you want to draw below display cutouts with a QQuickView you can use these flags:

view.setFlag(Qt::MaximizeUsingFullscreenGeometryHint, true);
view.setFlag(Qt::Window, true);
view.show();

or you can set the same values in QML. This demo app shows the result:

Example of demo Qt application drawing content over cutout margins but still preventing interactive content from being hidden.

Leave a Reply

Your email address will not be published. Required fields are marked *