Has anyone worked around iOS safe zone margins, like with iPhone X?
-
Hi @patrickkidd
These links might help you.
Sample code for QML.
ApplicationWindow { id: root flags: Qt.Window | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | (Qt.platform.os === "ios" ? Qt.MaximizeUsingFullscreenGeometryHint : 0) }
// This function is to support the iPhone X Series notch issue - status bar size is 44pt function toolbarMarginSupport() { if (isIPad || (Qt.platform.os === "ios" && isPortraitMode)) { switch(windowScreen.height * windowScreen.devicePixelRatio) { case 1624: // iPhone_XR (Qt Provided Physical Resolution); case 1792: // iPhone_XR; case 2436: // iPhone_X_XS; case 2688: // iPhone_XS_MAX; return 44; default: return 20; } } else { return 0; } } function isIPhoneXSeries() { if (isIPad || (Qt.platform.os === "ios" && isPortraitMode)) { switch(windowScreen.height * windowScreen.devicePixelRatio) { case 1624: // iPhone_XR (Qt Provided Physical Resolution); case 1792: // iPhone_XR; case 2436: // iPhone_X_XS; case 2688: // iPhone_XS_MAX; return true; default: return false; } } else { return false; } }
All the best.
-
this workaround works
https://bugreports.qt.io/browse/QTBUG-64574
but make sure, to delay the reading after a orientation change
-
Hi @patrickkidd ,
-
Here is a sample code,which will return you the notch values:-
QPlatformWindow *platformWindow = static_cast<QPlatformWindow *>(window->handle());
QMargins margins = platformWindow->safeAreaMargins();
int topMargin = 0;
int bottomMorgin = 0;
int leftMargin = 0;
int rightMargin = 0;
topMargin = margins.top();
rightMargin = margins.right();
bottomMorgin = margins.bottom();
leftMargin = margins.left(); -
You need also need to set this:-
window.setFlag(Qt::MaximizeUsingFullscreenGeometryHint, true);
-
-
All very helpful and interesting responses.
Looks like
Qt.MaximizeUsingFullscreenGeometryHint
doesn't have an effect. I am using a QMainWindow for my top-level widget with no other flags set. -
@patrickkidd
if you're working with QWidgtes, and your TopMost Widget is a QMainWindow. Then simply set a Layout to the central widget.By default the layout respects the safe margins
-
@J.Hilk Can you paste a code snippet? When you say "set a Layout to the central widget," do you mean 1) layout the central widget as in my .ui file:
self.centralWidget = QtWidgets.QWidget(MainWindow) self.centralWidget.setObjectName("centralWidget") self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralWidget)
or 2) lay out the QMainWindow and add the central widget:
self.ui.centralWidget = QOpenGLWidget(self) self.setCentralWidget(self.ui.centralWidget) Layout = QVBoxLayout(self) Layout.setContentsMargins(0, 0, 0, 0) Layout.addWidget(self.ui.centralWidget)
When I run #2 it gives the following warning and the app runs on Mac but only shows a white screen (within the safe zone) on iOS. There is no layout explicitly added so it must be implicit in QMainWindow:
kernel/qlayout.cpp(148): QLayout: Attempting to add QLayout "" to MainWindow "", which already has a layout
-
@patrickkidd
Sadly I have next to no experience with the python bindingsbut here's a simple c++ example (everything in main)
#include <QApplication> #include <QVBoxLayout> #include <QDebug> #include <QWidget> #include <QPainter> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr) : QWidget(parent) { setStyleSheet("background-color:transparent;"); } ~Widget() = default; void setGridDistance(int distance) { m_GridDistance = distance; update(); } protected: void paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter p(this); p.setPen(QPen(Qt::white,3)); for(int i(0); i < width(); i += m_GridDistance){ p.drawLine(i,0,i,height()); } for(int i(0); i < height(); i += m_GridDistance){ p.drawLine(0,i,width(),i); } } int m_GridDistance = 20; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget *w = new QWidget(); w->setStyleSheet("background-color:red;"); w->setWindowFlag(Qt::MaximizeUsingFullscreenGeometryHint,true); w->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea,false); w->showFullScreen(); Widget *wChild = new Widget(w); wChild->setStyleSheet("background-color:transparent;"); //!Does not work { QVBoxLayout *layout = new QVBoxLayout(w); layout->setSizeConstraint(QLayout::SetNoConstraint); layout->setMargin(0); layout->addWidget(wChild); } //!Works { // wChild->resize(w->size()); // wChild->show(); } return a.exec(); }
the normal QWidget spans the whole screen, the wChild widget only inside the save margins, due to the layout
Ignore the extra part, commended , parts IIRC that is for an other issue x)
-
@J.Hilk said in Has anyone worked around iOS safe zone margins, like with iPhone X?:
w->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea,false);
It looks like this was the line to do it. The
Qt::MaximizeUsingFullscreenGeometryHint
didn't have any effect. I didn't callshowFullScreen()
.So now it will just be a matter of getting the margins from QPlatformWindow using the example from the following if I can only figure out the include for QPlatformWindow. <qpa/qplatformwindow.h> doesn't seem to work:
QPlatformWindow *platformWindow = static_cast<QPlatformWindow *>(window->handle()); QMargins margins = platformWindow->safeAreaMargins();
Any idea what the include is for QPlatformWindow?
-
@patrickkidd said in Has anyone worked around iOS safe zone margins, like with iPhone X?:
Any idea what the include is for QPlatformWindow?
inside your *.pro file you need to include this module:
QT += gui-private
then this include is available:
#include <QtGui/qpa/qplatformwindow.h>
-
I didn't like too much the idea of using the private module, so this is how I implemented it: https://github.com/carlonluca/lqtutils/blob/master/lqtutils_ui.h#L55. Uses Objective-C++ on iOS and JNI on Android. More info: https://bugfreeblog.duckdns.org/2023/01/qt-qml-cutouts.html.