Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
6.2.11, 6.5.5-1, 6.7.0 RC, 6.7.0, 6.8.0
-
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.