Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-122799

Provide a modernized and coherent story for switching between portrait and landscape views

    XMLWordPrintable

Details

    Description

      (screenshots below taken with Qt 6.7.0 beta3)

      The Boot2Qt docs correctly states that "it might be desirable to change the default view orientation" [1]. An example use-case is be to create an HMI that is displayed on a rotatable screen, running on a device with no window manager.

      Let's have a look at how we might implement this.

       

      Solution #1: Let the QPA layer handle screen rotation

      According to vhilshei, this is the preferred way to proceed. "You would usually have an OS where the screen's rotation is provided by the window manager, and the OS makes sure that "up is up".... [otherwise] you have to provide some device-wide configuration option and implement the correct frame buffer-to-video-memory mapping in the QPA layer (e.g. a custom EGL/FS integration or similar). And then again your application doesn't have to rotate." [2]

       

      What works?
      Desktop and mobile platforms. The QPA plugin receives orientation information from the OS and updates QScreen::orientation() accordingly. The OS also rotates everything on the screen, so indeed the application doesn't have to do much.

       

      What doesn't?
      Embedded Linux. Our EGL/FS plugin assumes that "there's a single application that owns the entire screen.... The applications runs an HMI that has been designed for a specific display configuration, with well-known dimensions. Rotating things at runtime goes beyond the design of what we provide as an out of the box QPA implementation." [3] This means the users' best bet is to implement a custom QPA plugin, which is quite a hurdle.

      The QT_QPA_EGLFS_ROTATION variable works for widgets which are painted onto an intermediate buffer, but it has no effect on hardware-accelerated content like Qt Quick [4]. The EGL/FS documentation even suggests doing it in the Application layer, which takes us to Solution #2.

       

      Solution #2: Rotate the root/container Item in QML

      • The docs for EGL/FS says, "Qt Quick applications can apply transformations in their QML scene" [4]
      • The Boot2Qt docs showcases the technique of applying Item.rotation = 90 to the container Item [1]
      • vhilshei mentioned that the same can be done to Window.contentItem: "To rotate the window content, change the rotation of the contentItem of the window." [5]

       

      What works?
      The standard Item tree under the root/container all rotate as expected. Anchors, layouts, absolute positioning are all OK.

       

      What doesn't?
      Popups (including Drawers, ComboBox drop-downs, Menus, etc.). They do calculations based on the window's unrotated geometry, which is expected at first glance [6]... but then they stubbornly resist our attempts to force a non-default geometry (QTBUG-122771)

       

      Solution #3: Let the Wayland compositor handle screen rotation

      OK, so neither the QPA layer nor the Application layer are feasible right now. There is another layer in-between these that could do it: "On an embedded system where Qt owns the screen, [rotation should be done in] the QPA layer (or, if a Qt Wayland compositor is involved, that compositor)" [7]

       

      What works?
      Individual apps (Wayland clients) all rotate as expected. Yay!

       

      What doesn't?
      The Wayland server itself: The contents of WaylandOutput.window still suffer from the same issues that plague Solution #2.

       

      Applying solutions to Qt Application Manager

      Qt Application Manager ("AppMan") is built on top of the Qt Wayland Compositor. It lets users implement a "System UI" ("SysUI") which is displayed in the Wayland server's output window (an internal QQuickView), and implement "Applications" which are Wayland clients.

      The above describes "multi-process" mode. AppMan also supports "single-process" mode where the Application windows are actually embedded Items instead of separate windows. This abstraction allows AppMan to run on non-Linux systems too (e.g. for testing on the host PC)

       

      What works?
      Rotating Applications in multi-process mode. Since these are Wayland clients, Solution #3 works here.

       

      What doesn't?

      • Rotating the SysUI in multi-process mode (Limitation of Solution #3)
      • Rotating the SysUI in single-process mode (Limitation of Solution #2)
      • Rotating Applications in single-process mode (Limitation of Solution #2)

       

      Trying to work around the limitations in AppMan

      Since Wayland clients rotate fine already, we could move all SysUI Overlays into a background Application that is mostly transparent and always covers the whole SysUI.

       

      What works?
      Overlays now rotate correctly

       

      What doesn't?
      As a consequence of the Overlays being in a separate process from the SysUI, they can no longer access the SysUI API and cannot participate in performing SysUI tasks

       

      Next Steps

      Going through everything above, it is clear that fixing QTBUG-122771 would help tremendously to enable painless rotation (Solutions #2 and #3). That makes it an obvious starting point.

      In the longer-term though, I think we should clarify the "proper" way to do things. vhilshei's comments give me the impression that Solution #1 is most proper, followed by Solution #3 when Wayland is in use [7]. However,

      • Our documentation only discusses Solution #2 [1][4] and not the others. Our documentation should reflect best practices.
      • Implementing a custom EGL/FS plugin is quite a big hurdle. We should provide some guidance on how to follow best practices (or add the relevant functionality into our official plugin).

       

      References

      [1] "Switching Between Portrait and Landscape Views" | "Customizing Runtime Environment": https://doc.qt.io/Boot2Qt/b2qt-customization.html#switching-between-portrait-and-landscape-views

      [2] https://bugreports.qt.io/browse/QTBUG-71117?focusedId=757625&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-757625

      [3] Internal discussion

      [4] "QT_QPA_EGLFS_ROTATION" | "Environment variables used by EGLFS" | "Qt for Embedded Linux" https://doc.qt.io/qt-6/embedded-linux.html#environment-variables-used-by-eglfs

      [5] https://bugreports.qt.io/browse/QTBUG-80910?focusedId=757595&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-757595

      [6] "Popup Sizing" | "Popup QML Type" https://doc.qt.io/qt-6/qml-qtquick-controls-popup.html#popup-sizing

      [7] https://bugreports.qt.io/browse/QTBUG-122286?focusedId=775835&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-775835

      Attachments

        1. rottest-2a-landscape2portrait.gif
          314 kB
          Sze Howe Koh
        2. rottest-2b-portraitpopups.gif
          446 kB
          Sze Howe Koh
        3. rottest-3a-rotatecompositor.gif
          1.05 MB
          Sze Howe Koh
        4. rottest-3b-rotatecompositor-bad.gif
          590 kB
          Sze Howe Koh
        5. Sol2-WindowRotationTest.zip
          2 kB
          Sze Howe Koh
        6. Sol3-RotatableCompositor.zip
          2 kB
          Sze Howe Koh
        7. win10-display-settings.png
          13 kB
          Sze Howe Koh

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              lagocs Laszlo Agocs
              skoh-qt Sze Howe Koh
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There are no open Gerrit changes