Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Has anyone worked around iOS safe zone margins, like with iPhone X?
Forum Updated to NodeBB v4.3 + New Features

Has anyone worked around iOS safe zone margins, like with iPhone X?

Scheduled Pinned Locked Moved Solved Mobile and Embedded
11 Posts 5 Posters 4.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    patrickkidd
    wrote on last edited by
    #1

    UIKit in iOS 11 has new features for laying out your main view without overlapping built-in device controls and bezels, for example on the iPhone X. Has anyone played out their widgets according to these? I have some strange behavior with my QGraphicsView and QWidget overlays, which should be full screen (see screenshot):

    0_1560500680588_Untitled 2.png

    0_1560500778275_Untitled 3.png

    0_1560500753761_Untitled 4.png

    I suppose I would like to know what the margins are and also how to prevent my view from automatically being restricted to the safe zone. Some elements need to be drawn differently, and some simply need to go outside the safe zones to the actual edges of the screen.

    Here are two links describing how to handle this in swift:

    1. iOS Safe Area

    2. How to Handle Safe Area Insets, Notch & Display Cutout for iPhone X, iPad X and Android P – 2019

    https://alaskafamilysystems.com/

    J.HilkJ 1 Reply Last reply
    0
    • Pradeep P NP Offline
      Pradeep P NP Offline
      Pradeep P N
      wrote on last edited by Pradeep P N
      #2

      Hi @patrickkidd

      These links might help you.

      • iPhone X - The Screen notch & bottom bar.

      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;
              }
          }
      
      • Qt World Summit 2018 Conference App.

      All the best.

      Pradeep Nimbalkar.
      Upvote the answer(s) that helped you to solve the issue...
      Keep code clean.

      1 Reply Last reply
      1
      • P patrickkidd

        UIKit in iOS 11 has new features for laying out your main view without overlapping built-in device controls and bezels, for example on the iPhone X. Has anyone played out their widgets according to these? I have some strange behavior with my QGraphicsView and QWidget overlays, which should be full screen (see screenshot):

        0_1560500680588_Untitled 2.png

        0_1560500778275_Untitled 3.png

        0_1560500753761_Untitled 4.png

        I suppose I would like to know what the margins are and also how to prevent my view from automatically being restricted to the safe zone. Some elements need to be drawn differently, and some simply need to go outside the safe zones to the actual edges of the screen.

        Here are two links describing how to handle this in swift:

        1. iOS Safe Area

        2. How to Handle Safe Area Insets, Notch & Display Cutout for iPhone X, iPad X and Android P – 2019

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        @patrickkidd

        this workaround works

        https://bugreports.qt.io/browse/QTBUG-64574

        but make sure, to delay the reading after a orientation change

        https://bugreports.qt.io/browse/QTBUG-76234


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        3
        • Shrinidhi UpadhyayaS Offline
          Shrinidhi UpadhyayaS Offline
          Shrinidhi Upadhyaya
          wrote on last edited by Shrinidhi Upadhyaya
          #4

          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);
            

          Shrinidhi Upadhyaya.
          Upvote the answer(s) that helped you to solve the issue.

          1 Reply Last reply
          2
          • P Offline
            P Offline
            patrickkidd
            wrote on last edited by
            #5

            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.

            https://alaskafamilysystems.com/

            J.HilkJ 1 Reply Last reply
            0
            • P patrickkidd

              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.

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #6

              @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

              0_1560502580696_IMG_0515.PNG


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              P 1 Reply Last reply
              2
              • J.HilkJ J.Hilk

                @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

                0_1560502580696_IMG_0515.PNG

                P Offline
                P Offline
                patrickkidd
                wrote on last edited by
                #7

                @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
                

                https://alaskafamilysystems.com/

                J.HilkJ 1 Reply Last reply
                0
                • P patrickkidd

                  @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
                  
                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by J.Hilk
                  #8

                  @patrickkidd
                  Sadly I have next to no experience with the python bindings

                  but 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)


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  P 1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @patrickkidd
                    Sadly I have next to no experience with the python bindings

                    but 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)

                    P Offline
                    P Offline
                    patrickkidd
                    wrote on last edited by patrickkidd
                    #9

                    @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 call showFullScreen().

                    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:

                    @Shrinidhi-Upadhyaya

                    QPlatformWindow *platformWindow = static_cast<QPlatformWindow *>(window->handle());
                    QMargins margins = platformWindow->safeAreaMargins();
                    

                    Any idea what the include is for QPlatformWindow?

                    https://alaskafamilysystems.com/

                    J.HilkJ 1 Reply Last reply
                    0
                    • P patrickkidd

                      @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 call showFullScreen().

                      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:

                      @Shrinidhi-Upadhyaya

                      QPlatformWindow *platformWindow = static_cast<QPlatformWindow *>(window->handle());
                      QMargins margins = platformWindow->safeAreaMargins();
                      

                      Any idea what the include is for QPlatformWindow?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @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>


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      0
                      • L Offline
                        L Offline
                        Luc4
                        wrote on last edited by
                        #11

                        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.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved