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

Drawer opening/closing algorithm does not consider change of direction

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.2.11, 6.5.5-1, 6.7.0 RC, 6.7.0
    • Quick: Controls 2
    • Windows 10 22H2, MSVC 2019 x64

    Description

      Suppose that the user starts opening a Drawer: He presses, holds, and drags the Drawer all the way to position=1.0 but doesn't release it yet. Then, the user changes his mind, so he swipes backwards hard and fast, releasing the Drawer at almost position=0+.

      import QtQuick
      import QtQuick.Controls.Basic
      import QtTest
      
      Rectangle {
          id: root
          width: 800
          height: 600
      
          Drawer {
              id: drawer
              width: parent.width / 3
              height: parent.height
              edge: Qt.LeftEdge
      
              Text {
                  anchors.right: parent.right
                  anchors.verticalCenter: parent.verticalCenter
                  text: drawer.position.toFixed(2)
              }
          }
      
          TestCase {
              id: testCase
      
              function test_changeMind() {
                  testCase.mousePress(root, 0)
      
                  // Slowly start to open the drawer...
                  let nSegments = 100
                  for (let i = 0; i < nSegments; ++i) {
                      testCase.mouseMove(root, drawer.width * i/nSegments)
                      testCase.wait(10)
                  }
      
                  // ...changed mind. Swipe backwards rapidly and release to close the drawer.
                  nSegments = 5
                  for (let i = 0; i < nSegments; ++i) {
                      testCase.mouseMove(root, drawer.width * (1 - i/nSegments))
                      testCase.wait(10)
                  }
                  testCase.mouseRelease(root)
      
                  // Did the drawer close as expected?
                  testCase.tryCompare(drawer, "position", 0)
              }
          }
      }
      

       

      Expected outcome
      The Drawer closes.

       

      Actual outcome
      The Drawer opens.

       

      Analysis
      The Drawer is quite simplistic, only considering the start (Press) point and the stop (Release) point.

      In the user's mind, the hard and fast backwards swipe should be considered a large negative velocity - a strong sign that they want the Drawer to return to its closed state. However, QQuickDrawerPrivate::handleRelease() sees a positive displacement and  QQuickVelocityCalculator sees as a positive velocity, so the Drawer concludes that it should open.

       

      Possible solutions

      • QEventPoint already calculates instantaneous velocity (https://github.com/qt/qtbase/blob/v6.7.0/src/gui/kernel/qeventpoint.cpp#L592-L595 ) - could we make use of its calculations instead?
      • Instead of calculating the velocity based on 2D coordinates (and then discarding one axis), we could simply calculate the 1D rate-of-change of Drawer.position and reset the "start" point when the direction changes. See the idea in the attached patch.

      Attachments

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

        Activity

          People

            edcooke Ed Cooke
            skoh-qt Sze Howe Koh
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes