Merge lp:~dandrader/unity8/sizeHints into lp:unity8

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~dandrader/unity8/sizeHints
Merge into: lp:unity8
Diff against target: 1043 lines (+651/-80)
15 files modified
CMakeLists.txt (+1/-1)
debian/control (+3/-3)
qml/Stages/ApplicationWindow.qml (+7/-0)
qml/Stages/DecoratedWindow.qml (+7/-0)
qml/Stages/DesktopStage.qml (+6/-0)
qml/Stages/WindowResizeArea.qml (+95/-16)
tests/mocks/Unity/Application/MirSurface.cpp (+48/-0)
tests/mocks/Unity/Application/MirSurface.h (+21/-0)
tests/mocks/Unity/Application/SurfaceManager.cpp (+56/-0)
tests/mocks/Unity/Application/SurfaceManager.h (+40/-0)
tests/qmltests/Stages/SizeHintField.qml (+33/-0)
tests/qmltests/Stages/SurfaceManagerControls.qml (+33/-0)
tests/qmltests/Stages/SurfaceManagerField.qml (+40/-0)
tests/qmltests/Stages/tst_DesktopStage.qml (+36/-30)
tests/qmltests/Stages/tst_WindowResizeArea.qml (+225/-30)
To merge this branch: bzr merge lp:~dandrader/unity8/sizeHints
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Albert Astals Cid (community) merges fine Abstain
Lukáš Tinkl (community) Approve
Review via email: mp+278743@code.launchpad.net

This proposal has been superseded by a proposal from 2016-02-03.

Commit message

Window Size Hints

Description of the change

* Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~dandrader/unity-api/surfaceItemSizeHints/+merge/278740
https://code.launchpad.net/~dandrader/qtmir/sizeHints/+merge/278741

* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes.

Run "make tryWindowResizeArea" and "make tryDesktopStage"

For live testing, use the test application in lp:~dandrader/+junk/sizeHintsDemo
Build it with "qmake && make"
Run "./sizeHintsDemo --help" for command line options.

There are two things to test:
1 - size hints set at start up (use command line for that)
2 - size hints set/changed while after the window has been shown. Use GUI for that.

* Did you make sure that your branch does not contain spurious tags?
Yes

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable

* If you changed the UI, has there been a design review?
Not applicable

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Text conflict in qml/Stages/DesktopStage.qml
Text conflict in tests/qmltests/Stages/tst_DesktopStage.qml
2 conflicts encountered.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 30/11/2015 06:30, Albert Astals Cid wrote:
> Text conflict in qml/Stages/DesktopStage.qml
> Text conflict in tests/qmltests/Stages/tst_DesktopStage.qml
> 2 conflicts encountered.

Fixed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

+++ qml/Stages/WindowResizeArea.qml

+ property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth

(and the others in the private "d" object)

Shouldn't they be readonly? After all they just calculate and return values

review: Needs Information
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 01/12/2015 14:28, Lukáš Tinkl wrote:
> Review: Needs Information
>
> +++ qml/Stages/WindowResizeArea.qml
>
> + property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
>
> (and the others in the private "d" object)
>
> Shouldn't they be readonly? After all they just calculate and return values

Right, done.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

In make tryShell, I can't type anything into the controls that should set the min/max width/height. The controls just don't accept any input

review: Needs Fixing
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Also, the description mentions "make tryWindowSizeHint" which doesn't exist, co can't test either :/

review: Needs Fixing
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

Tested it with a real app (dialer) which has both minimum and maximum size set. Resizing works fine within those bounds but the window can still be maximized... which kind of defeats the purpose of restricting the window width/height. I guess this needs fixing too

review: Needs Fixing
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

After some discussion, let's leave the window flags for later, when the window management situation settles a bit.

* Did you perform an exploratory manual test run of the code change and any related functionality?

Yes

* Did CI run pass? If not, please explain why.

No, unsatisfied unity-api version

* Did you make sure that the branch does not contain spurious tags?

Yes

review: Approve
Revision history for this message
Albert Astals Cid (aacid) wrote :

Note for later: This was already top-approved

Text conflict in tests/qmltests/Stages/tst_DesktopStage.qml
1 conflicts encountered.

review: Needs Fixing
lp:~dandrader/unity8/sizeHints updated
2077. By Daniel d'Andrada

Merge trunk

[ Albert Astals Cid ]
* Allow dragging launcher items with the quicklist open (LP: #1250861)
* Create ratings on demand instead of all at the same time (LP:
  #1519898, #1492214)
* LVWPH: Process correctly section changes (LP: #1519893)
* Make sure that unfavoriting a scope gives us the next one
* Move images only used in tests to tests folder
[ Andrea Cimitan ]
* Add shadows to ubuntu store icon
[ Daniel d'Andrada ]
* MirSurfaceItem got a new property: fillMode (LP: #1497083)
* Session can have multiple surfaces now
* plugins/Cursor: Do not force loading a specific cursor size (LP:
  #1517878)
[ Lukáš Tinkl ]
* Indicators convergence: use the "phone" profile everywhere (LP:
  #1520492)
[ Michael Terry ]
* Let qtmir know which apps are exempt from the lifecycle management.
  This way, it can manage its own wakelocks better (and stop
  preventing the system from deep sleeping).
[ Michael Zanetti ]
* Use proper z ordering instead of app index for occlusion detection
* add some debug prints to the uinput backend
* drop the ignoredMice hack again (LP: #1521580)
[ Michał Sawicz ]
* Let qtmir know which apps are exempt from the lifecycle management.
  This way, it can manage its own wakelocks better (and stop
  preventing the system from deep sleeping).
* Update .pot file in debian/clean when in train
* Rebuild against Qt 5.5.1.

2078. By Daniel d'Andrada

Update unity-api version requirements

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> Note for later: This was already top-approved
>
> Text conflict in tests/qmltests/Stages/tst_DesktopStage.qml
> 1 conflicts encountered.

Fixed.

Revision history for this message
Albert Astals Cid (aacid) wrote :

Re-top approving since it merges fine now.

review: Abstain (merges fine)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)

Unmerged revisions

2078. By Daniel d'Andrada

Update unity-api version requirements

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-12-03 19:36:58 +0000
3+++ CMakeLists.txt 2015-12-14 10:37:31 +0000
4@@ -57,7 +57,7 @@
5 find_package(Qt5Concurrent 5.4 REQUIRED)
6 find_package(Qt5Sql 5.4 REQUIRED)
7
8-pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=12)
9+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
10
11 # Standard install paths
12 include(GNUInstallDirs)
13
14=== modified file 'debian/control'
15--- debian/control 2015-12-08 15:37:20 +0000
16+++ debian/control 2015-12-14 10:37:31 +0000
17@@ -29,7 +29,7 @@
18 libqt5xmlpatterns5-dev,
19 libsystemsettings-dev,
20 libudev-dev,
21- libunity-api-dev (>= 7.104),
22+ libunity-api-dev (>= 7.105),
23 libusermetricsoutput1-dev,
24 libxcb1-dev,
25 pkg-config,
26@@ -128,7 +128,7 @@
27 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= 1.3.1627) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles (>= 1.3.1627),
28 qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
29 ubuntu-thumbnailer-impl-0,
30- unity-application-impl-12,
31+ unity-application-impl-13,
32 unity-notifications-impl-3,
33 unity-plugin-scopes | unity-scopes-impl,
34 unity-scopes-impl-7,
35@@ -174,7 +174,7 @@
36 Depends: ${misc:Depends},
37 ${shlibs:Depends},
38 Provides: unity-application-impl,
39- unity-application-impl-12,
40+ unity-application-impl-13,
41 Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1)
42 Description: Fake environment for running Unity 8 shell
43 Provides fake implementations of some QML modules used by Unity 8 shell
44
45=== modified file 'qml/Stages/ApplicationWindow.qml'
46--- qml/Stages/ApplicationWindow.qml 2015-11-23 13:52:39 +0000
47+++ qml/Stages/ApplicationWindow.qml 2015-12-14 10:37:31 +0000
48@@ -37,6 +37,13 @@
49 property int requestedWidth: -1
50 property int requestedHeight: -1
51
52+ readonly property int minimumWidth: sessionContainer.surface ? sessionContainer.surface.minimumWidth : 0
53+ readonly property int minimumHeight: sessionContainer.surface ? sessionContainer.surface.minimumHeight : 0
54+ readonly property int maximumWidth: sessionContainer.surface ? sessionContainer.surface.maximumWidth : 0
55+ readonly property int maximumHeight: sessionContainer.surface ? sessionContainer.surface.maximumHeight : 0
56+ readonly property int widthIncrement: sessionContainer.surface ? sessionContainer.surface.widthIncrement : 0
57+ readonly property int heightIncrement: sessionContainer.surface ? sessionContainer.surface.heightIncrement : 0
58+
59 QtObject {
60 id: d
61
62
63=== modified file 'qml/Stages/DecoratedWindow.qml'
64--- qml/Stages/DecoratedWindow.qml 2015-11-23 15:09:45 +0000
65+++ qml/Stages/DecoratedWindow.qml 2015-12-14 10:37:31 +0000
66@@ -39,6 +39,13 @@
67 property alias requestedWidth: applicationWindow.requestedWidth
68 property real requestedHeight
69
70+ property alias minimumWidth: applicationWindow.minimumWidth
71+ readonly property int minimumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.minimumHeight
72+ property alias maximumWidth: applicationWindow.maximumWidth
73+ readonly property int maximumHeight: (root.decorationShown ? decoration.height : 0) + applicationWindow.maximumHeight
74+ property alias widthIncrement: applicationWindow.widthIncrement
75+ property alias heightIncrement: applicationWindow.heightIncrement
76+
77 signal close()
78 signal maximize()
79 signal minimize()
80
81=== modified file 'qml/Stages/DesktopStage.qml'
82--- qml/Stages/DesktopStage.qml 2015-11-30 17:27:47 +0000
83+++ qml/Stages/DesktopStage.qml 2015-12-14 10:37:31 +0000
84@@ -247,6 +247,12 @@
85 height: decoratedWindow.height
86 property alias requestedWidth: decoratedWindow.requestedWidth
87 property alias requestedHeight: decoratedWindow.requestedHeight
88+ property alias minimumWidth: decoratedWindow.minimumWidth
89+ property alias minimumHeight: decoratedWindow.minimumHeight
90+ property alias maximumWidth: decoratedWindow.maximumWidth
91+ property alias maximumHeight: decoratedWindow.maximumHeight
92+ property alias widthIncrement: decoratedWindow.widthIncrement
93+ property alias heightIncrement: decoratedWindow.heightIncrement
94
95 QtObject {
96 id: appDelegatePrivate
97
98=== modified file 'qml/Stages/WindowResizeArea.qml'
99--- qml/Stages/WindowResizeArea.qml 2015-11-23 13:52:39 +0000
100+++ qml/Stages/WindowResizeArea.qml 2015-12-14 10:37:31 +0000
101@@ -72,8 +72,8 @@
102 var windowGeometry = windowStateStorage.getGeometry(root.windowId,
103 Qt.rect(target.x, target.y, defaultWidth, defaultHeight));
104
105- target.requestedWidth = Math.min(Math.max(windowGeometry.width, minWidth), screenWidth);
106- target.requestedHeight = Math.min(Math.max(windowGeometry.height, minHeight), root.screenHeight - PanelState.panelHeight);
107+ target.requestedWidth = Math.min(Math.max(windowGeometry.width, d.minimumWidth), screenWidth);
108+ target.requestedHeight = Math.min(Math.max(windowGeometry.height, d.minimumHeight), root.screenHeight - PanelState.panelHeight);
109 target.x = Math.max(Math.min(windowGeometry.x, root.screenWidth - target.requestedWidth), 0)
110 target.y = Math.max(Math.min(windowGeometry.y, root.screenHeight - target.requestedHeight), PanelState.panelHeight)
111
112@@ -91,6 +91,65 @@
113
114 QtObject {
115 id: d
116+
117+ readonly property int maxSafeInt: 2147483647
118+ readonly property int maxSizeIncrement: units.gu(40)
119+
120+ readonly property int minimumWidth: root.target ? Math.max(root.minWidth, root.target.minimumWidth) : root.minWidth
121+ onMinimumWidthChanged: {
122+ if (target.requestedWidth < minimumWidth) {
123+ target.requestedWidth = minimumWidth;
124+ }
125+ }
126+ readonly property int minimumHeight: root.target ? Math.max(root.minHeight, root.target.minimumHeight) : root.minHeight
127+ onMinimumHeightChanged: {
128+ if (target.requestedHeight < minimumHeight) {
129+ target.requestedHeight = minimumHeight;
130+ }
131+ }
132+ readonly property int maximumWidth: root.target && root.target.maximumWidth >= minimumWidth && root.target.maximumWidth > 0
133+ ? root.target.maximumWidth : maxSafeInt
134+ onMaximumWidthChanged: {
135+ if (target.requestedWidth > maximumWidth) {
136+ target.requestedWidth = maximumWidth;
137+ }
138+ }
139+ readonly property int maximumHeight: root.target && root.target.maximumHeight >= minimumHeight && root.target.maximumHeight > 0
140+ ? root.target.maximumHeight : maxSafeInt
141+ onMaximumHeightChanged: {
142+ if (target.requestedHeight > maximumHeight) {
143+ target.requestedHeight = maximumHeight;
144+ }
145+ }
146+ readonly property int widthIncrement: {
147+ if (!root.target) {
148+ return 1;
149+ }
150+ if (root.target.widthIncrement > 0) {
151+ if (root.target.widthIncrement < maxSizeIncrement) {
152+ return root.target.widthIncrement;
153+ } else {
154+ return maxSizeIncrement;
155+ }
156+ } else {
157+ return 1;
158+ }
159+ }
160+ readonly property int heightIncrement: {
161+ if (!root.target) {
162+ return 1;
163+ }
164+ if (root.target.heightIncrement > 0) {
165+ if (root.target.heightIncrement < maxSizeIncrement) {
166+ return root.target.heightIncrement;
167+ } else {
168+ return maxSizeIncrement;
169+ }
170+ } else {
171+ return 1;
172+ }
173+ }
174+
175 property bool leftBorder: false
176 property bool rightBorder: false
177 property bool topBorder: false
178@@ -209,38 +268,58 @@
179
180 var pos = mapToItem(target.parent, mouse.x, mouse.y);
181
182- var deltaX = pos.x - d.startMousePosX;
183- var deltaY = pos.y - d.startMousePosY;
184+ var deltaX = Math.floor((pos.x - d.startMousePosX) / d.widthIncrement) * d.widthIncrement;
185+ var deltaY = Math.floor((pos.y - d.startMousePosY) / d.heightIncrement) * d.heightIncrement;
186
187 if (d.leftBorder) {
188 var newTargetX = d.startX + deltaX;
189- if (target.x + target.width > newTargetX + minWidth) {
190- target.requestedWidth = target.x + target.width - newTargetX;
191+ var rightBorderX = target.x + target.width;
192+ if (rightBorderX > newTargetX + d.minimumWidth) {
193+ if (rightBorderX < newTargetX + d.maximumWidth) {
194+ target.requestedWidth = rightBorderX - newTargetX;
195+ } else {
196+ target.requestedWidth = d.maximumWidth;
197+ }
198 } else {
199- target.requestedWidth = minWidth;
200+ target.requestedWidth = d.minimumWidth;
201 }
202
203 } else if (d.rightBorder) {
204- if (d.startWidth + deltaX >= minWidth) {
205- target.requestedWidth = d.startWidth + deltaX;
206+ var newWidth = d.startWidth + deltaX;
207+ if (newWidth > d.minimumWidth) {
208+ if (newWidth < d.maximumWidth) {
209+ target.requestedWidth = newWidth;
210+ } else {
211+ target.requestedWidth = d.maximumWidth;
212+ }
213 } else {
214- target.requestedWidth = minWidth;
215+ target.requestedWidth = d.minimumWidth;
216 }
217 }
218
219 if (d.topBorder) {
220 var newTargetY = d.startY + deltaY;
221- if (target.y + target.height > newTargetY + minHeight) {
222- target.requestedHeight = target.y + target.height - newTargetY;
223+ var bottomBorderY = target.y + target.height;
224+ if (bottomBorderY > newTargetY + d.minimumHeight) {
225+ if (bottomBorderY < newTargetY + d.maximumHeight) {
226+ target.requestedHeight = bottomBorderY - newTargetY;
227+ } else {
228+ target.requestedHeight = d.maximumHeight;
229+ }
230 } else {
231- target.requestedHeight = minHeight;
232+ target.requestedHeight = d.minimumHeight;
233 }
234
235 } else if (d.bottomBorder) {
236- if (d.startHeight + deltaY >= minHeight) {
237- target.requestedHeight = d.startHeight + deltaY;
238+ var newHeight = d.startHeight + deltaY;
239+ if (newHeight > d.minimumHeight) {
240+ if (newHeight < d.maximumHeight) {
241+ target.requestedHeight = newHeight;
242+ } else {
243+ target.requestedHeight = d.maximumHeight;
244+ }
245 } else {
246- target.requestedHeight = minHeight;
247+ target.requestedHeight = d.minimumHeight;
248 }
249 }
250 }
251
252=== modified file 'tests/mocks/Unity/Application/MirSurface.cpp'
253--- tests/mocks/Unity/Application/MirSurface.cpp 2015-11-06 15:52:24 +0000
254+++ tests/mocks/Unity/Application/MirSurface.cpp 2015-12-14 10:37:31 +0000
255@@ -266,3 +266,51 @@
256 }
257 }
258 }
259+
260+void MirSurface::setMinimumWidth(int value)
261+{
262+ if (value != m_minimumWidth) {
263+ m_minimumWidth = value;
264+ Q_EMIT minimumWidthChanged(m_minimumWidth);
265+ }
266+}
267+
268+void MirSurface::setMaximumWidth(int value)
269+{
270+ if (value != m_maximumWidth) {
271+ m_maximumWidth = value;
272+ Q_EMIT maximumWidthChanged(m_maximumWidth);
273+ }
274+}
275+
276+void MirSurface::setMinimumHeight(int value)
277+{
278+ if (value != m_minimumHeight) {
279+ m_minimumHeight = value;
280+ Q_EMIT minimumHeightChanged(m_minimumHeight);
281+ }
282+}
283+
284+void MirSurface::setMaximumHeight(int value)
285+{
286+ if (value != m_maximumHeight) {
287+ m_maximumHeight = value;
288+ Q_EMIT maximumHeightChanged(m_maximumHeight);
289+ }
290+}
291+
292+void MirSurface::setWidthIncrement(int value)
293+{
294+ if (value != m_widthIncrement) {
295+ m_widthIncrement = value;
296+ Q_EMIT widthIncrementChanged(m_widthIncrement);
297+ }
298+}
299+
300+void MirSurface::setHeightIncrement(int value)
301+{
302+ if (value != m_heightIncrement) {
303+ m_heightIncrement = value;
304+ Q_EMIT heightIncrementChanged(m_heightIncrement);
305+ }
306+}
307
308=== modified file 'tests/mocks/Unity/Application/MirSurface.h'
309--- tests/mocks/Unity/Application/MirSurface.h 2015-11-06 15:52:24 +0000
310+++ tests/mocks/Unity/Application/MirSurface.h 2015-12-14 10:37:31 +0000
311@@ -66,6 +66,13 @@
312 Mir::OrientationAngle orientationAngle() const override;
313 void setOrientationAngle(Mir::OrientationAngle) override;
314
315+ int minimumWidth() const override { return m_minimumWidth; }
316+ int minimumHeight() const override { return m_minimumHeight; }
317+ int maximumWidth() const override { return m_maximumWidth; }
318+ int maximumHeight() const override { return m_maximumHeight; }
319+ int widthIncrement() const override { return m_widthIncrement; }
320+ int heightIncrement() const override { return m_heightIncrement; }
321+
322 ////
323 // API for tests
324
325@@ -82,6 +89,13 @@
326 bool isSlowToResize() const;
327 void setSlowToResize(bool value);
328
329+ Q_INVOKABLE void setMinimumWidth(int);
330+ Q_INVOKABLE void setMaximumWidth(int);
331+ Q_INVOKABLE void setMinimumHeight(int);
332+ Q_INVOKABLE void setMaximumHeight(int);
333+ Q_INVOKABLE void setWidthIncrement(int);
334+ Q_INVOKABLE void setHeightIncrement(int);
335+
336 /////
337 // internal mock stuff
338
339@@ -125,6 +139,13 @@
340 int m_width;
341 int m_height;
342
343+ int m_minimumWidth{0};
344+ int m_minimumHeight{0};
345+ int m_maximumWidth{0};
346+ int m_maximumHeight{0};
347+ int m_widthIncrement{0};
348+ int m_heightIncrement{0};
349+
350 bool m_slowToResize;
351 QTimer m_delayedResizeTimer;
352 QSize m_delayedResize;
353
354=== modified file 'tests/mocks/Unity/Application/SurfaceManager.cpp'
355--- tests/mocks/Unity/Application/SurfaceManager.cpp 2015-09-02 08:04:41 +0000
356+++ tests/mocks/Unity/Application/SurfaceManager.cpp 2015-12-14 10:37:31 +0000
357@@ -46,6 +46,14 @@
358 MirSurface* surface = qobject_cast<MirSurface*>(obj);
359 Q_EMIT surfaceDestroyed(surface);
360 });
361+
362+ surface->setMinimumWidth(m_newSurfaceMinimumWidth);
363+ surface->setMaximumWidth(m_newSurfaceMaximumWidth);
364+ surface->setMinimumHeight(m_newSurfaceMinimumHeight);
365+ surface->setMaximumHeight(m_newSurfaceMaximumHeight);
366+ surface->setWidthIncrement(m_newSurfaceWidthIncrement);
367+ surface->setHeightIncrement(m_newSurfaceHeightIncrement);
368+
369 Q_EMIT surfaceCreated(surface);
370 return surface;
371 }
372@@ -62,3 +70,51 @@
373 }
374 return m_virtualKeyboard;
375 }
376+
377+void SurfaceManager::setNewSurfaceMinimumWidth(int value)
378+{
379+ if (m_newSurfaceMinimumWidth != value) {
380+ m_newSurfaceMinimumWidth = value;
381+ Q_EMIT newSurfaceMinimumWidthChanged(m_newSurfaceMinimumWidth);
382+ }
383+}
384+
385+void SurfaceManager::setNewSurfaceMaximumWidth(int value)
386+{
387+ if (m_newSurfaceMaximumWidth != value) {
388+ m_newSurfaceMaximumWidth = value;
389+ Q_EMIT newSurfaceMaximumWidthChanged(m_newSurfaceMaximumWidth);
390+ }
391+}
392+
393+void SurfaceManager::setNewSurfaceMinimumHeight(int value)
394+{
395+ if (m_newSurfaceMinimumHeight != value) {
396+ m_newSurfaceMinimumHeight = value;
397+ Q_EMIT newSurfaceMinimumHeightChanged(m_newSurfaceMinimumHeight);
398+ }
399+}
400+
401+void SurfaceManager::setNewSurfaceMaximumHeight(int value)
402+{
403+ if (m_newSurfaceMaximumHeight != value) {
404+ m_newSurfaceMaximumHeight = value;
405+ Q_EMIT newSurfaceMaximumHeightChanged(m_newSurfaceMaximumHeight);
406+ }
407+}
408+
409+void SurfaceManager::setNewSurfaceWidthIncrement(int value)
410+{
411+ if (m_newSurfaceWidthIncrement != value) {
412+ m_newSurfaceWidthIncrement = value;
413+ Q_EMIT newSurfaceWidthIncrementChanged(m_newSurfaceWidthIncrement);
414+ }
415+}
416+
417+void SurfaceManager::setNewSurfaceHeightIncrement(int value)
418+{
419+ if (m_newSurfaceHeightIncrement != value) {
420+ m_newSurfaceHeightIncrement = value;
421+ Q_EMIT newSurfaceHeightIncrementChanged(m_newSurfaceHeightIncrement);
422+ }
423+}
424
425=== modified file 'tests/mocks/Unity/Application/SurfaceManager.h'
426--- tests/mocks/Unity/Application/SurfaceManager.h 2015-08-03 15:00:47 +0000
427+++ tests/mocks/Unity/Application/SurfaceManager.h 2015-12-14 10:37:31 +0000
428@@ -25,6 +25,14 @@
429 class SurfaceManager : public QObject
430 {
431 Q_OBJECT
432+
433+ Q_PROPERTY(int newSurfaceMinimumWidth READ newSurfaceMinimumWidth WRITE setNewSurfaceMinimumWidth NOTIFY newSurfaceMinimumWidthChanged)
434+ Q_PROPERTY(int newSurfaceMaximumWidth READ newSurfaceMaximumWidth WRITE setNewSurfaceMaximumWidth NOTIFY newSurfaceMaximumWidthChanged)
435+ Q_PROPERTY(int newSurfaceMinimumHeight READ newSurfaceMinimumHeight WRITE setNewSurfaceMinimumHeight NOTIFY newSurfaceMinimumHeightChanged)
436+ Q_PROPERTY(int newSurfaceMaximumHeight READ newSurfaceMaximumHeight WRITE setNewSurfaceMaximumHeight NOTIFY newSurfaceMaximumHeightChanged)
437+ Q_PROPERTY(int newSurfaceWidthIncrement READ newSurfaceWidthIncrement WRITE setNewSurfaceWidthIncrement NOTIFY newSurfaceWidthIncrementChanged)
438+ Q_PROPERTY(int newSurfaceHeightIncrement READ newSurfaceHeightIncrement WRITE setNewSurfaceHeightIncrement NOTIFY newSurfaceHeightIncrementChanged)
439+
440 public:
441 explicit SurfaceManager(QObject *parent = 0);
442
443@@ -38,14 +46,46 @@
444 // To be used in the tests
445 Q_INVOKABLE MirSurface* inputMethodSurface();
446
447+ int newSurfaceMinimumWidth() const { return m_newSurfaceMinimumWidth; }
448+ void setNewSurfaceMinimumWidth(int value);
449+
450+ int newSurfaceMaximumWidth() const { return m_newSurfaceMaximumWidth; }
451+ void setNewSurfaceMaximumWidth(int value);
452+
453+ int newSurfaceMinimumHeight() const { return m_newSurfaceMinimumHeight; }
454+ void setNewSurfaceMinimumHeight(int value);
455+
456+ int newSurfaceMaximumHeight() const { return m_newSurfaceMaximumHeight; }
457+ void setNewSurfaceMaximumHeight(int value);
458+
459+ int newSurfaceWidthIncrement() const { return m_newSurfaceWidthIncrement; }
460+ void setNewSurfaceWidthIncrement(int);
461+
462+ int newSurfaceHeightIncrement() const { return m_newSurfaceHeightIncrement; }
463+ void setNewSurfaceHeightIncrement(int);
464+
465 Q_SIGNALS:
466 void countChanged();
467 void surfaceCreated(MirSurface *surface);
468 void surfaceDestroyed(MirSurface*surface);
469
470+ void newSurfaceMinimumWidthChanged(int value);
471+ void newSurfaceMaximumWidthChanged(int value);
472+ void newSurfaceMinimumHeightChanged(int value);
473+ void newSurfaceMaximumHeightChanged(int value);
474+ void newSurfaceWidthIncrementChanged(int value);
475+ void newSurfaceHeightIncrementChanged(int value);
476+
477 private:
478 static SurfaceManager *the_surface_manager;
479 VirtualKeyboard *m_virtualKeyboard;
480+
481+ int m_newSurfaceMinimumWidth{0};
482+ int m_newSurfaceMaximumWidth{0};
483+ int m_newSurfaceMinimumHeight{0};
484+ int m_newSurfaceMaximumHeight{0};
485+ int m_newSurfaceWidthIncrement{1};
486+ int m_newSurfaceHeightIncrement{1};
487 };
488
489 #endif // SURFACEMANAGER_H
490
491=== added file 'tests/qmltests/Stages/SizeHintField.qml'
492--- tests/qmltests/Stages/SizeHintField.qml 1970-01-01 00:00:00 +0000
493+++ tests/qmltests/Stages/SizeHintField.qml 2015-12-14 10:37:31 +0000
494@@ -0,0 +1,33 @@
495+/*
496+ * Copyright 2015 Canonical Ltd.
497+ *
498+ * This program is free software; you can redistribute it and/or modify
499+ * it under the terms of the GNU General Public License as published by
500+ * the Free Software Foundation; version 3.
501+ *
502+ * This program is distributed in the hope that it will be useful,
503+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
504+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
505+ * GNU General Public License for more details.
506+ *
507+ * You should have received a copy of the GNU General Public License
508+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
509+ */
510+
511+import QtQuick 2.4
512+import QtQuick.Layouts 1.1
513+import Ubuntu.Components 1.3
514+
515+Row {
516+ property alias text: label.text
517+ property alias value: field.text
518+ spacing: units.gu(1)
519+ Label {
520+ id: label
521+ color: "black"; anchors.verticalCenter: parent.verticalCenter
522+ }
523+ TextField {
524+ id: field
525+ text: ""; width: units.gu(8); hasClearButton: false; maximumLength: 6; inputMask: "d00000"
526+ }
527+}
528
529=== added file 'tests/qmltests/Stages/SurfaceManagerControls.qml'
530--- tests/qmltests/Stages/SurfaceManagerControls.qml 1970-01-01 00:00:00 +0000
531+++ tests/qmltests/Stages/SurfaceManagerControls.qml 2015-12-14 10:37:31 +0000
532@@ -0,0 +1,33 @@
533+/*
534+ * Copyright (C) 2015 Canonical, Ltd.
535+ *
536+ * This program is free software; you can redistribute it and/or modify
537+ * it under the terms of the GNU General Public License as published by
538+ * the Free Software Foundation; version 3.
539+ *
540+ * This program is distributed in the hope that it will be useful,
541+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
542+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
543+ * GNU General Public License for more details.
544+ *
545+ * You should have received a copy of the GNU General Public License
546+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
547+ */
548+
549+import QtQuick 2.4
550+import Ubuntu.Components 1.3
551+import Unity.Application 0.1
552+
553+Column {
554+ id: root
555+ property color textColor: "black"
556+
557+ Label {text: "Size hints for new surface:"; color: root.textColor; font.bold: true}
558+
559+ SurfaceManagerField { text: "min width"; propertyName: "newSurfaceMinimumWidth"; textColor: root.textColor }
560+ SurfaceManagerField { text: "max width"; propertyName: "newSurfaceMaximumWidth"; textColor: root.textColor }
561+ SurfaceManagerField { text: "min height"; propertyName: "newSurfaceMinimumHeight"; textColor: root.textColor }
562+ SurfaceManagerField { text: "max height"; propertyName: "newSurfaceMaximumHeight"; textColor: root.textColor }
563+ SurfaceManagerField { text: "width increment"; propertyName: "newSurfaceWidthIncrement"; textColor: root.textColor }
564+ SurfaceManagerField { text: "height increment"; propertyName: "newSurfaceHeightIncrement"; textColor: root.textColor }
565+}
566
567=== added file 'tests/qmltests/Stages/SurfaceManagerField.qml'
568--- tests/qmltests/Stages/SurfaceManagerField.qml 1970-01-01 00:00:00 +0000
569+++ tests/qmltests/Stages/SurfaceManagerField.qml 2015-12-14 10:37:31 +0000
570@@ -0,0 +1,40 @@
571+/*
572+ * Copyright (C) 2015 Canonical, Ltd.
573+ *
574+ * This program is free software; you can redistribute it and/or modify
575+ * it under the terms of the GNU General Public License as published by
576+ * the Free Software Foundation; version 3.
577+ *
578+ * This program is distributed in the hope that it will be useful,
579+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
580+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
581+ * GNU General Public License for more details.
582+ *
583+ * You should have received a copy of the GNU General Public License
584+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
585+ */
586+
587+import QtQuick 2.4
588+import Ubuntu.Components 1.3
589+import Unity.Application 0.1
590+
591+Row {
592+ id: root
593+ property alias textColor: label.color
594+ property alias text: label.text
595+ property string propertyName
596+
597+ Label {id: label; anchors.verticalCenter: parent.verticalCenter}
598+ TextField {
599+ width: units.gu(10); hasClearButton: false; maximumLength: 6
600+ inputMask: "d00000"
601+ text: ""
602+ onTextChanged: {
603+ if (text.length > 0) {
604+ SurfaceManager[root.propertyName] = parseInt(text);
605+ } else {
606+ SurfaceManager[root.propertyName] = 0;
607+ }
608+ }
609+ }
610+}
611
612=== modified file 'tests/qmltests/Stages/tst_DesktopStage.qml'
613--- tests/qmltests/Stages/tst_DesktopStage.qml 2015-12-08 15:37:51 +0000
614+++ tests/qmltests/Stages/tst_DesktopStage.qml 2015-12-14 10:37:31 +0000
615@@ -88,36 +88,42 @@
616 right: parent.right
617 }
618
619- Column {
620- anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
621- spacing: units.gu(1)
622-
623- Button {
624- color: "white"
625- text: "Make surface slow to resize"
626- activeFocusOnPress: false
627- onClicked: {
628- if (ApplicationManager.focusedApplicationId) {
629- var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
630- surface.slowToResize = true;
631- }
632- }
633- }
634-
635- EdgeBarrierControls {
636- id: edgeBarrierControls
637- text: "Drag here to pull out spread"
638- backgroundColor: "blue"
639- onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
640- }
641-
642- Divider {}
643-
644- Repeater {
645- model: ApplicationManager.availableApplications
646- ApplicationCheckBox {
647- appId: modelData
648- }
649+ Flickable {
650+ anchors.fill: parent
651+ contentHeight: controlsColumn.height
652+ Column {
653+ id: controlsColumn
654+ spacing: units.gu(1)
655+
656+ Button {
657+ color: "white"
658+ text: "Make surface slow to resize"
659+ activeFocusOnPress: false
660+ onClicked: {
661+ if (ApplicationManager.focusedApplicationId) {
662+ var surface = ApplicationManager.findApplication(ApplicationManager.focusedApplicationId).session.lastSurface;
663+ surface.slowToResize = true;
664+ }
665+ }
666+ }
667+
668+ EdgeBarrierControls {
669+ id: edgeBarrierControls
670+ text: "Drag here to pull out spread"
671+ backgroundColor: "blue"
672+ onDragged: { desktopStageLoader.item.pushRightEdge(amount); }
673+ }
674+
675+ Divider {}
676+
677+ Repeater {
678+ model: ApplicationManager.availableApplications
679+ ApplicationCheckBox {
680+ appId: modelData
681+ }
682+ }
683+
684+ SurfaceManagerControls { textColor: "white" }
685 }
686 }
687 }
688
689=== modified file 'tests/qmltests/Stages/tst_WindowResizeArea.qml'
690--- tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-11-20 13:04:46 +0000
691+++ tests/qmltests/Stages/tst_WindowResizeArea.qml 2015-12-14 10:37:31 +0000
692@@ -28,7 +28,7 @@
693 Item {
694 id: root
695 height: units.gu(60)
696- width: units.gu(60)
697+ width: units.gu(85)
698
699 Binding {
700 target: PanelState
701@@ -41,14 +41,20 @@
702
703 Item {
704 id: fakeWindow
705- property alias minWidth: windowResizeArea.minWidth
706- property alias minHeight: windowResizeArea.minHeight
707+ property alias resizeAreaMinWidth: windowResizeArea.minWidth
708+ property alias resizeAreaMinHeight: windowResizeArea.minHeight
709 x: units.gu(20)
710 y: units.gu(20)
711 width: requestedWidth
712 height: requestedHeight
713 property real requestedWidth
714 property real requestedHeight
715+ property real minimumWidth: 0
716+ property real minimumHeight: 0
717+ property real maximumWidth: 0
718+ property real maximumHeight: 0
719+ property real widthIncrement: 0
720+ property real heightIncrement: 0
721 state: "normal"
722
723 function maximize() {
724@@ -80,6 +86,10 @@
725 anchors.fill: parent
726 hoverEnabled: true
727 }
728+ Text {
729+ text: parent.width + "x" + parent.height
730+ color: "white"
731+ }
732 }
733 }
734 }
735@@ -90,27 +100,107 @@
736 active: windowLoaderCheckbox.checked
737 }
738
739- Column {
740- MouseTouchEmulationCheckbox {
741- checked: false
742- color: "black"
743- }
744- RowLayout {
745- Layout.fillWidth: true
746- CheckBox {
747- id: windowLoaderCheckbox
748- checked: true
749- activeFocusOnPress: false
750+ Rectangle {
751+ anchors.right: parent.right
752+ anchors.top: parent.top
753+ anchors.bottom: parent.bottom
754+ width: units.gu(25)
755+ color: "lightgrey"
756+ Column {
757+ width: parent.width
758+ spacing: units.gu(1)
759+ MouseTouchEmulationCheckbox {
760+ checked: false
761+ color: "black"
762+ }
763+ RowLayout {
764+ Layout.fillWidth: true
765+ CheckBox {
766+ id: windowLoaderCheckbox
767+ checked: true
768+ activeFocusOnPress: false
769+ }
770+ Label {
771+ color: "black"
772+ text: "Window loader active"
773+ anchors.verticalCenter: parent.verticalCenter
774+ }
775 }
776 Label {
777- id: label
778+ color: "black"; font.bold: true
779+ text: "Size Hints:"
780+ }
781+ SizeHintField { id: minWidthText; text: "min width" }
782+ SizeHintField { id: maxWidthText; text: "max width" }
783+ SizeHintField { id: minHeightText; text: "min height" }
784+ SizeHintField { id: maxHeightText; text: "max height" }
785+ SizeHintField { id: widthIncrText; text: "width incr" }
786+ SizeHintField { id: heightIncrText; text: "height incr" }
787+ Button {
788 color: "black"
789- text: "Window loader active"
790- anchors.verticalCenter: parent.verticalCenter
791+ anchors.horizontalCenter: parent.horizontalCenter
792+ text: "Apply"
793+ onClicked: {
794+ var value = parseInt(minWidthText.value);
795+ if (isNaN(value)) {
796+ windowLoader.item.minimumWidth = 0;
797+ } else {
798+ windowLoader.item.resizeAreaMinWidth = 1; // get it out of the way
799+ windowLoader.item.minimumWidth = value;
800+ }
801+
802+ value = parseInt(maxWidthText.value);
803+ if (isNaN(value)) {
804+ windowLoader.item.maximumWidth = 0;
805+ } else {
806+ windowLoader.item.maximumWidth = value;
807+ }
808+
809+ value = parseInt(minHeightText.value);
810+ if (isNaN(value)) {
811+ windowLoader.item.minimumHeight = 0;
812+ } else {
813+ windowLoader.item.resizeAreaMinHeight = 1; // get it out of the way
814+ windowLoader.item.minimumHeight = value;
815+ }
816+
817+ value = parseInt(maxHeightText.value);
818+ if (isNaN(value)) {
819+ windowLoader.item.maximumHeight = 0;
820+ } else {
821+ windowLoader.item.maximumHeight = value;
822+ }
823+
824+ value = parseInt(widthIncrText.value);
825+ if (isNaN(value)) {
826+ windowLoader.item.widthIncrement = 0;
827+ } else {
828+ windowLoader.item.widthIncrement = value;
829+ }
830+
831+ value = parseInt(heightIncrText.value);
832+ if (isNaN(value)) {
833+ windowLoader.item.heightIncrement = 0;
834+ } else {
835+ windowLoader.item.heightIncrement = value;
836+ }
837+ }
838 }
839 }
840 }
841
842+ SignalSpy {
843+ id: windowRequestedWidthSpy
844+ target: windowLoader.item
845+ signalName: "onRequestedWidthChanged"
846+ }
847+
848+ SignalSpy {
849+ id: windowRequestedHeightSpy
850+ target: windowLoader.item
851+ signalName: "onRequestedHeightChanged"
852+ }
853+
854 UnityTestCase {
855 name: "WindowResizeArea"
856 when: windowShown
857@@ -122,6 +212,18 @@
858 fakeWindow.y = units.gu(20)
859 fakeWindow.requestedWidth = units.gu(20)
860 fakeWindow.requestedHeight = units.gu(20)
861+ fakeWindow.resizeAreaMinWidth = units.gu(15);
862+ fakeWindow.resizeAreaMinHeight = units.gu(10);
863+ fakeWindow.minimumWidth = 0;
864+ fakeWindow.minimumHeight = 0;
865+ fakeWindow.maximumWidth = 0;
866+ fakeWindow.maximumHeight = 0;
867+ fakeWindow.widthIncrement = 0;
868+ fakeWindow.heightIncrement = 0;
869+
870+ // Our test window resizes instantly
871+ compare(fakeWindow.width, fakeWindow.requestedWidth);
872+ compare(fakeWindow.height, fakeWindow.requestedHeight);
873 }
874
875 function test_resizeWindowRightBottom_data() {
876@@ -143,8 +245,8 @@
877 var startDragY = initialWindowY + initialWindowHeight + 1
878 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
879
880- tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.minWidth));
881- tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.minHeight));
882+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + data.dx, fakeWindow.resizeAreaMinWidth));
883+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + data.dy, fakeWindow.resizeAreaMinHeight));
884
885 compare(fakeWindow.x, initialWindowX);
886 compare(fakeWindow.y, initialWindowY);
887@@ -169,11 +271,11 @@
888 var startDragY = initialWindowY - 1
889 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, true, units.gu(.5), 10);
890
891- tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.minWidth));
892- tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.minHeight));
893+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - data.dx, fakeWindow.resizeAreaMinWidth));
894+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - data.dy, fakeWindow.resizeAreaMinHeight));
895
896- var maxMoveX = initialWindowWidth - fakeWindow.minWidth;
897- var maxMoveY = initialWindowHeight - fakeWindow.minHeight;
898+ var maxMoveX = initialWindowWidth - fakeWindow.resizeAreaMinWidth;
899+ var maxMoveY = initialWindowHeight - fakeWindow.resizeAreaMinHeight;
900 compare(fakeWindow.x, Math.min(initialWindowX + data.dx, initialWindowX + maxMoveX));
901 compare(fakeWindow.y, Math.min(initialWindowY + data.dy, initialWindowY + maxMoveY));
902 }
903@@ -189,8 +291,8 @@
904 var startDragY = initialWindowY + initialWindowHeight + 1
905 mouseFlick(root, startDragX, startDragY, startDragX + resizeDelta, startDragY + resizeDelta, true, true, units.gu(.5), 10);
906
907- tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
908- tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
909+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
910+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
911
912 // This will destroy the window and recreate it
913 windowLoader.active = false;
914@@ -198,8 +300,8 @@
915 windowLoader.active = true;
916
917 // Make sure its size is again the same as before
918- tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.minWidth));
919- tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.minHeight));
920+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth + resizeDelta, fakeWindow.resizeAreaMinWidth));
921+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight + resizeDelta, fakeWindow.resizeAreaMinHeight));
922 }
923
924 // This tests if dragging smaller than minSize and then larger again, will keep the edge sticking
925@@ -220,8 +322,8 @@
926 var startDragX = initialWindowX + data.startX
927 var startDragY = initialWindowY + data.startY
928 mouseFlick(root, startDragX, startDragY, startDragX + data.dx, startDragY + data.dy, true, false, units.gu(.05), 10);
929- tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.minWidth));
930- tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.minHeight));
931+ tryCompare(fakeWindow, "width", Math.max(initialWindowWidth - Math.abs(data.dx), fakeWindow.resizeAreaMinWidth));
932+ tryCompare(fakeWindow, "height", Math.max(initialWindowHeight - Math.abs(data.dy), fakeWindow.resizeAreaMinHeight));
933 mouseFlick(root, startDragX + data.dx, startDragY + data.dy, startDragX, startDragY, false, true, units.gu(.05), 10);
934 tryCompare(fakeWindow, "width", initialWindowWidth);
935 tryCompare(fakeWindow, "height", initialWindowHeight);
936@@ -257,7 +359,6 @@
937 fakeWindow.state = "normal"
938 }
939
940-
941 function test_restoreMovesIntoBounds_data() {
942 return [
943 {tag: "left off", x: -units.gu(5), y: units.gu(5), w: units.gu(10), h: units.gu(10)},
944@@ -290,5 +391,99 @@
945
946 waitForRendering(root)
947 }
948+
949+ /*
950+ Tests that even though you dragged the window bottom right corner continously (ie,
951+ through multiple intermediate steps), its (requested) width and height changed only
952+ once. And, furthermore, its dimensions increased by a multiple of its size (width
953+ and height) increment value.
954+ */
955+ function test_sizeIncrement() {
956+ var initialWindowX = fakeWindow.x;
957+ var initialWindowY = fakeWindow.y;
958+ var initialWindowWidth = fakeWindow.width
959+ var initialWindowHeight = fakeWindow.height
960+
961+ fakeWindow.widthIncrement = 70;
962+ fakeWindow.heightIncrement = 70;
963+
964+ var startDragX = initialWindowX + initialWindowWidth + 1
965+ var startDragY = initialWindowY + initialWindowHeight + 1
966+ var deltaX = 100;
967+ var deltaY = 100;
968+
969+ windowRequestedWidthSpy.clear();
970+ verify(windowRequestedWidthSpy.valid);
971+
972+ windowRequestedHeightSpy.clear();
973+ verify(windowRequestedHeightSpy.valid);
974+
975+ mouseFlick(root, startDragX, startDragY, startDragX + deltaX, startDragY + deltaY, true, true, units.gu(.5), 10);
976+
977+ compare(windowRequestedWidthSpy.count, 1);
978+ compare(fakeWindow.width, initialWindowWidth + fakeWindow.widthIncrement);
979+ compare(windowRequestedHeightSpy.count, 1);
980+ compare(fakeWindow.height, initialWindowHeight + fakeWindow.heightIncrement);
981+ }
982+
983+ /*
984+ Tests that when dragging a window border you cannot make it bigger than its maximum size
985+ */
986+ function test_maximumSize() {
987+ fakeWindow.x = units.gu(1);
988+ fakeWindow.y = units.gu(1);
989+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
990+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
991+ fakeWindow.requestedWidth = units.gu(10);
992+ fakeWindow.requestedHeight = units.gu(10);
993+
994+ fakeWindow.maximumWidth = units.gu(20);
995+ fakeWindow.maximumHeight = units.gu(20);
996+
997+ // Our test window resizes instantly
998+ compare(fakeWindow.width, fakeWindow.requestedWidth);
999+ compare(fakeWindow.height, fakeWindow.requestedHeight);
1000+
1001+ var startDragX = fakeWindow.width + 1
1002+ var startDragY = fakeWindow.height + 1
1003+ var endDragX = (fakeWindow.maximumWidth * 2) + 1;
1004+ var endDragY = (fakeWindow.maximumHeight * 2) + 1;
1005+
1006+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
1007+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
1008+
1009+ compare(fakeWindow.requestedWidth, fakeWindow.maximumWidth);
1010+ compare(fakeWindow.requestedHeight, fakeWindow.maximumHeight);
1011+ }
1012+
1013+ /*
1014+ Tests that when dragging a window border you cannot make it smaller than its minimum size
1015+ */
1016+ function test_minimumSize() {
1017+ fakeWindow.x = units.gu(1);
1018+ fakeWindow.y = units.gu(1);
1019+ fakeWindow.resizeAreaMinWidth = 1; // so it does not interfere with anything
1020+ fakeWindow.resizeAreaMinHeight = 1; // so it does not interfere with anything
1021+ fakeWindow.requestedWidth = units.gu(20);
1022+ fakeWindow.requestedHeight = units.gu(20);
1023+
1024+ fakeWindow.minimumWidth = units.gu(10);
1025+ fakeWindow.minimumHeight = units.gu(10);
1026+
1027+ // Our test window resizes instantly
1028+ compare(fakeWindow.width, fakeWindow.requestedWidth);
1029+ compare(fakeWindow.height, fakeWindow.requestedHeight);
1030+
1031+ var startDragX = fakeWindow.width + 1
1032+ var startDragY = fakeWindow.height + 1
1033+ var endDragX = (fakeWindow.minimumWidth * 0.5) + 1;
1034+ var endDragY = (fakeWindow.minimumHeight * 0.5) + 1;
1035+
1036+ mouseFlick(fakeWindow, startDragX, startDragY, endDragX, endDragY,
1037+ true/*pressMouse*/, true/*releaseMouse*/, units.gu(.5)/*speed*/, 20/*iterations*/);
1038+
1039+ compare(fakeWindow.requestedWidth, fakeWindow.minimumWidth);
1040+ compare(fakeWindow.requestedHeight, fakeWindow.minimumHeight);
1041+ }
1042 }
1043 }

Subscribers

People subscribed via source and target branches