on xenial help sign in
Fix resizing windows when making it smaller than minSize and then larger again.
d6b7ae5Michael Zanetti
qml/Stages/WindowMoveResizeArea.qml+16−23
@@ -39,8 +39,6 @@ MouseArea {
39 readonly property int windowHeight: root.height - resizeHandleWidth * 2
39 readonly property int windowHeight: root.height - resizeHandleWidth * 2
40
40
41 property var startPoint
41 property var startPoint
42− property int startWidth
43− property int startHeight
44
42
45 property bool resizeTop: false
43 property bool resizeTop: false
46 property bool resizeBottom: false
44 property bool resizeBottom: false
@@ -60,9 +58,7 @@ MouseArea {
60 }
58 }
61
59
62 onPressed: {
60 onPressed: {
63− priv.startPoint = mapToItem(null, Qt.point(mouse.x, mouse.y)).x;
61+ priv.startPoint = Qt.point(mouse.x, mouse.y);
64− priv.startWidth = root.width;
65− priv.startHeight = root.height;
66 priv.resizeTop = mouseY < root.resizeHandleWidth;
62 priv.resizeTop = mouseY < root.resizeHandleWidth;
67 priv.resizeBottom = mouseY > (root.height - root.resizeHandleWidth);
63 priv.resizeBottom = mouseY > (root.height - root.resizeHandleWidth);
68 priv.resizeLeft = mouseX < root.resizeHandleWidth;
64 priv.resizeLeft = mouseX < root.resizeHandleWidth;
@@ -70,32 +66,28 @@ MouseArea {
70 }
66 }
71
67
72 onPositionChanged: {
68 onPositionChanged: {
73− var currentPoint = mapToItem(null, Qt.point(mouse.x, mouse.y)).x;
69+ var currentPoint = Qt.point(mouse.x, mouse.y);
74 var mouseDiff = Qt.point(currentPoint.x - priv.startPoint.x, currentPoint.y - priv.startPoint.y);
70 var mouseDiff = Qt.point(currentPoint.x - priv.startPoint.x, currentPoint.y - priv.startPoint.y);
75 var moveDiff = Qt.point(0, 0);
71 var moveDiff = Qt.point(0, 0);
76 var sizeDiff = Qt.point(0, 0);
72 var sizeDiff = Qt.point(0, 0);
73+ var maxSizeDiff = Qt.point(root.minWidth - root.target.width, root.minHeight - root.target.height)
74+
77 if (priv.resizeTop || priv.resizeBottom || priv.resizeLeft || priv.resizeRight) {
75 if (priv.resizeTop || priv.resizeBottom || priv.resizeLeft || priv.resizeRight) {
78 if (priv.resizeTop) {
76 if (priv.resizeTop) {
79− moveDiff.y += mouseDiff.y;
77+ sizeDiff.y = Math.max(maxSizeDiff.y, -currentPoint.y + priv.startPoint.y)
80− sizeDiff.y += -mouseDiff.y;
78+ moveDiff.y = -sizeDiff.y
81− } else if (priv.resizeBottom) {
82− sizeDiff.y += mouse.y - priv.startPoint.y;
83− priv.startPoint.y = mouse.y
84 }
79 }
85− if (priv.resizeLeft) {
80+ if (priv.resizeBottom) {
86− moveDiff.x += mouseDiff.x;
81+ sizeDiff.y = Math.max(maxSizeDiff.y, currentPoint.y - priv.startPoint.y)
87− sizeDiff.x += -mouseDiff.x;
82+ priv.startPoint.y += sizeDiff.y
88− } else if (priv.resizeRight) {
89− sizeDiff.x += mouse.x - priv.startPoint.x;
90− priv.startPoint.x = mouse.x
91 }
83 }
92− if (priv.windowWidth + sizeDiff.x < root.minWidth) {
84+ if (priv.resizeLeft) {
93− sizeDiff.x = root.minWidth - priv.windowWidth;
85+ sizeDiff.x = Math.max(maxSizeDiff.x, -currentPoint.x + priv.startPoint.x)
94− moveDiff.x = moveDiff.x == 0 ? 0 : -sizeDiff.x;
86+ moveDiff.x = -sizeDiff.x
95 }
87 }
96− if (priv.windowHeight + sizeDiff.y < root.minHeight) {
88+ if (priv.resizeRight) {
97− sizeDiff.y = root.minHeight - priv.windowHeight;
89+ sizeDiff.x = Math.max(maxSizeDiff.x, currentPoint.x - priv.startPoint.x)
98− moveDiff.y = moveDiff.y == 0 ? 0 : -sizeDiff.y;
90+ priv.startPoint.x += sizeDiff.x
99 }
91 }
100
92
101 target.x += moveDiff.x;
93 target.x += moveDiff.x;
@@ -106,6 +98,7 @@ MouseArea {
106 target.x += mouseDiff.x;
98 target.x += mouseDiff.x;
107 target.y += mouseDiff.y;
99 target.y += mouseDiff.y;
108 }
100 }
101+
109 }
102 }
110
103
111 Component.onDestruction: {
104 Component.onDestruction: {
tests/qmltests/Stages/tst_WindowMoveResizeArea.qml+25
@@ -208,5 +208,30 @@ Item {
208 tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
208 tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
209 tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
209 tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
210 }
210 }
211+
212+ // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
213+ // to the mouse, instead of immediately making the window grow again when switching direction
214+ function test_resizeSmallerAndLarger_data() {
215+ return [
216+ { tag: "topLeft", startX: -1, startY: -1, dx: units.gu(15), dy: units.gu(15) },
217+ { tag: "bottomRight", startX: fakeWindow.width + 1, startY: fakeWindow.height + 1, dx: -units.gu(15), dy: -units.gu(15) }
218+ ]
219+ }
220+
221+ function test_resizeSmallerAndLarger(data) {
222+ var initialWindowX = fakeWindow.x;
223+ var initialWindowY = fakeWindow.y;
224+ var initialWindowWidth = fakeWindow.width
225+ var initialWindowHeight = fakeWindow.height
226+
227+ var startDragX = initialWindowX + data.startX
228+ var startDragY = initialWindowY + data.startY
229+ mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
230+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
231+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
232+ mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
233+ tryCompare(fakeWindow, "width", initialWindowWidth);
234+ tryCompare(fakeWindow, "height", initialWindowHeight);
235+ }
211 }
236 }
212}
237}