on xenial help sign in
snap and properly restore the window when dragging it back
f6ec03fLukáš Tinkl
qml/Stages/DesktopStage.qml+2
@@ -505,6 +505,8 @@ AbstractStage {
505 duration: UbuntuAnimation.SnapDuration
505 duration: UbuntuAnimation.SnapDuration
506 }
506 }
507
507
508+ // unlike requestedX/Y, this is the last known grab position before being pushed against edges/corners
509+ // when restoring, the window should return to these, not to the place where it was dropped near the edge
508 property real restoredX
510 property real restoredX
509 property real restoredY
511 property real restoredY
510
512
qml/Stages/WindowDecoration.qml+21−14
@@ -17,6 +17,7 @@
17import QtQuick 2.4
17import QtQuick 2.4
18import Unity.Application 0.1 // For Mir singleton
18import Unity.Application 0.1 // For Mir singleton
19import Ubuntu.Components 1.3
19import Ubuntu.Components 1.3
20+import Utils 0.1
20import "../Components"
21import "../Components"
21import "../Components/PanelState"
22import "../Components/PanelState"
22
23
@@ -53,6 +54,7 @@ MouseArea {
53 onDoubleClicked: {
54 onDoubleClicked: {
54 priv.resetEdges();
55 priv.resetEdges();
55 if (target.canBeMaximized && mouse.button == Qt.LeftButton) {
56 if (target.canBeMaximized && mouse.button == Qt.LeftButton) {
57+ priv.dragging = false; // do not interfere with a quick double click followed by a mouse move/drag
56 root.maximizeClicked();
58 root.maximizeClicked();
57 }
59 }
58 }
60 }
@@ -82,16 +84,9 @@ MouseArea {
82 nearBottomRightCorner = false;
84 nearBottomRightCorner = false;
83 }
85 }
84
86
85− function saveRestoredPos(x, y) {
86− var pos = mapToItem(root.target, x, y);
87− target.restoredX = Math.round(pos.x);
88− target.restoredY = Math.round(pos.y);
89− print("!!! Saved pos", target.restoredX, target.restoredY)
90− }
91−
92 // return the progress of mouse pointer movement from 0 to 1 within a corner square of the screen
87 // return the progress of mouse pointer movement from 0 to 1 within a corner square of the screen
93 // 0 -> before the mouse enters the square
88 // 0 -> before the mouse enters the square
94− // 1 -> mouse is exactly in the very corner
89+ // 1 -> mouse is in the outer corner
95 // a is the corner, b is the mouse pos
90 // a is the corner, b is the mouse pos
96 function progressInCorner(ax, ay, bx, by) {
91 function progressInCorner(ax, ay, bx, by) {
97 // distance of two points, a and b, in pixels
92 // distance of two points, a and b, in pixels
@@ -107,7 +102,14 @@ MouseArea {
107 onPressedChanged: {
102 onPressedChanged: {
108 if (pressed && pressedButtons == Qt.LeftButton) {
103 if (pressed && pressedButtons == Qt.LeftButton) {
109 var pos = mapToItem(root.target, mouseX, mouseY);
104 var pos = mapToItem(root.target, mouseX, mouseY);
110− priv.distanceX = pos.x;
105+ if (target.anyMaximized) {
106+ // keep distanceX relative to the normal window width minus the window control buttons (+spacing)
107+ // so that dragging it back doesn't make the window jump around to weird positions, away from the mouse pointer
108+ priv.distanceX = MathUtils.clampAndProject(pos.x, 0, root.target.width, buttons.width + row.spacing, root.target.resizeArea.normalWidth);
109+ } else {
110+ priv.distanceX = pos.x;
111+ }
112+
111 priv.distanceY = pos.y;
113 priv.distanceY = pos.y;
112 priv.dragging = true;
114 priv.dragging = true;
113 } else {
115 } else {
@@ -119,11 +121,16 @@ MouseArea {
119 onPositionChanged: {
121 onPositionChanged: {
120 if (priv.dragging) {
122 if (priv.dragging) {
121 Mir.cursorName = "grabbing";
123 Mir.cursorName = "grabbing";
124+
125+ if (target.anyMaximized) { // restore from maximized when dragging away from edges/corners
126+ priv.progress = 0;
127+ target.restore(false, WindowStateStorage.WindowStateNormal);
128+ }
129+
122 var pos = mapToItem(root.target.parent, mouseX, mouseY);
130 var pos = mapToItem(root.target.parent, mouseX, mouseY);
123 // Use integer coordinate values to ensure that target is left in a pixel-aligned
131 // Use integer coordinate values to ensure that target is left in a pixel-aligned
124 // position. Mouse movement could have subpixel precision, yielding a fractional
132 // position. Mouse movement could have subpixel precision, yielding a fractional
125 // mouse position.
133 // mouse position.
126−
127 root.target.requestedX = Math.round(pos.x - priv.distanceX);
134 root.target.requestedX = Math.round(pos.x - priv.distanceX);
128 root.target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
135 root.target.requestedY = Math.round(Math.max(pos.y - priv.distanceY, PanelState.panelHeight));
129
136
@@ -185,9 +192,6 @@ MouseArea {
185 priv.progress = 0;
192 priv.progress = 0;
186 priv.resetEdges();
193 priv.resetEdges();
187 root.stopFakeAnimation();
194 root.stopFakeAnimation();
188− } else if (target.anyMaximized) {
189− priv.progress = 0;
190− target.restoreFromMaximized();
191 }
195 }
192 }
196 }
193 }
197 }
@@ -195,7 +199,9 @@ MouseArea {
195 onReleased: {
199 onReleased: {
196 print("Mouse released (left/top/right)", priv.nearLeftEdge, priv.nearTopEdge, priv.nearRightEdge)
200 print("Mouse released (left/top/right)", priv.nearLeftEdge, priv.nearTopEdge, priv.nearRightEdge)
197 if (mouse.button == Qt.LeftButton && (target.state == "normal" || target.state == "restored") && priv.progress == 0) {
201 if (mouse.button == Qt.LeftButton && (target.state == "normal" || target.state == "restored") && priv.progress == 0) {
198− priv.saveRestoredPos(target.x, target.y);
202+ // save the x/y to restore to
203+ target.restoredX = target.x;
204+ target.restoredY = target.y;
199 } else if (priv.progress < 0.3) { // cancel the preview shape if under 30%
205 } else if (priv.progress < 0.3) { // cancel the preview shape if under 30%
200 priv.progress = 0;
206 priv.progress = 0;
201 priv.resetEdges();
207 priv.resetEdges();
@@ -228,6 +234,7 @@ MouseArea {
228 }
234 }
229
235
230 Row {
236 Row {
237+ id: row
231 anchors {
238 anchors {
232 fill: parent
239 fill: parent
233 leftMargin: overlayShown ? units.gu(5) : units.gu(1)
240 leftMargin: overlayShown ? units.gu(5) : units.gu(1)
qml/Stages/WindowResizeArea.qml+1
@@ -30,6 +30,7 @@ MouseArea {
30
30
31 property var windowStateStorage: WindowStateStorage
31 property var windowStateStorage: WindowStateStorage
32 readonly property alias dragging: d.dragging
32 readonly property alias dragging: d.dragging
33+ readonly property alias normalWidth: priv.normalWidth
33
34
34 // The target item managed by this. Must be a parent or a sibling
35 // The target item managed by this. Must be a parent or a sibling
35 // The area will anchor to it and manage resize events
36 // The area will anchor to it and manage resize events