on xenial help sign in
Window Size Hints
998108cDaniel d'Andrada
CMakeLists.txt+1−1
@@ -57,7 +57,7 @@ find_package(Qt5DBus 5.4 REQUIRED)
57find_package(Qt5Concurrent 5.4 REQUIRED)
57find_package(Qt5Concurrent 5.4 REQUIRED)
58find_package(Qt5Sql 5.4 REQUIRED)
58find_package(Qt5Sql 5.4 REQUIRED)
59
59
60−pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=11)
60+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
61
61
62# Standard install paths
62# Standard install paths
63include(GNUInstallDirs)
63include(GNUInstallDirs)
debian/control+3−3
@@ -29,7 +29,7 @@ Build-Depends: cmake,
29 libqt5xmlpatterns5-dev,
29 libqt5xmlpatterns5-dev,
30 libsystemsettings-dev,
30 libsystemsettings-dev,
31 libudev-dev,
31 libudev-dev,
32− libunity-api-dev (>= 7.103),
32+ libunity-api-dev (>= 7.104),
33 libusermetricsoutput1-dev,
33 libusermetricsoutput1-dev,
34 libxcb1-dev,
34 libxcb1-dev,
35 pkg-config,
35 pkg-config,
@@ -128,7 +128,7 @@ Depends: qml-module-qtquick-layouts,
128 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
128 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
129 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
129 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
130 ubuntu-thumbnailer-impl-0,
130 ubuntu-thumbnailer-impl-0,
131− unity-application-impl-11,
131+ unity-application-impl-12,
132 unity-notifications-impl-3,
132 unity-notifications-impl-3,
133 unity-plugin-scopes | unity-scopes-impl,
133 unity-plugin-scopes | unity-scopes-impl,
134 unity-scopes-impl-7,
134 unity-scopes-impl-7,
@@ -174,7 +174,7 @@ Pre-Depends: ${misc:Pre-Depends},
174Depends: ${misc:Depends},
174Depends: ${misc:Depends},
175 ${shlibs:Depends},
175 ${shlibs:Depends},
176Provides: unity-application-impl,
176Provides: unity-application-impl,
177− unity-application-impl-11,
177+ unity-application-impl-12,
178Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
178Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
179Description: Fake environment for running Unity 8 shell
179Description: Fake environment for running Unity 8 shell
180 Provides fake implementations of some QML modules used by Unity 8 shell
180 Provides fake implementations of some QML modules used by Unity 8 shell
qml/Stages/ApplicationWindow.qml+7
@@ -37,6 +37,13 @@ FocusScope {
37 property int requestedWidth: -1
37 property int requestedWidth: -1
38 property int requestedHeight: -1
38 property int requestedHeight: -1
39
39
40+ readonly property int minimumWidth: sessionContainer.surface ? sessionContainer.surface.minimumWidth : 0
41+ readonly property int minimumHeight: sessionContainer.surface ? sessionContainer.surface.minimumHeight : 0
42+ readonly property int maximumWidth: sessionContainer.surface ? sessionContainer.surface.maximumWidth : 0
43+ readonly property int maximumHeight: sessionContainer.surface ? sessionContainer.surface.maximumHeight : 0
44+ readonly property int widthIncrement: sessionContainer.surface ? sessionContainer.surface.widthIncrement : 0
45+ readonly property int heightIncrement: sessionContainer.surface ? sessionContainer.surface.heightIncrement : 0
46+
40 QtObject {
47 QtObject {
41 id: d
48 id: d
42
49
qml/Stages/DecoratedWindow.qml+7
@@ -39,6 +39,13 @@ FocusScope {
39 property alias requestedWidth: applicationWindow.requestedWidth
39 property alias requestedWidth: applicationWindow.requestedWidth
40 property real requestedHeight
40 property real requestedHeight
41
41
42+ property alias minimumWidth: applicationWindow.minimumWidth
43+ readonly property int minimumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.minimumHeight
44+ property alias maximumWidth: applicationWindow.maximumWidth
45+ readonly property int maximumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.maximumHeight
46+ property alias widthIncrement: applicationWindow.widthIncrement
47+ property alias heightIncrement: applicationWindow.heightIncrement
48+
42 signal close()
49 signal close()
43 signal maximize()
50 signal maximize()
44 signal minimize()
51 signal minimize()
qml/Stages/DesktopStage.qml+6
@@ -244,6 +244,12 @@ AbstractStage {
244 height: decoratedWindow.height
244 height: decoratedWindow.height
245 property alias requestedWidth: decoratedWindow.requestedWidth
245 property alias requestedWidth: decoratedWindow.requestedWidth
246 property alias requestedHeight: decoratedWindow.requestedHeight
246 property alias requestedHeight: decoratedWindow.requestedHeight
247+ property alias minimumWidth: decoratedWindow.minimumWidth
248+ property alias minimumHeight: decoratedWindow.minimumHeight
249+ property alias maximumWidth: decoratedWindow.maximumWidth
250+ property alias maximumHeight: decoratedWindow.maximumHeight
251+ property alias widthIncrement: decoratedWindow.widthIncrement
252+ property alias heightIncrement: decoratedWindow.heightIncrement
247
253
248 QtObject {
254 QtObject {
249 id: appDelegatePrivate
255 id: appDelegatePrivate
qml/Stages/WindowResizeArea.qml+95−16
@@ -72,8 +72,8 @@ MouseArea {
72 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
72 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
73 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
73 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
74
74
75− target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth);
75+ target.requestedWidth = Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth);
76− target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight);
76+ target.requestedHeight = Math.min(Math.max(windowGeometry.height, d.minimumHeight), root.screenHeight - PanelState.panelHeight);
77 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
77 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
78 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
78 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
79
79
@@ -91,6 +91,65 @@ MouseArea {
91
91
92 QtObject {
92 QtObject {
93 id: d
93 id: d
94+
95+ readonly property int maxSafeInt: 2147483647
96+ readonly property int maxSizeIncrement: units.gu(40)
97+
98+ property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
99+ onMinimumWidthChanged: {
100+ if (target.requestedWidth < minimumWidth) {
101+ target.requestedWidth = minimumWidth;
102+ }
103+ }
104+ property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight
105+ onMinimumHeightChanged: {
106+ if (target.requestedHeight < minimumHeight) {
107+ target.requestedHeight = minimumHeight;
108+ }
109+ }
110+ property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0
111+ ? root.target.maximumWidth : maxSafeInt
112+ onMaximumWidthChanged: {
113+ if (target.requestedWidth > maximumWidth) {
114+ target.requestedWidth = maximumWidth;
115+ }
116+ }
117+ property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0
118+ ? root.target.maximumHeight : maxSafeInt
119+ onMaximumHeightChanged: {
120+ if (target.requestedHeight > maximumHeight) {
121+ target.requestedHeight = maximumHeight;
122+ }
123+ }
124+ property int widthIncrement: {
125+ if (!root.target) {
126+ return 1;
127+ }
128+ if (root.target.widthIncrement > 0) {
129+ if (root.target.widthIncrement < maxSizeIncrement) {
130+ return root.target.widthIncrement;
131+ } else {
132+ return maxSizeIncrement;
133+ }
134+ } else {
135+ return 1;
136+ }
137+ }
138+ property int heightIncrement: {
139+ if (!root.target) {
140+ return 1;
141+ }
142+ if (root.target.heightIncrement > 0) {
143+ if (root.target.heightIncrement < maxSizeIncrement) {
144+ return root.target.heightIncrement;
145+ } else {
146+ return maxSizeIncrement;
147+ }
148+ } else {
149+ return 1;
150+ }
151+ }
152+
94 property bool leftBorder: false
153 property bool leftBorder: false
95 property bool rightBorder: false
154 property bool rightBorder: false
96 property bool topBorder: false
155 property bool topBorder: false
@@ -209,38 +268,58 @@ MouseArea {
209
268
210 var pos = mapToItem(target.parent, mouse.x, mouse.y);
269 var pos = mapToItem(target.parent, mouse.x, mouse.y);
211
270
212− var deltaX = pos.x - d.startMousePosX;
271+ var deltaX = Math.floor((pos.x - d.startMousePosX) / d.widthIncrement) * d.widthIncrement;
213− var deltaY = pos.y - d.startMousePosY;
272+ var deltaY = Math.floor((pos.y - d.startMousePosY) / d.heightIncrement) * d.heightIncrement;
214
273
215 if (d.leftBorder) {
274 if (d.leftBorder) {
216 var newTargetX = d.startX + deltaX;
275 var newTargetX = d.startX + deltaX;
217− if (target.x + target.width > newTargetX + minWidth) {
276+ var rightBorderX = target.x + target.width;
218− target.requestedWidth = target.x + target.width - newTargetX;
277+ if (rightBorderX > newTargetX + d.minimumWidth) {
278+ if (rightBorderX < newTargetX + d.maximumWidth) {
279+ target.requestedWidth = rightBorderX - newTargetX;
280+ } else {
281+ target.requestedWidth = d.maximumWidth;
282+ }
219 } else {
283 } else {
220− target.requestedWidth = minWidth;
284+ target.requestedWidth = d.minimumWidth;
221 }
285 }
222
286
223 } else if (d.rightBorder) {
287 } else if (d.rightBorder) {
224− if (d.startWidth + deltaX >= minWidth) {
288+ var newWidth = d.startWidth + deltaX;
289+ if (newWidth > d.minimumWidth) {
290+ if (newWidth < d.maximumWidth) {
225− target.requestedWidth = d.startWidth + deltaX;
291+ target.requestedWidth = newWidth;
292+ } else {
293+ target.requestedWidth = d.maximumWidth;
294+ }
226 } else {
295 } else {
227− target.requestedWidth = minWidth;
296+ target.requestedWidth = d.minimumWidth;
228 }
297 }
229 }
298 }
230
299
231 if (d.topBorder) {
300 if (d.topBorder) {
232 var newTargetY = d.startY + deltaY;
301 var newTargetY = d.startY + deltaY;
233− if (target.y + target.height > newTargetY + minHeight) {
302+ var bottomBorderY = target.y + target.height;
234− target.requestedHeight = target.y + target.height - newTargetY;
303+ if (bottomBorderY > newTargetY + d.minimumHeight) {
304+ if (bottomBorderY < newTargetY + d.maximumHeight) {
305+ target.requestedHeight = bottomBorderY - newTargetY;
306+ } else {
307+ target.requestedHeight = d.maximumHeight;
308+ }
235 } else {
309 } else {
236− target.requestedHeight = minHeight;
310+ target.requestedHeight = d.minimumHeight;
237 }
311 }
238
312
239 } else if (d.bottomBorder) {
313 } else if (d.bottomBorder) {
240− if (d.startHeight + deltaY >= minHeight) {
314+ var newHeight = d.startHeight + deltaY;
315+ if (newHeight > d.minimumHeight) {
316+ if (newHeight < d.maximumHeight) {
241− target.requestedHeight = d.startHeight + deltaY;
317+ target.requestedHeight = newHeight;
318+ } else {
319+ target.requestedHeight = d.maximumHeight;
320+ }
242 } else {
321 } else {
243− target.requestedHeight = minHeight;
322+ target.requestedHeight = d.minimumHeight;
244 }
323 }
245 }
324 }
246 }
325 }
tests/mocks/Unity/Application/MirSurface.cpp+48
@@ -266,3 +266,51 @@ void MirSurface::setSlowToResize(bool value)
266 }
266 }
267 }
267 }
268}
268}
269+
270+void MirSurface::setMinimumWidth(int value)
271+{
272+ if (value != m_minimumWidth) {
273+ m_minimumWidth = value;
274+ Q_EMIT minimumWidthChanged(m_minimumWidth);
275+ }
276+}
277+
278+void MirSurface::setMaximumWidth(int value)
279+{
280+ if (value != m_maximumWidth) {
281+ m_maximumWidth = value;
282+ Q_EMIT maximumWidthChanged(m_maximumWidth);
283+ }
284+}
285+
286+void MirSurface::setMinimumHeight(int value)
287+{
288+ if (value != m_minimumHeight) {
289+ m_minimumHeight = value;
290+ Q_EMIT minimumHeightChanged(m_minimumHeight);
291+ }
292+}
293+
294+void MirSurface::setMaximumHeight(int value)
295+{
296+ if (value != m_maximumHeight) {
297+ m_maximumHeight = value;
298+ Q_EMIT maximumHeightChanged(m_maximumHeight);
299+ }
300+}
301+
302+void MirSurface::setWidthIncrement(int value)
303+{
304+ if (value != m_widthIncrement) {
305+ m_widthIncrement = value;
306+ Q_EMIT widthIncrementChanged(m_widthIncrement);
307+ }
308+}
309+
310+void MirSurface::setHeightIncrement(int value)
311+{
312+ if (value != m_heightIncrement) {
313+ m_heightIncrement = value;
314+ Q_EMIT heightIncrementChanged(m_heightIncrement);
315+ }
316+}
tests/mocks/Unity/Application/MirSurface.h+21
@@ -66,6 +66,13 @@ public:
66 Mir::OrientationAngle orientationAngle() const override;
66 Mir::OrientationAngle orientationAngle() const override;
67 void setOrientationAngle(Mir::OrientationAngle) override;
67 void setOrientationAngle(Mir::OrientationAngle) override;
68
68
69+ int minimumWidth() const override { return m_minimumWidth; }
70+ int minimumHeight() const override { return m_minimumHeight; }
71+ int maximumWidth() const override { return m_maximumWidth; }
72+ int maximumHeight() const override { return m_maximumHeight; }
73+ int widthIncrement() const override { return m_widthIncrement; }
74+ int heightIncrement() const override { return m_heightIncrement; }
75+
69 ////
76 ////
70 // API for tests
77 // API for tests
71
78
@@ -82,6 +89,13 @@ public:
82 bool isSlowToResize() const;
89 bool isSlowToResize() const;
83 void setSlowToResize(bool value);
90 void setSlowToResize(bool value);
84
91
92+ Q_INVOKABLE void setMinimumWidth(int);
93+ Q_INVOKABLE void setMaximumWidth(int);
94+ Q_INVOKABLE void setMinimumHeight(int);
95+ Q_INVOKABLE void setMaximumHeight(int);
96+ Q_INVOKABLE void setWidthIncrement(int);
97+ Q_INVOKABLE void setHeightIncrement(int);
98+
85 /////
99 /////
86 // internal mock stuff
100 // internal mock stuff
87
101
@@ -125,6 +139,13 @@ private:
125 int m_width;
139 int m_width;
126 int m_height;
140 int m_height;
127
141
142+ int m_minimumWidth{0};
143+ int m_minimumHeight{0};
144+ int m_maximumWidth{0};
145+ int m_maximumHeight{0};
146+ int m_widthIncrement{0};
147+ int m_heightIncrement{0};
148+
128 bool m_slowToResize;
149 bool m_slowToResize;
129 QTimer m_delayedResizeTimer;
150 QTimer m_delayedResizeTimer;
130 QSize m_delayedResize;
151 QSize m_delayedResize;
tests/mocks/Unity/Application/SurfaceManager.cpp+56
@@ -46,6 +46,14 @@ MirSurface *SurfaceManager::createSurface(const QString& name,
46 MirSurface* surface = qobject_cast<MirSurface*>(obj);
46 MirSurface* surface = qobject_cast<MirSurface*>(obj);
47 Q_EMIT surfaceDestroyed(surface);
47 Q_EMIT surfaceDestroyed(surface);
48 });
48 });
49+
50+ surface->setMinimumWidth(m_newSurfaceMinimumWidth);
51+ surface->setMaximumWidth(m_newSurfaceMaximumWidth);
52+ surface->setMinimumHeight(m_newSurfaceMinimumHeight);
53+ surface->setMaximumHeight(m_newSurfaceMaximumHeight);
54+ surface->setWidthIncrement(m_newSurfaceWidthIncrement);
55+ surface->setHeightIncrement(m_newSurfaceHeightIncrement);
56+
49 Q_EMIT surfaceCreated(surface);
57 Q_EMIT surfaceCreated(surface);
50 return surface;
58 return surface;
51}
59}
@@ -62,3 +70,51 @@ MirSurface *SurfaceManager::inputMethodSurface()
62 }
70 }
63 return m_virtualKeyboard;
71 return m_virtualKeyboard;
64}
72}
73+
74+void SurfaceManager::setNewSurfaceMinimumWidth(int value)
75+{
76+ if (m_newSurfaceMinimumWidth != value) {
77+ m_newSurfaceMinimumWidth = value;
78+ Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
79+ }
80+}
81+
82+void SurfaceManager::setNewSurfaceMaximumWidth(int value)
83+{
84+ if (m_newSurfaceMaximumWidth != value) {
85+ m_newSurfaceMaximumWidth = value;
86+ Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
87+ }
88+}
89+
90+void SurfaceManager::setNewSurfaceMinimumHeight(int value)
91+{
92+ if (m_newSurfaceMinimumHeight != value) {
93+ m_newSurfaceMinimumHeight = value;
94+ Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
95+ }
96+}
97+
98+void SurfaceManager::setNewSurfaceMaximumHeight(int value)
99+{
100+ if (m_newSurfaceMaximumHeight != value) {
101+ m_newSurfaceMaximumHeight = value;
102+ Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
103+ }
104+}
105+
106+void SurfaceManager::setNewSurfaceWidthIncrement(int value)
107+{
108+ if (m_newSurfaceWidthIncrement != value) {
109+ m_newSurfaceWidthIncrement = value;
110+ Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
111+ }
112+}
113+
114+void SurfaceManager::setNewSurfaceHeightIncrement(int value)
115+{
116+ if (m_newSurfaceHeightIncrement != value) {
117+ m_newSurfaceHeightIncrement = value;
118+ Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
119+ }
120+}
tests/mocks/Unity/Application/SurfaceManager.h+40
@@ -25,6 +25,14 @@
25class SurfaceManager : public QObject
25class SurfaceManager : public QObject
26{
26{
27 Q_OBJECT
27 Q_OBJECT
28+
29+ Q_PROPERTY(int newSurfaceMinimumWidth READ newSurfaceMinimumWidth WRITE setNewSurfaceMinimumWidth NOTIFY newSurfaceMinimumWidthChanged)
30+ Q_PROPERTY(int newSurfaceMaximumWidth READ newSurfaceMaximumWidth WRITE setNewSurfaceMaximumWidth NOTIFY newSurfaceMaximumWidthChanged)
31+ Q_PROPERTY(int newSurfaceMinimumHeight READ newSurfaceMinimumHeight WRITE setNewSurfaceMinimumHeight NOTIFY newSurfaceMinimumHeightChanged)
32+ Q_PROPERTY(int newSurfaceMaximumHeight READ newSurfaceMaximumHeight WRITE setNewSurfaceMaximumHeight NOTIFY newSurfaceMaximumHeightChanged)
33+ Q_PROPERTY(int newSurfaceWidthIncrement READ newSurfaceWidthIncrement WRITE setNewSurfaceWidthIncrement NOTIFY newSurfaceWidthIncrementChanged)
34+ Q_PROPERTY(int newSurfaceHeightIncrement READ newSurfaceHeightIncrement WRITE setNewSurfaceHeightIncrement NOTIFY newSurfaceHeightIncrementChanged)
35+
28public:
36public:
29 explicit SurfaceManager(QObject *parent = 0);
37 explicit SurfaceManager(QObject *parent = 0);
30
38
@@ -38,14 +46,46 @@ public:
38 // To be used in the tests
46 // To be used in the tests
39 Q_INVOKABLE MirSurface* inputMethodSurface();
47 Q_INVOKABLE MirSurface* inputMethodSurface();
40
48
49+ int newSurfaceMinimumWidth() const { return m_newSurfaceMinimumWidth; }
50+ void setNewSurfaceMinimumWidth(int value);
51+
52+ int newSurfaceMaximumWidth() const { return m_newSurfaceMaximumWidth; }
53+ void setNewSurfaceMaximumWidth(int value);
54+
55+ int newSurfaceMinimumHeight() const { return m_newSurfaceMinimumHeight; }
56+ void setNewSurfaceMinimumHeight(int value);
57+
58+ int newSurfaceMaximumHeight() const { return m_newSurfaceMaximumHeight; }
59+ void setNewSurfaceMaximumHeight(int value);
60+
61+ int newSurfaceWidthIncrement() const { return m_newSurfaceWidthIncrement; }
62+ void setNewSurfaceWidthIncrement(int);
63+
64+ int newSurfaceHeightIncrement() const { return m_newSurfaceHeightIncrement; }
65+ void setNewSurfaceHeightIncrement(int);
66+
41Q_SIGNALS:
67Q_SIGNALS:
42 void countChanged();
68 void countChanged();
43 void surfaceCreated(MirSurface *surface);
69 void surfaceCreated(MirSurface *surface);
44 void surfaceDestroyed(MirSurface*surface);
70 void surfaceDestroyed(MirSurface*surface);
45
71
72+ void newSurfaceMinimumWidthChanged(int value);
73+ void newSurfaceMaximumWidthChanged(int value);
74+ void newSurfaceMinimumHeightChanged(int value);
75+ void newSurfaceMaximumHeightChanged(int value);
76+ void newSurfaceWidthIncrementChanged(int value);
77+ void newSurfaceHeightIncrementChanged(int value);
78+
46private:
79private:
47 static SurfaceManager *the_surface_manager;
80 static SurfaceManager *the_surface_manager;
48 VirtualKeyboard *m_virtualKeyboard;
81 VirtualKeyboard *m_virtualKeyboard;
82+
83+ int m_newSurfaceMinimumWidth{0};
84+ int m_newSurfaceMaximumWidth{0};
85+ int m_newSurfaceMinimumHeight{0};
86+ int m_newSurfaceMaximumHeight{0};
87+ int m_newSurfaceWidthIncrement{1};
88+ int m_newSurfaceHeightIncrement{1};
49};
89};
50
90
51#endif // SURFACEMANAGER_H
91#endif // SURFACEMANAGER_H
tests/qmltests/Stages/SizeHintField.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright 2015 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import QtQuick.Layouts 1.1
19+import Ubuntu.Components 1.3
20+
21+Row {
22+ property alias text: label.text
23+ property alias value: field.text
24+ spacing: units.gu(1)
25+ Label {
26+ id: label
27+ color: "black"; anchors.verticalCenter: parent.verticalCenter
28+ }
29+ TextField {
30+ id: field
31+ text: ""; width: units.gu(8); hasClearButton: false; maximumLength: 6; inputMask: "d00000"
32+ }
33+}
tests/qmltests/Stages/SurfaceManagerControls.qmlnew file+33
@@ -0,0 +1,33 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Column {
22+ id: root
23+ property color textColor: "black"
24+
25+ Label {text: "Size hints for new surface:"; color: root.textColor; font.bold: true}
26+
27+ SurfaceManagerField { text: "min width"; propertyName: "newSurfaceMinimumWidth"; textColor: root.textColor }
28+ SurfaceManagerField { text: "max width"; propertyName: "newSurfaceMaximumWidth"; textColor: root.textColor }
29+ SurfaceManagerField { text: "min height"; propertyName: "newSurfaceMinimumHeight"; textColor: root.textColor }
30+ SurfaceManagerField { text: "max height"; propertyName: "newSurfaceMaximumHeight"; textColor: root.textColor }
31+ SurfaceManagerField { text: "width increment"; propertyName: "newSurfaceWidthIncrement"; textColor: root.textColor }
32+ SurfaceManagerField { text: "height increment"; propertyName: "newSurfaceHeightIncrement"; textColor: root.textColor }
33+}
tests/qmltests/Stages/SurfaceManagerField.qmlnew file+40
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.4
18+import Ubuntu.Components 1.3
19+import Unity.Application 0.1
20+
21+Row {
22+ id: root
23+ property alias textColor: label.color
24+ property alias text: label.text
25+ property string propertyName
26+
27+ Label {id: label; anchors.verticalCenter: parent.verticalCenter}
28+ TextField {
29+ width: units.gu(10); hasClearButton: false; maximumLength: 6
30+ inputMask: "d00000"
31+ text: ""
32+ onTextChanged: {
33+ if (text.length > 0) {
34+ SurfaceManager[root.propertyName] = parseInt(text);
35+ } else {
36+ SurfaceManager[root.propertyName] = 0;
37+ }
38+ }
39+ }
40+}
tests/qmltests/Stages/tst_DesktopStage.qml+30−24
@@ -88,36 +88,42 @@ Item {
88 right: parent.right
88 right: parent.right
89 }
89 }
90
90
91− Column {
91+ Flickable {
92− anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
92+ anchors.fill: parent
93+ contentHeight: controlsColumn.height
94+ Column {
95+ id: controlsColumn
93− spacing: units.gu(1)
96+ spacing: units.gu(1)
94−
97+
95− Button {
98+ Button {
96− color: "white"
99+ color: "white"
97− text: "Make surface slow to resize"
100+ text: "Make surface slow to resize"
98− activeFocusOnPress: false
101+ activeFocusOnPress: false
99− onClicked: {
102+ onClicked: {
100− if (ApplicationManager.focusedApplicationId) {
103+ if (ApplicationManager.focusedApplicationId) {
101− var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.surface;
104+ var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.surface;
102− surface.slowToResize = true;
105+ surface.slowToResize = true;
106+ }
103 }
107 }
104 }
108 }
105− }
106
109
107− EdgeBarrierControls {
110+ EdgeBarrierControls {
108− id: edgeBarrierControls
111+ id: edgeBarrierControls
109− text: "Drag here to pull out spread"
112+ text: "Drag here to pull out spread"
110− backgroundColor: "blue"
113+ backgroundColor: "blue"
111− onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
114+ onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
112− }
115+ }
113
116
114− Divider {}
117+ Divider {}
115
118
116− Repeater {
119+ Repeater {
117− model: ApplicationManager.availableApplications
120+ model: ApplicationManager.availableApplications
118− ApplicationCheckBox {
121+ ApplicationCheckBox {
119− appId: modelData
122+ appId: modelData
123+ }
120 }
124 }
125+
126+ SurfaceManagerControls { textColor: "white" }
121 }
127 }
122 }
128 }
123 }
129 }
tests/qmltests/Stages/tst_WindowResizeArea.qml+225−30
@@ -28,7 +28,7 @@ import Unity.Application 0.1
28Item {
28Item {
29 id: root
29 id: root
30 height: units.gu(60)
30 height: units.gu(60)
31− width: units.gu(60)
31+ width: units.gu(85)
32
32
33 Binding {
33 Binding {
34 target: PanelState
34 target: PanelState
@@ -41,14 +41,20 @@ Item {
41
41
42 Item {
42 Item {
43 id: fakeWindow
43 id: fakeWindow
44− property alias minWidth: windowResizeArea.minWidth
44+ property alias resizeAreaMinWidth: windowResizeArea.minWidth
45− property alias minHeight: windowResizeArea.minHeight
45+ property alias resizeAreaMinHeight: windowResizeArea.minHeight
46 x: units.gu(20)
46 x: units.gu(20)
47 y: units.gu(20)
47 y: units.gu(20)
48 width: requestedWidth
48 width: requestedWidth
49 height: requestedHeight
49 height: requestedHeight
50 property real requestedWidth
50 property real requestedWidth
51 property real requestedHeight
51 property real requestedHeight
52+ property real minimumWidth: 0
53+ property real minimumHeight: 0
54+ property real maximumWidth: 0
55+ property real maximumHeight: 0
56+ property real widthIncrement: 0
57+ property real heightIncrement: 0
52 state: "normal"
58 state: "normal"
53
59
54 function maximize() {
60 function maximize() {
@@ -80,6 +86,10 @@ Item {
80 anchors.fill: parent
86 anchors.fill: parent
81 hoverEnabled: true
87 hoverEnabled: true
82 }
88 }
89+ Text {
90+ text: parent.width + "x" + parent.height
91+ color: "white"
92+ }
83 }
93 }
84 }
94 }
85 }
95 }
@@ -90,27 +100,107 @@ Item {
90 active: windowLoaderCheckbox.checked
100 active: windowLoaderCheckbox.checked
91 }
101 }
92
102
103+ Rectangle {
104+ anchors.right: parent.right
105+ anchors.top: parent.top
106+ anchors.bottom: parent.bottom
107+ width: units.gu(25)
108+ color: "lightgrey"
93− Column {
109+ Column {
110+ width: parent.width
111+ spacing: units.gu(1)
94− MouseTouchEmulationCheckbox {
112+ MouseTouchEmulationCheckbox {
95− checked: false
113+ checked: false
96− color: "black"
114+ color: "black"
97− }
115+ }
98− RowLayout {
116+ RowLayout {
99− Layout.fillWidth: true
117+ Layout.fillWidth: true
100− CheckBox {
118+ CheckBox {
101− id: windowLoaderCheckbox
119+ id: windowLoaderCheckbox
102− checked: true
120+ checked: true
103− activeFocusOnPress: false
121+ activeFocusOnPress: false
122+ }
123+ Label {
124+ color: "black"
125+ text: "Window loader active"
126+ anchors.verticalCenter: parent.verticalCenter
127+ }
104 }
128 }
105 Label {
129 Label {
106− id: label
130+ color: "black"; font.bold: true
131+ text: "Size Hints:"
132+ }
133+ SizeHintField { id: minWidthText; text: "min width" }
134+ SizeHintField { id: maxWidthText; text: "max width" }
135+ SizeHintField { id: minHeightText; text: "min height" }
136+ SizeHintField { id: maxHeightText; text: "max height" }
137+ SizeHintField { id: widthIncrText; text: "width incr" }
138+ SizeHintField { id: heightIncrText; text: "height incr" }
139+ Button {
107 color: "black"
140 color: "black"
108− text: "Window loader active"
141+ anchors.horizontalCenter: parent.horizontalCenter
109− anchors.verticalCenter: parent.verticalCenter
142+ text: "Apply"
143+ onClicked: {
144+ var value = parseInt(minWidthText.value);
145+ if (isNaN(value)) {
146+ windowLoader.item.minimumWidth = 0;
147+ } else {
148+ windowLoader.item.resizeAreaMinWidth = 1; // get it out of the way
149+ windowLoader.item.minimumWidth = value;
150+ }
151+
152+ value = parseInt(maxWidthText.value);
153+ if (isNaN(value)) {
154+ windowLoader.item.maximumWidth = 0;
155+ } else {
156+ windowLoader.item.maximumWidth = value;
157+ }
158+
159+ value = parseInt(minHeightText.value);
160+ if (isNaN(value)) {
161+ windowLoader.item.minimumHeight = 0;
162+ } else {
163+ windowLoader.item.resizeAreaMinHeight = 1; // get it out of the way
164+ windowLoader.item.minimumHeight = value;
165+ }
166+
167+ value = parseInt(maxHeightText.value);
168+ if (isNaN(value)) {
169+ windowLoader.item.maximumHeight = 0;
170+ } else {
171+ windowLoader.item.maximumHeight = value;
172+ }
173+
174+ value = parseInt(widthIncrText.value);
175+ if (isNaN(value)) {
176+ windowLoader.item.widthIncrement = 0;
177+ } else {
178+ windowLoader.item.widthIncrement = value;
179+ }
180+
181+ value = parseInt(heightIncrText.value);
182+ if (isNaN(value)) {
183+ windowLoader.item.heightIncrement = 0;
184+ } else {
185+ windowLoader.item.heightIncrement = value;
186+ }
187+ }
110 }
188 }
111 }
189 }
112 }
190 }
113
191
192+ SignalSpy {
193+ id: windowRequestedWidthSpy
194+ target: windowLoader.item
195+ signalName: "onRequestedWidthChanged"
196+ }
197+
198+ SignalSpy {
199+ id: windowRequestedHeightSpy
200+ target: windowLoader.item
201+ signalName: "onRequestedHeightChanged"
202+ }
203+
114 UnityTestCase {
204 UnityTestCase {
115 name: "WindowResizeArea"
205 name: "WindowResizeArea"
116 when: windowShown
206 when: windowShown
@@ -122,6 +212,18 @@ Item {
122 fakeWindow.y = units.gu(20)
212 fakeWindow.y = units.gu(20)
123 fakeWindow.requestedWidth = units.gu(20)
213 fakeWindow.requestedWidth = units.gu(20)
124 fakeWindow.requestedHeight = units.gu(20)
214 fakeWindow.requestedHeight = units.gu(20)
215+ fakeWindow.resizeAreaMinWidth = units.gu(15);
216+ fakeWindow.resizeAreaMinHeight = units.gu(10);
217+ fakeWindow.minimumWidth = 0;
218+ fakeWindow.minimumHeight = 0;
219+ fakeWindow.maximumWidth = 0;
220+ fakeWindow.maximumHeight = 0;
221+ fakeWindow.widthIncrement = 0;
222+ fakeWindow.heightIncrement = 0;
223+
224+ // Our test window resizes instantly
225+ compare(fakeWindow.width, fakeWindow.requestedWidth);
226+ compare(fakeWindow.height, fakeWindow.requestedHeight);
125 }
227 }
126
228
127 function test_resizeWindowRightBottom_data() {
229 function test_resizeWindowRightBottom_data() {
@@ -143,8 +245,8 @@ Item {
143 var startDragY = initialWindowY + initialWindowHeight + 1
245 var startDragY = initialWindowY + initialWindowHeight + 1
144 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
246 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
145
247
146− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.minWidth));
248+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
147− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.minHeight));
249+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
148
250
149 compare(fakeWindow.x, initialWindowX);
251 compare(fakeWindow.x, initialWindowX);
150 compare(fakeWindow.y, initialWindowY);
252 compare(fakeWindow.y, initialWindowY);
@@ -169,11 +271,11 @@ Item {
169 var startDragY = initialWindowY - 1
271 var startDragY = initialWindowY - 1
170 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
272 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
171
273
172− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.minWidth));
274+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.resizeAreaMinWidth));
173− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.minHeight));
275+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.resizeAreaMinHeight));
174
276
175− var maxMoveX = initialWindowWidth - fakeWindow.minWidth;
277+ var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
176− var maxMoveY = initialWindowHeight - fakeWindow.minHeight;
278+ var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
177 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
279 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
178 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
280 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
179 }
281 }
@@ -189,8 +291,8 @@ Item {
189 var startDragY = initialWindowY + initialWindowHeight + 1
291 var startDragY = initialWindowY + initialWindowHeight + 1
190 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
292 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
191
293
192− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
294+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
193− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
295+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
194
296
195 // This will destroy the window and recreate it
297 // This will destroy the window and recreate it
196 windowLoader.active = false;
298 windowLoader.active = false;
@@ -198,8 +300,8 @@ Item {
198 windowLoader.active = true;
300 windowLoader.active = true;
199
301
200 // Make sure its size is again the same as before
302 // Make sure its size is again the same as before
201− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
303+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
202− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
304+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
203 }
305 }
204
306
205 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
307 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
@@ -220,8 +322,8 @@ Item {
220 var startDragX = initialWindowX + data.startX
322 var startDragX = initialWindowX + data.startX
221 var startDragY = initialWindowY + data.startY
323 var startDragY = initialWindowY + data.startY
222 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
324 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
223− tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
325+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.resizeAreaMinWidth));
224− tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
326+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.resizeAreaMinHeight));
225 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
327 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
226 tryCompare(fakeWindow, "width", initialWindowWidth);
328 tryCompare(fakeWindow, "width", initialWindowWidth);
227 tryCompare(fakeWindow, "height", initialWindowHeight);
329 tryCompare(fakeWindow, "height", initialWindowHeight);
@@ -257,7 +359,6 @@ Item {
257 fakeWindow.state = "normal"
359 fakeWindow.state = "normal"
258 }
360 }
259
361
260−
261 function test_restoreMovesIntoBounds_data() {
362 function test_restoreMovesIntoBounds_data() {
262 return [
363 return [
263 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
364 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
@@ -290,5 +391,99 @@ Item {
290
391
291 waitForRendering(root)
392 waitForRendering(root)
292 }
393 }
394+
395+ /*
396+ Tests that even though you dragged the window bottom right corner continously (ie,
397+ through multiple intermediate steps), its (requested) width and height changed only
398+ once. And, furthermore, its dimensions increased by a multiple of its size (width
399+ and height) increment value.
400+ */
401+ function test_sizeIncrement() {
402+ var initialWindowX = fakeWindow.x;
403+ var initialWindowY = fakeWindow.y;
404+ var initialWindowWidth = fakeWindow.width
405+ var initialWindowHeight = fakeWindow.height
406+
407+ fakeWindow.widthIncrement = 70;
408+ fakeWindow.heightIncrement = 70;
409+
410+ var startDragX = initialWindowX + initialWindowWidth + 1
411+ var startDragY = initialWindowY + initialWindowHeight + 1
412+ var deltaX = 100;
413+ var deltaY = 100;
414+
415+ windowRequestedWidthSpy.clear();
416+ verify(windowRequestedWidthSpy.valid);
417+
418+ windowRequestedHeightSpy.clear();
419+ verify(windowRequestedHeightSpy.valid);
420+
421+ mouseFlick(root, startDragX, startDragY, startDragX + deltaX, startDragY + deltaY, true, true, units.gu(.5), 10);
422+
423+ compare(windowRequestedWidthSpy.count, 1);
424+ compare(fakeWindow.width, initialWindowWidth + fakeWindow.widthIncrement);
425+ compare(windowRequestedHeightSpy.count, 1);
426+ compare(fakeWindow.height, initialWindowHeight + fakeWindow.heightIncrement);
427+ }
428+
429+ /*
430+ Tests that when dragging a window border you cannot make it bigger than its maximum size
431+ */
432+ function test_maximumSize() {
433+ fakeWindow.x = units.gu(1);
434+ fakeWindow.y = units.gu(1);
435+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
436+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
437+ fakeWindow.requestedWidth = units.gu(10);
438+ fakeWindow.requestedHeight = units.gu(10);
439+
440+ fakeWindow.maximumWidth = units.gu(20);
441+ fakeWindow.maximumHeight = units.gu(20);
442+
443+ // Our test window resizes instantly
444+ compare(fakeWindow.width, fakeWindow.requestedWidth);
445+ compare(fakeWindow.height, fakeWindow.requestedHeight);
446+
447+ var startDragX = fakeWindow.width + 1
448+ var startDragY = fakeWindow.height + 1
449+ var endDragX = (fakeWindow.maximumWidth * 2) + 1;
450+ var endDragY = (fakeWindow.maximumHeight * 2) + 1;
451+
452+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
453+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
454+
455+ compare(fakeWindow.requestedWidth, fakeWindow.maximumWidth);
456+ compare(fakeWindow.requestedHeight, fakeWindow.maximumHeight);
457+ }
458+
459+ /*
460+ Tests that when dragging a window border you cannot make it smaller than its minimum size
461+ */
462+ function test_minimumSize() {
463+ fakeWindow.x = units.gu(1);
464+ fakeWindow.y = units.gu(1);
465+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
466+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
467+ fakeWindow.requestedWidth = units.gu(20);
468+ fakeWindow.requestedHeight = units.gu(20);
469+
470+ fakeWindow.minimumWidth = units.gu(10);
471+ fakeWindow.minimumHeight = units.gu(10);
472+
473+ // Our test window resizes instantly
474+ compare(fakeWindow.width, fakeWindow.requestedWidth);
475+ compare(fakeWindow.height, fakeWindow.requestedHeight);
476+
477+ var startDragX = fakeWindow.width + 1
478+ var startDragY = fakeWindow.height + 1
479+ var endDragX = (fakeWindow.minimumWidth * 0.5) + 1;
480+ var endDragY = (fakeWindow.minimumHeight * 0.5) + 1;
481+
482+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
483+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
484+
485+ compare(fakeWindow.requestedWidth, fakeWindow.minimumWidth);
486+ compare(fakeWindow.requestedHeight, fakeWindow.minimumHeight);
487+ }
293 }
488 }
294}
489}