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

Bindings on Overlay's size and position are not respected

    XMLWordPrintable

Details

    Description

      Code

      import QtQuick
      import QtQuick.Controls.Basic
      
      Window {
          id: window
          width: 800
          height: 600
          visible: true
      
          Overlay.overlay.width: window.width * 3/4
          Overlay.overlay.height: window.height * 3/4
          Overlay.overlay.anchors.centerIn: window.contentItem
      /*
          // WORKAROUND: Replace the bindings above with the following
          Overlay.overlay.anchors.fill: board
          Item {
              id: board
              width: window.width * 3/4
              height: window.height * 3/4
              anchors.centerIn: parent
          }
      */
          Popup {
              id: popup
              width: window.width / 2
              height: window.height / 2
              anchors.centerIn: parent
              dim: true
              opacity: 0.5
          }
          Text {
              anchors.centerIn: parent
              text: `Window: ${window.width}x${window.height}` + '\n' +
                    `Overlay: (${window.Overlay.overlay.x}, ${window.Overlay.overlay.y}) ${window.Overlay.overlay.width}x${window.Overlay.overlay.height}`
          }
          Row {
              spacing: 10
              Button {
                  text: "Pop Up"
                  onClicked: popup.open()
              }
              Button {
                  text: "Kick Width"
                  onClicked: {
                      window.width += 1
                      window.width -= 1
                  }
              }
              Button {
                  text: "Kick Height"
                  onClicked: {
                      window.height += 1
                      window.height -= 1
                  }
              }
          }
      }
      

      Steps to reproduce

      1. Run the example code above
      2. Click "Pop Up"
      3. Click "Kick Width" and then click "Pop Up"
      4. Click "Kick Height" and then click "Pop Up"
      5. Click "Pop Up" and then resize the window freely

       

      Expected outcomes

      • The Popup's dimmer is always 3/4 the size of the window
      • Also, Steps #2-#4: The text reports "Overlay: (100, 75) 650x450" throughout

       

      Actual outcomes

      • Step #2: "Overlay: (0, 0) 800x600"
      • Step #3: "Overlay: (100, 0) 600x600"
      • Step #4: "Overlay: (0, 75) 800x450"
      • Step #5: The dimmer fluctuates between being too wide, or too tall, or just right (at 3/4 the size of the window)

       

      Workaround
      Instead of binding width/height, create an invisible Item with the geometry that you want the dimmer to be. Then, use anchors.fill to make the Overlay's geometry match that Item (see code above)

       

      Analysis
      This issue occurs because QQuickOverlay::updateGeometry() calls setSize() and setPosition().

      The workaround works because, in the current implementation of Qt Quick, anchors are calculated after size and position are applied so the results of QQuickOverlay::updateGeometry() are overwritten. But I don't know if this behaviour is guaranteed to persist into the future.

      It would be good if QQuickOverlay could be bound to the geometry of the QQuickWindow::contentItem() at initialization, but then allow the user to override that binding from QML.

       

      Use cases

      • Our Boot2Qt documentation shows how to switch between portrait and lanscape views. But if the GUI contains Popups/ComboBoxes/Drawers/Menus then we also need to manually change the Overlay's geometry to apply this trick.
      • If we spin the Popup (say, for an animated effect), we need to enlarge the dimmer so that it covers whole window throughout the animation:
        import QtQuick
        import QtQuick.Controls.Basic
        
        Window {
            id: window
            width: 800
            height: 600
            visible: true
        
            property double diagonal: Math.sqrt(window.width*window.width + window.height*window.height)
        
            Popup {
                id: popup
                width: window.width / 2
                height: window.height / 2
                anchors.centerIn: parent
                dim: true
        
                PropertyAnimation {
                    id: anim
                    target: popup.Overlay.overlay
                    property: "rotation"
                    from: 0
                    to: 360
                    duration: 1000
                }
                Overlay.modeless: Rectangle {
                    color: "blue"
                    opacity: 0.5
                    width: window.diagonal // DOESN'T WORK
                    height: window.diagonal // DOESN'T WORK
                }
                Button {
                    anchors.centerIn: parent
                    text: "Spin!"
                    onClicked: anim.start()
                }
            }
            Button {
                text: "Pop Up"
                onClicked: popup.open()
            }
        /*
            // WORKAROUND
            Overlay.overlay.anchors.fill: board
            Item {
                id: board
                width: window.diagonal
                height: window.diagonal
                anchors.centerIn: parent
            }
        */
        }
        

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-122962
          # Subject Branch Project Status CR V

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              skoh-qt Sze Howe Koh
              Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There is 1 open Gerrit change