on xenial help sign in
Merge pull request #355 from ubports/xenial_-_qt-5-12

Fixes for Qt 5.12 migration

commitf821fd2ee66e2ffc0a9d30ec311f7f03430cf3ec authorMarius Gripsgard <marius@ubports.com> dateSun 17 Jan 2021, 03:02 (6 years ago) parent3741ec233d9fd1
58 files changed+823−989
debian/control+206−189 debian/rules+12 debian/tests/control+5−3 debian/unity8-greeter.install+1−1 debian/unity8-private.install+1−1 debian/unity8.install+6−6 plugins/Utils/windowstatestorage.cpp+13−31 plugins/Utils/windowstatestorage.h+1−7 po/unity8.pot−12 qml/ApplicationMenus/ApplicationMenuItemFactory.qml+7−7 qml/ApplicationMenus/RegisteredApplicationMenuModel.qml+1−1 qml/Components/KeyboardShortcutsOverlay.qml−24 qml/Components/ResponsiveGridView.qml−98 qml/Components/Showable.qml+4−4 qml/Launcher/DrawerGridView.qml+2−3 qml/Launcher/LauncherDelegate.qml+1−3 qml/Launcher/LauncherPanel.qml+3−4 qml/Panel/Indicators/IndicatorMenuItemFactory.qml+3−3 qml/Panel/Indicators/IndicatorsLight.qml+2−2 qml/Panel/PanelMenuPage.qml+1−1 qml/Shell.qml+1−1 qml/Stage/MoveHandler.qml+7−7 qml/Stage/Splash.qml+4−4 qml/Stage/Stage.qml+2−2 qml/Stage/WindowDecoration.qml+5−6 qml/Tutorial/TutorialContent.qml+8−8 qml/Tutorial/TutorialLeft.qml+1−1 qml/Tutorial/TutorialLeftLong.qml+1−1 qml/Tutorial/TutorialTop.qml+2−2 qml/Wizard/Pages/30-wifi.qml+4−5 qml/Wizard/Pages/50-timezone.qml+9−11 tests/mocks/GSettings.1.0/fake_gsettings.cpp+22−5 tests/mocks/GSettings.1.0/fake_gsettings.h+8−6 tests/mocks/Unity/Application/SurfaceManager.cpp+3 tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.cpp+2−2 tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.h+1−1 tests/mocks/Wizard/CMakeLists.txt+1 tests/mocks/Wizard/MockSystem.cpp+7−1 tests/mocks/Wizard/MockSystem.h+4 tests/mocks/Wizard/mockplugin.cpp+2 tests/plugins/Utils/WindowStateStorageTest.cpp+1−1 tests/qmltests/ApplicationMenuDataLoader.qml+1−1 tests/qmltests/CMakeLists.txt−1 tests/qmltests/Components/tst_ResponsiveGridView.qml−157 tests/qmltests/Launcher/tst_Launcher.qml+91−31 tests/qmltests/Notifications/tst_Notifications.qml+2−1 tests/qmltests/Notifications/tst_SwipeToAct.qml+2−1 tests/qmltests/Panel/PanelUI.qml+1−1 tests/qmltests/Panel/tst_PanelMenuPage.qml+1−1 tests/qmltests/Stage/ApplicationCheckBox.qml+6−6 tests/qmltests/Stage/tst_ApplicationWindow.qml+3−2 tests/qmltests/Stage/tst_PhoneStage.qml+5−4 tests/qmltests/Stage/tst_SurfaceContainer.qml+2−1 tests/qmltests/Stage/tst_WindowResizeArea.qml+2−1 tests/qmltests/tst_OrientedShell.qml+261−221 tests/qmltests/tst_ShellWithPin.qml+67−77 tests/utils/modules/Unity/Test/MouseTouchEmulationCheckbox.qml+1−1 tests/utils/modules/Unity/Test/StageTestCase.qml+14−18
debian/control+206−189
@@ -2,166 +2,171 @@ Source: unity8
22Section: x11
33Priority: optional
44Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5−Build-Depends: cmake,
6− cmake-extras,
7− dbus-test-runner,
8− debhelper (>= 9),
9− dh-apparmor,
10− doxyqml,
11−# To allow cross-compiling to work, we also must append :native
12−# to g++ so we don't try to run arm g++
13−# on an x86 CPU for example, when cross-compiling.
14− g++:native,
15− gdb,
16− graphviz,
17− gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
18− libandroid-properties-dev,
19− libconnectivity-qt1-dev (>= 0.7.1),
20− libevdev-dev,
21− libgeonames-dev (>= 0.2),
22− libgnome-desktop-3-dev,
23− libgl1-mesa-dev[!arm64 !armhf] | libgl-dev[!arm64 !armhf],
24− libgl1-mesa-dri,
25− libgles2-mesa-dev[arm64 armhf],
26− libglib2.0-dev,
27− libgsettings-qt-dev,
28− libhardware-dev,
29− liblightdm-qt5-3-dev,
30− libpam0g-dev,
31− libpulse-dev,
32− libqmenumodel-dev (>= 0.2.12),
33− libqtdbusmock1-dev (>= 0.7),
34− libqtdbustest1-dev,
35− libqt5svg5-dev,
36− libqt5xmlpatterns5-dev,
37− libsystemsettings-dev,
38− libubuntu-app-launch2-dev,
39− libubuntu-download-manager-common-dev,
40− libubuntugestures5-dev (>= 1.3.2030),
41− libubuntugestures5-private-dev (>= 1.3.2030),
42− libudev-dev,
43− libudm-common-dev,
44− libunity-api-dev (>= 8.7),
45− libusermetricsoutput1-dev,
46−# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
47− libx11-dev[!arm64 !armhf],
48− libxcb1-dev[!arm64 !armhf],
49− libxi-dev[!arm64 !armhf],
50−# End of X11 libs
51− pkg-config,
52− python3-all:any,
53− python3-setuptools,
54− qtdbustest-runner,
55− qml-module-qt-labs-folderlistmodel,
56− qml-module-qt-labs-settings,
57− qml-module-qtqml-statemachine,
58− qml-module-qtmultimedia (>= 5.6),
59− qml-module-qtquick-layouts,
60− qml-module-qtquick-xmllistmodel,
61− qml-module-qtquick2,
62− qml-module-qtsysteminfo,
63− qml-module-qttest,
64− qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
65− qml-module-ubuntu-layouts,
66− qml-module-ubuntu-test,
67− qt5-default,
68− qtbase5-dev (>= 5.6),
69− qtbase5-dev-tools,
70− qtbase5-private-dev (>= 5.6),
71− qtdeclarative5-dev (>= 5.6),
72− qtdeclarative5-dev-tools,
73− qtdeclarative5-private-dev (>= 5.6),
74− qtdeclarative5-ubuntu-content1,
75− qtdeclarative5-ubuntu-settings-components (>= 0.11),
76− ttf-ubuntu-font-family,
77− xvfb,
78− android-headers,
5+Build-Depends:
6+ android-headers,
7+ cmake,
8+ cmake-extras,
9+ dbus-test-runner,
10+ debhelper (>= 9),
11+ dh-apparmor,
12+ doxyqml,
13+ g++:native,
14+ gdb,
15+ graphviz,
16+ gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
17+ libandroid-properties-dev,
18+ libconnectivity-qt1-dev (>= 0.7.1),
19+ libevdev-dev,
20+ libgeonames-dev (>= 0.2),
21+ libgl1-mesa-dev[!arm64 !armhf] | libgl-dev[!arm64 !armhf],
22+ libgl1-mesa-dri,
23+ libgles2-mesa-dev[arm64 armhf],
24+ libglib2.0-dev,
25+ libgnome-desktop-3-dev,
26+ libgsettings-qt-dev,
27+ libhardware-dev,
28+ liblightdm-qt5-3-dev,
29+ libpam0g-dev,
30+ libpulse-dev,
31+ libqmenumodel-dev (>= 0.2.12),
32+ libqt5sql5-sqlite,
33+ libqt5svg5-dev,
34+ libqt5xmlpatterns5-dev,
35+ libqtdbusmock1-dev (>= 0.7),
36+ libqtdbustest1-dev,
37+ libsystemsettings-dev,
38+ libubuntu-app-launch2-dev,
39+ libubuntu-download-manager-common-dev,
40+ libubuntugestures5-dev (>= 1.3.2030),
41+ libubuntugestures5-private-dev (>= 1.3.2030),
42+ libudev-dev,
43+ libudm-common-dev,
44+ libunity-api-dev (>= 8.7),
45+ libusermetricsoutput1-dev,
46+ libx11-dev[!arm64 !armhf],
47+ libxcb1-dev[!arm64 !armhf],
48+ libxi-dev[!arm64 !armhf],
49+ pkg-config,
50+ python3-all:any,
51+ python3-setuptools,
52+ qml-module-qt-labs-folderlistmodel,
53+ qml-module-qt-labs-settings,
54+ qml-module-qtmultimedia (>= 5.6),
55+ qml-module-qtqml-statemachine,
56+ qml-module-qtquick-layouts,
57+ qml-module-qtquick-xmllistmodel,
58+ qml-module-qtquick2,
59+ qml-module-qtsysteminfo,
60+ qml-module-qttest,
61+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
62+ qml-module-ubuntu-layouts,
63+ qml-module-ubuntu-settings-components,
64+ qml-module-ubuntu-test,
65+ qtbase5-dev (>= 5.6),
66+ qtbase5-dev-tools,
67+ qtbase5-private-dev (>= 5.6),
68+ qtdbustest-runner,
69+ qtdeclarative5-dev (>= 5.6),
70+ qtdeclarative5-dev-tools,
71+ qtdeclarative5-private-dev (>= 5.6),
72+ qtdeclarative5-ubuntu-content1,
73+ ttf-ubuntu-font-family,
74+ ubports-wallpapers,
75+ xvfb,
7976Standards-Version: 3.9.4
80−Homepage: http://launchpad.net/unity
81−# If you aren't a member of ~unity-team but need to upload
82−# packaging changes, just go ahead. ~unity-team will notice
83−# and sync up the code again.
84−Vcs-Bzr: https://code.launchpad.net/unity8
85−Vcs-Browser: https://bazaar.launchpad.net/~unity-team/unity8/trunk
77+Homepage: https://github.com/ubports/unity8
78+Vcs-Git: https://github.com/ubports/unity8
8679XS-Testsuite: autopkgtest
8780X-Ubuntu-Use-Langpack: yes
8881
8982Package: indicators-client
9083Architecture: any
91−Depends: qmenumodel-qml (>= 0.2.11),
92− qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
93− unity8 (= ${binary:Version}),
94− ${misc:Depends},
95− ${shlibs:Depends},
84+Depends:
85+ qmenumodel-qml (>= 0.2.11),
86+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
87+ unity8 (= ${binary:Version}),
88+ ${misc:Depends},
89+ ${shlibs:Depends},
9690Description: Indicators client test application
9791 This package contains the client application for indicators used by autopilot
9892
9993Package: unity8-greeter
10094Architecture: any
101−Depends: unity8 (= ${binary:Version}),
102− unity-system-compositor,
103− ${misc:Depends},
104− ${shlibs:Depends}
105−Recommends: lightdm
106−Provides: lightdm-greeter
95+Depends:
96+ unity-system-compositor,
97+ unity8 (= ${binary:Version}),
98+ ${misc:Depends},
99+ ${shlibs:Depends},
100+Recommends:
101+ lightdm,
102+Provides:
103+ lightdm-greeter,
107104Description: The Unity8 Greeter
108105 The Unity 8 greeter is the primary login greeter for Ubuntu devices.
109106
110107Package: unity8
111108Architecture: any
112−Provides: indicator-renderer,
113−Depends: dmz-cursor-theme,
114− gsettings-desktop-schemas,
115− libcap2-bin,
116− libglib2.0-bin,
117− qmenumodel-qml (>= 0.2.11),
118− qml-module-biometryd,
119− qml-module-qt-labs-folderlistmodel,
120− qml-module-qt-labs-settings,
121− qml-module-qtqml-statemachine,
122− qml-module-qtquick-xmllistmodel,
123− qml-module-qtsysteminfo,
124−# qml-module-ubuntu-web,
125− qtdeclarative5-qtmir-plugin (>= 0.4.8),
126− qtdeclarative5-ubuntu-telephony0.1,
127− ubuntu-system-settings (>= 0.4),
128− unity-launcher-impl-13,
129− unity8-common (= ${source:Version}),
130− unity8-private (= ${binary:Version}),
131− unity8-private | unity-launcher-impl,
132− ${misc:Depends},
133− ${shlibs:Depends},
134−Recommends: indicator-keyboard,
135− indicator-session,
136− unity-greeter-session-broadcast,
137−Breaks: indicator-network (<< 0.5.1+14.10.20141014),
138− ubuntu-touch-session (<< 0.107),
139− unity8-greeter (<< 7.89),
140− unity-scope-tool,
141− ubuntu-keyboard (<< 0.100),
142−Replaces: ubuntu-touch-session (<< 0.82~),
143− unity8-greeter (<< 7.89),
144− unity-scope-tool,
145−Conflicts: ubuntu-system-settings-wizard,
109+Provides:
110+ indicator-renderer,
111+Depends:
112+ dmz-cursor-theme,
113+ gsettings-desktop-schemas,
114+ libcap2-bin,
115+ libglib2.0-bin,
116+ qmenumodel-qml (>= 0.2.11),
117+ qml-module-biometryd,
118+ qml-module-qt-labs-folderlistmodel,
119+ qml-module-qt-labs-settings,
120+ qml-module-qtqml-statemachine,
121+ qml-module-qtquick-xmllistmodel,
122+ qml-module-qtsysteminfo,
123+ qtdeclarative5-qtmir-plugin (>= 0.4.8),
124+ qtdeclarative5-ubuntu-telephony0.1,
125+ ubuntu-system-settings (>= 0.4),
126+ unity-launcher-impl-13,
127+ unity8-common (= ${source:Version}),
128+ unity8-private (= ${binary:Version}),
129+ unity8-private | unity-launcher-impl,
130+ ${misc:Depends},
131+ ${shlibs:Depends},
132+Recommends:
133+ indicator-keyboard,
134+ indicator-session,
135+ unity-greeter-session-broadcast,
136+Breaks:
137+ indicator-network (<< 0.5.1+14.10.20141014),
138+ ubuntu-keyboard (<< 0.100),
139+ ubuntu-touch-session (<< 0.107),
140+ unity-scope-tool,
141+ unity8-greeter (<< 7.89),
142+Replaces:
143+ ubuntu-touch-session (<< 0.82~),
144+ unity-scope-tool,
145+ unity8-greeter (<< 7.89),
146+Conflicts:
147+ ubuntu-system-settings-wizard,
146148Description: Unity 8 shell
147149 The Unity 8 shell is the primary user interface for Ubuntu devices.
148150
149151Package: unity8-common
150152Architecture: all
151−Depends: qml-module-qtquick-layouts,
152− qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
153− qml-module-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
154− qtdeclarative5-ubuntu-settings-components (>= 0.11),
155− qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
156− qttranslations5-l10n,
157− ubuntu-thumbnailer-impl-0,
158− unity-application-impl-27,
159− unity-notifications-impl-3,
160− unity8-tests | unity-application-impl,
161− unity8-schemas,
162− ${misc:Depends},
163−Breaks: unity8 (<< 7.86),
164−Replaces: unity8 (<< 7.86),
153+Depends:
154+ qml-module-qtquick-layouts,
155+ qml-module-ubuntu-components (>= 1.3.2030) | qml-module-ubuntu-components-gles (>= 1.3.2030),
156+ qml-module-ubuntu-settings-components,
157+ qml-module-ubuntu-thumbnailer0.1 | ubuntu-thumbnailer-impl,
158+ qtdeclarative5-unity-notifications-plugin (>= 0.1.2) | unity-notifications-impl,
159+ qttranslations5-l10n,
160+ ubuntu-thumbnailer-impl-0,
161+ unity-application-impl-27,
162+ unity-notifications-impl-3,
163+ unity8-schemas,
164+ unity8-tests | unity-application-impl,
165+ ${misc:Depends},
166+Breaks:
167+ unity8 (<< 7.86),
168+Replaces:
169+ unity8 (<< 7.86),
165170Description: Unity 8 shell (common files)
166171 The Unity 8 shell is the primary user interface for Ubuntu devices.
167172 .
@@ -169,46 +174,52 @@ Description: Unity 8 shell (common files)
169174
170175Package: unity8-autopilot
171176Architecture: all
172−Depends: autopilot-qt5 (>= 1.4),
173− gir1.2-glib-2.0,
174− gir1.2-notify-0.7,
175− libqt5test5,
176− libqt5widgets5,
177− ofono-phonesim,
178− python3-autopilot,
179− python3-evdev,
180− python3-fixtures,
181− python3-gi,
182− qttestability-autopilot (>= 1.4),
183− ubuntu-ui-toolkit-autopilot (>= 1.3.2030),
184− unity8 (= ${source:Version}),
185− unity8-tests (= ${source:Version}),
186− url-dispatcher-tools,
187− xvfb,
188− ${misc:Depends},
189− ${python3:Depends},
177+Depends:
178+ autopilot-qt5 (>= 1.4),
179+ gir1.2-glib-2.0,
180+ gir1.2-notify-0.7,
181+ libqt5test5,
182+ libqt5widgets5,
183+ ofono-phonesim,
184+ python3-autopilot,
185+ python3-evdev,
186+ python3-fixtures,
187+ python3-gi,
188+ qttestability-autopilot (>= 1.4),
189+ ubuntu-ui-toolkit-autopilot (>= 1.3.2030),
190+ unity8 (= ${source:Version}),
191+ unity8-tests (= ${source:Version}),
192+ url-dispatcher-tools,
193+ xvfb,
194+ ${misc:Depends},
195+ ${python3:Depends},
190196Description: Test package for Unity 8 shell
191197 Autopilot tests for the unity8 package
192198
193199Package: unity8-tests
194200Architecture: any
195201Multi-Arch: same
196−Pre-Depends: ${misc:Pre-Depends},
197−Depends: dbus-test-runner,
198− parallel,
199− qtdbustest-runner,
200− qt5-default,
201− qtdeclarative5-dev-tools,
202− unity8 (= ${source:Version}),
203− xvfb,
204− ${misc:Depends},
205− ${shlibs:Depends},
206−Provides: unity-application-impl,
207− unity-application-impl-27,
208− unity8-fake-env,
209−Replaces: unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1),
210− unity8-fake-env,
211−Conflicts: unity8-fake-env,
202+Pre-Depends:
203+ ${misc:Pre-Depends},
204+Depends:
205+ dbus-test-runner,
206+ parallel,
207+ qt5-default,
208+ qtdbustest-runner,
209+ qtdeclarative5-dev-tools,
210+ unity8 (= ${source:Version}),
211+ xvfb,
212+ ${misc:Depends},
213+ ${shlibs:Depends},
214+Provides:
215+ unity-application-impl,
216+ unity-application-impl-27,
217+ unity8-fake-env,
218+Replaces:
219+ unity8-autopilot (<< 8.02+15.04.20150422-0ubuntu1),
220+ unity8-fake-env,
221+Conflicts:
222+ unity8-fake-env,
212223Description: Scripts and mocks for running Unity 8 shell tests
213224 Provides fake implementations of some QML modules used by Unity 8 shell
214225 (e.g Ubuntu.Application) so that you can run it in a sandboxed environment
@@ -217,30 +228,35 @@ Description: Scripts and mocks for running Unity 8 shell tests
217228Package: unity8-private
218229Architecture: any
219230Multi-Arch: same
220−Pre-Depends: ${misc:Pre-Depends},
221−Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
222− gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
223− libhardware2,
224− unity8-schemas,
225− qtdeclarative5-gsettings1.0,
226− qml-module-qtmultimedia,
227− ${misc:Depends},
228− ${shlibs:Depends},
229−Provides: unity-launcher-impl,
230− unity-launcher-impl-13,
231+Pre-Depends:
232+ ${misc:Pre-Depends},
233+Depends:
234+ accountsservice-ubuntu-schemas (>= 0.0.7),
235+ gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
236+ libhardware2,
237+ qml-module-qtmultimedia,
238+ qtdeclarative5-gsettings1.0,
239+ unity8-schemas,
240+ ${misc:Depends},
241+ ${shlibs:Depends},
242+Provides:
243+ unity-launcher-impl,
244+ unity-launcher-impl-13,
231245Description: Unity 8 private libs
232246 The Unity 8 shell is the primary user interface for Ubuntu devices.
233247 .
234248 This package contains the private libraries for QML and other components
235249 only used by the shell.
236250
237−
238251Package: unity8-schemas
239252Architecture: all
240253Multi-Arch: foreign
241−Depends: ${misc:Depends},
242−Replaces: unity-schemas (>= 7.3.1+14.10.20140915),
243−Breaks: unity-schemas (>= 7.3.1+14.10.20140915),
254+Depends:
255+ ${misc:Depends},
256+Replaces:
257+ unity-schemas (>= 7.3.1+14.10.20140915),
258+Breaks:
259+ unity-schemas (>= 7.3.1+14.10.20140915),
244260Description: Unity 8 schemas
245261 The Unity 8 shell is the primary user interface for Ubuntu devices.
246262 .
@@ -250,6 +266,7 @@ Package: unity8-doc
250266Section: doc
251267Architecture: all
252268Multi-Arch: foreign
253−Depends: ${misc:Depends},
269+Depends:
270+ ${misc:Depends},
254271Description: Documentation for Unity8
255272 The Unity 8 shell is the primary user interface for Ubuntu devices. (documentation)
debian/rules+12
@@ -7,6 +7,12 @@ include /usr/share/dpkg/default.mk
77#export DH_VERBOSE=1
88export DPKG_GENSYMBOLS_CHECK_LEVEL=4
99export NO_PNG_PKG_MANGLE=1
10+export QT_SELECT=qt5
11+
12+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
13+
14+# Skip tests on the archs they are known to be flaky with current configuration
15+testskip_architectures := arm64 powerpc ppc64el s390x
1016
1117%:
1218 dh $@ --parallel --fail-missing --with python3
@@ -24,7 +30,13 @@ override_dh_auto_test:
2430 # Run the entire test battery
2531 # Parallel tests have a risk of starting xvfb on the same DISPLAY multiple times,
2632 # causing the whole battery to fail.
33+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
34+ifneq (,$(filter $(DEB_HOST_ARCH),$(testskip_architectures)))
35+ -dh_auto_test --no-parallel -- -O -k xvfballtests
36+else
2737 dh_auto_test --no-parallel -- -O -k xvfballtests
38+endif
39+endif
2840
2941override_dh_install:
3042 # install autopilot tests
debian/tests/control+5−3
@@ -1,9 +1,11 @@
11Tests: qmluitests.sh
22Restrictions: allow-stderr
3−Depends: dpkg-dev,
4− unity8-tests,
3+Depends:
4+ dpkg-dev,
5+ unity8-tests,
56
67Tests: autopilot.sh
78Restrictions: allow-stderr,
89 isolation-machine,
9−Depends: unity8-autopilot,
10+Depends:
11+ unity8-autopilot,
debian/unity8-greeter.install+1−1
@@ -1,5 +1,5 @@
1−data/unity8-greeter-wrapper usr/bin/
21data/unity8-greeter-init.conf usr/share/upstart/sessions/
2+data/unity8-greeter-wrapper usr/bin/
33data/unity8-greeter.pkla /var/lib/polkit-1/localauthority/10-vendor.d/
44usr/share/lightdm/greeters/unity8-greeter.desktop
55usr/share/lightdm/lightdm.conf.d/51-unity8-greeter.conf
debian/unity8-private.install+1−1
@@ -8,9 +8,9 @@ usr/lib/*/unity8/qml/Lights
88usr/lib/*/unity8/qml/Powerd
99usr/lib/*/unity8/qml/ScreenshotDirectory
1010usr/lib/*/unity8/qml/SessionBroadcast
11+usr/lib/*/unity8/qml/UInput
1112usr/lib/*/unity8/qml/Ubuntu
1213usr/lib/*/unity8/qml/Unity
13−usr/lib/*/unity8/qml/UInput
1414usr/lib/*/unity8/qml/Utils
1515usr/lib/*/unity8/qml/WindowManager
1616usr/lib/*/unity8/qml/Wizard
debian/unity8.install+6−6
@@ -1,19 +1,19 @@
1−var/lib/unity8/version
2−data/unity8-filewatcher.conf usr/share/upstart/sessions/
3−data/unity8.conf usr/share/upstart/sessions/
41data/devices.conf etc/ubuntu/
52data/test.sensors etc/ubuntusensors/
3+data/unity8-filewatcher.conf usr/share/upstart/sessions/
4+data/unity8.conf usr/share/upstart/sessions/
65usr/bin/unity8
76usr/share/applications/unity8.desktop
87usr/share/unity8/ApplicationMenus
8+usr/share/unity8/DeviceConfiguration.qml
9+usr/share/unity8/DisabledScreenNotice.qml
910usr/share/unity8/Greeter
1011usr/share/unity8/Launcher
12+usr/share/unity8/OrientedShell.qml
1113usr/share/unity8/Panel
1214usr/share/unity8/Rotation
13−usr/share/unity8/DeviceConfiguration.qml
14−usr/share/unity8/OrientedShell.qml
15−usr/share/unity8/DisabledScreenNotice.qml
1615usr/share/unity8/Shell.qml
1716usr/share/unity8/Stage
1817usr/share/unity8/Tutorial
1918usr/share/unity8/Wizard
19+var/lib/unity8/version
plugins/Utils/windowstatestorage.cpp+13−31
@@ -18,7 +18,6 @@
1818
1919#include <QtConcurrent>
2020#include <QDebug>
21−#include <QFutureSynchronizer>
2221#include <QSqlQuery>
2322#include <QSqlError>
2423#include <QSqlResult>
@@ -33,24 +32,23 @@ inline QString sanitiseString(QString string) {
3332 .remove(QLatin1Char('\\'));
3433}
3534
36−WindowStateStorage::WindowStateStorage(QObject *parent):
35+WindowStateStorage::WindowStateStorage(const QString& dbName, QObject *parent):
3736 QObject(parent)
3837{
3938 const QString dbPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/unity8/");
4039 m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"));
4140 QDir dir;
4241 dir.mkpath(dbPath);
43− m_db.setDatabaseName(dbPath + "windowstatestorage.sqlite");
42+ if (dbName != nullptr) {
43+ m_db.setDatabaseName(dbName);
44+ } else {
45+ m_db.setDatabaseName(dbPath + "windowstatestorage.sqlite");
46+ }
4447 initdb();
4548}
4649
4750WindowStateStorage::~WindowStateStorage()
4851{
49− QFutureSynchronizer<void> futureSync;
50− for (int i = 0; i < m_asyncQueries.count(); ++i) {
51− futureSync.addFuture(m_asyncQueries[i]);
52− }
53− futureSync.waitForFinished();
5452 m_db.close();
5553}
5654
@@ -110,19 +108,6 @@ int WindowStateStorage::getStage(const QString &appId, int defaultValue) const
110108 return query.value("stage").toInt();
111109}
112110
113−void WindowStateStorage::executeAsyncQuery(const QString &queryString)
114−{
115− QMutexLocker l(&s_mutex);
116− QSqlQuery query;
117−
118− bool ok = query.exec(queryString);
119− if (!ok) {
120− qWarning() << "Error executing query" << queryString
121− << "Driver error:" << query.lastError().driverText()
122− << "Database error:" << query.lastError().databaseText();
123− }
124−}
125−
126111QRect WindowStateStorage::getGeometry(const QString &windowId, const QRect &defaultValue) const
127112{
128113 QString queryString = QStringLiteral("SELECT * FROM geometry WHERE windowId = '%1';")
@@ -171,16 +156,13 @@ void WindowStateStorage::initdb()
171156void WindowStateStorage::saveValue(const QString &queryString)
172157{
173158 QMutexLocker mutexLocker(&s_mutex);
174−
175− QFuture<void> future = QtConcurrent::run(&m_threadPool, executeAsyncQuery, queryString);
176− m_asyncQueries.append(future);
177−
178− QFutureWatcher<void> *futureWatcher = new QFutureWatcher<void>();
179− futureWatcher->setFuture(future);
180− connect(futureWatcher, &QFutureWatcher<void>::finished,
181− this,
182− [=](){ m_asyncQueries.removeAll(futureWatcher->future());
183− futureWatcher->deleteLater(); });
159+ QSqlQuery query;
160+ auto ok = query.exec(queryString);
161+ if (!ok) {
162+ qWarning() << "Error executing query" << queryString
163+ << "Driver error:" << query.lastError().driverText()
164+ << "Database error:" << query.lastError().databaseText();
165+ }
184166}
185167
186168QSqlQuery WindowStateStorage::getValue(const QString &queryString) const
plugins/Utils/windowstatestorage.h+1−7
@@ -17,8 +17,6 @@
1717#include <QObject>
1818#include <QSqlDatabase>
1919#include <QMutex>
20−#include <QFuture>
21−#include <QThreadPool>
2220
2321// unity-api
2422#include <unity/shell/application/Mir.h>
@@ -46,7 +44,7 @@ public:
4644 Q_DECLARE_FLAGS(WindowStates, WindowState)
4745 Q_FLAG(WindowStates)
4846
49− WindowStateStorage(QObject *parent = nullptr);
47+ WindowStateStorage(const QString& dbName = nullptr, QObject *parent = nullptr);
5048 virtual ~WindowStateStorage();
5149
5250 Q_INVOKABLE void saveState(const QString &windowId, WindowState state);
@@ -66,12 +64,8 @@ private:
6664 void saveValue(const QString &queryString);
6765 QSqlQuery getValue(const QString &queryString) const;
6866
69− static void executeAsyncQuery(const QString &queryString);
7067 static QMutex s_mutex;
7168
7269 // NB: This is accessed from threads. Make sure to mutex it.
7370 QSqlDatabase m_db;
74−
75− QList<QFuture<void>> m_asyncQueries;
76− QThreadPool m_threadPool;
7771};
po/unity8.pot−12
@@ -218,18 +218,6 @@ msgstr ""
218218msgid "Opens the Application Drawer."
219219msgstr ""
220220
221−#: qml/Components/KeyboardShortcutsOverlay.qml:207
222−msgid "Scopes"
223−msgstr ""
224−
225−#: qml/Components/KeyboardShortcutsOverlay.qml:214
226−msgid "Super (Tap)"
227−msgstr ""
228−
229−#: qml/Components/KeyboardShortcutsOverlay.qml:219
230−msgid "Opens the Scopes home."
231−msgstr ""
232−
233221#: qml/Components/KeyboardShortcutsOverlay.qml:235
234222msgid "Switching"
235223msgstr ""
qml/ApplicationMenus/ApplicationMenuItemFactory.qml+7−7
@@ -21,7 +21,7 @@ import QMenuModel 0.1
2121import Utils 0.1 as Utils
2222import Ubuntu.Components 1.3
2323
24−Object {
24+Item {
2525 id: menuFactory
2626
2727 property string context
@@ -45,7 +45,7 @@ Object {
4545
4646 Action {
4747 id: action
48− text: menuData.label.replace("_", "&")
48+ text: menuData ? menuData.label.replace("_", "&") : ""
4949 }
5050
5151 ListItemLayout {
@@ -53,14 +53,14 @@ Object {
5353 title.text: action.text
5454
5555 Icon {
56− source: menuData && menuData.icon || ""
56+ source: menuData ? menuData.icon : ""
5757 SlotsLayout.position: SlotsLayout.Leading
5858 height: units.gu(3)
5959 }
6060
6161 Label {
62− text: menuData.shortcut
63− visible: menuData.shortcut && QuickUtils.keyboardAttached
62+ text: menuData ? menuData.shortcut : ""
63+ visible: menuData && menuData.shortcut && QuickUtils.keyboardAttached
6464 SlotsLayout.position: SlotsLayout.Trailing
6565 color: enabled ? theme.palette.normal.backgroundSecondaryText :
6666 theme.palette.disabled.backgroundSecondaryText
@@ -86,7 +86,7 @@ Object {
8686
8787 Action {
8888 id: action
89− text: menuData.label.replace("_", "&")
89+ text: menuData ? menuData.label.replace("_", "&") : ""
9090 }
9191
9292 ListItemLayout {
@@ -94,7 +94,7 @@ Object {
9494 title.text: action.text
9595
9696 Icon {
97− source: menuData && menuData.icon || ""
97+ source: menuData ? menuData.icon : ""
9898 SlotsLayout.position: SlotsLayout.Leading
9999 height: units.gu(3)
100100 }
qml/ApplicationMenus/RegisteredApplicationMenuModel.qml+1−1
@@ -20,7 +20,7 @@ import Unity.Indicators 0.1
2020import Unity.ApplicationMenu 0.1
2121import Unity.Indicators 0.1 as Indicators
2222
23−Object {
23+Item {
2424 property string persistentSurfaceId
2525 readonly property alias model: sharedAppModel.model
2626
qml/Components/KeyboardShortcutsOverlay.qml−24
@@ -198,30 +198,6 @@ Rectangle {
198198 wrapMode: Text.Wrap
199199 Layout.maximumWidth: maxTextSize
200200 }
201−
202−
203− // Scopes section
204− Item { Layout.columnSpan: 2; height: units.gu(2) }
205− Label {
206− Layout.columnSpan: 2
207− text: i18n.tr("Scopes")
208− font.weight: Font.Light
209− color: theme.palette.normal.baseText
210− lineHeight: 1.3
211− }
212−
213− Label {
214− text: i18n.tr("Super (Tap)")
215− fontSize: "small"
216− font.weight: Font.Medium
217− }
218− Label {
219− text: i18n.tr("Opens the Scopes home.")
220− fontSize: "small"
221− font.weight: Font.Light
222− wrapMode: Text.Wrap
223− Layout.maximumWidth: maxTextSize
224− }
225201 }
226202
227203 GridLayout {
qml/Components/ResponsiveGridView.qmldeleted−98
@@ -1,98 +0,0 @@
1−/*
2− * Copyright (C) 2013 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 "."
20−
21−/*
22− Essentially a GridView
23− */
24−Item {
25− property int minimumHorizontalSpacing: units.gu(0.5)
26− readonly property int columns: gridView.columns
27− property alias verticalSpacing: gridView.verticalSpacing
28− readonly property alias margins: gridView.margin
29− property int delegateWidth
30− property int delegateHeight
31− property alias model: gridView.model
32− property alias delegate: gridView.delegate
33− readonly property int cellWidth: gridView.cellWidth
34− readonly property int cellHeight: gridView.cellHeight
35− readonly property int totalContentHeight: {
36− if (gridView.model) {
37− return contentHeightForRows(Math.ceil(gridView.model.count / columns), cellHeight)
38− } else {
39− return 0;
40− }
41− }
42− property alias interactive: gridView.interactive
43− readonly property alias flicking: gridView.flicking
44− readonly property alias moving: gridView.moving
45− readonly property alias pressDelay: gridView.pressDelay
46− readonly property alias originY: gridView.originY
47− property alias displayMarginBeginning: gridView.displayMarginBeginning
48− property alias displayMarginEnd: gridView.displayMarginEnd
49− property alias highlightIndex: gridView.highlightIndex
50− property alias cacheBuffer: gridView.cacheBuffer
51− readonly property alias currentItem: gridView.currentItem
52−
53− function contentHeightForRows(rows, height) {
54− return rows * height
55− }
56−
57− GridView {
58− id: gridView
59− objectName: "responsiveGridViewGrid"
60− anchors {
61− fill: parent
62− leftMargin: margin/2
63− rightMargin: margin/2
64− }
65− clip: parent.height != totalContentHeight
66−
67− function pixelToGU(value) {
68− return Math.floor(value / units.gu(1));
69− }
70−
71− function spacingForColumns(columns) {
72− // spacing between columns as an integer number of GU, the remainder goes in the margins
73− var spacingGU = pixelToGU(allocatableHorizontalSpace / columns);
74− return units.gu(spacingGU);
75− }
76−
77− function columnsForSpacing(spacing) {
78− // minimum margin is half of the spacing
79− return Math.max(1, Math.floor(parent.width / (delegateWidth + spacing)));
80− }
81−
82− property real allocatableHorizontalSpace: parent.width - columns * delegateWidth
83− property int columns: columnsForSpacing(minimumHorizontalSpacing)
84− property real horizontalSpacing: spacingForColumns(columns)
85− property real verticalSpacing: horizontalSpacing
86− property int margin: allocatableHorizontalSpace - columns * horizontalSpacing
87− property int highlightIndex: -1
88−
89− cellWidth: delegateWidth + horizontalSpacing
90− cellHeight: delegateHeight + verticalSpacing
91−
92− onHighlightIndexChanged: {
93− if (highlightIndex != -1) {
94− currentIndex = highlightIndex
95− }
96− }
97− }
98−}
qml/Components/Showable.qml+4−4
@@ -35,13 +35,13 @@ Item {
3535 property bool __skipHideAnimation: false
3636
3737 property list<QtObject> hides
38− property var showAnimation
39− property var hideAnimation
38+ property Animation showAnimation
39+ property Animation hideAnimation
4040
4141 // automatically set the target on showAnimation and hideAnimation to be the
4242 // showable itself
43− onShowAnimationChanged: if (showAnimation) showAnimation["target"] = showable
44− onHideAnimationChanged: if (hideAnimation) hideAnimation["target"] = showable
43+ onShowAnimationChanged: if (showAnimation && showAnimation.hasOwnProperty("target")) showAnimation["target"] = showable
44+ onHideAnimationChanged: if (hideAnimation && hideAnimation.hasOwnProperty("target")) hideAnimation["target"] = showable
4545
4646 Component.onCompleted: required = shown;
4747
qml/Launcher/DrawerGridView.qml+2−3
@@ -34,7 +34,7 @@ FocusScope {
3434 property alias topMargin: gridView.topMargin
3535 property alias bottomMargin: gridView.bottomMargin
3636
37− readonly property int columns: width / delegateWidth
37+ readonly property int columns: Math.floor(width / delegateWidth)
3838 readonly property int rows: Math.ceil(gridView.model.count / root.columns)
3939
4040 property alias refreshing: pullToRefresh.refreshing
@@ -44,11 +44,10 @@ FocusScope {
4444 id: gridView
4545 anchors.fill: parent
4646 anchors.topMargin: units.gu(2)
47− leftMargin: spacing
4847 focus: true
4948
5049 readonly property int overflow: width - (root.columns * root.delegateWidth)
51− readonly property real spacing: overflow / (root.columns)
50+ readonly property real spacing: Math.floor(overflow / root.columns)
5251
5352 cellWidth: root.delegateWidth + spacing
5453 cellHeight: root.delegateHeight
qml/Launcher/LauncherDelegate.qml+1−3
@@ -37,7 +37,6 @@ Item {
3737
3838 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
3939 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
40− readonly property alias wiggling: wiggleAnim.running
4140
4241 property int itemWidth
4342 property int itemHeight
@@ -56,8 +55,7 @@ Item {
5655 property real wiggleAngle: 0
5756 }
5857
59− SequentialAnimation {
60− id: wiggleAnim
58+ readonly property var wiggleAnim: SequentialAnimation {
6159
6260 running: alerting
6361 loops: 1
qml/Launcher/LauncherPanel.qml+3−4
@@ -260,6 +260,7 @@ Rectangle {
260260
261261 SequentialAnimation {
262262 id: peekingAnimation
263+ objectName: "peekingAnimation" + index
263264
264265 // revealing
265266 PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 1 : 0 }
@@ -285,7 +286,7 @@ Rectangle {
285286 }
286287
287288 PropertyAction { target: launcherListViewItem; property: "clip"; value: 1 }
288− PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 0 : 1 }
289+ PropertyAction { target: root; property: "visible"; value: (launcher.visibleWidth === 0) ? 1 : 0 }
289290 PropertyAction { target: launcherListView; property: "peekingIndex"; value: -1 }
290291 }
291292
@@ -556,7 +557,7 @@ Rectangle {
556557
557558 function processPositionChanged(mouse) {
558559 if (draggedIndex >= 0) {
559− if (!selectedItem.dragging) {
560+ if (selectedItem && !selectedItem.dragging) {
560561 var distance = Math.max(Math.abs(mouse.x - startX), Math.abs(mouse.y - startY))
561562 if (!preDragging && distance > units.gu(1.5)) {
562563 preDragging = true;
@@ -566,8 +567,6 @@ Rectangle {
566567 selectedItem.dragging = true
567568 preDragging = false;
568569 }
569− }
570− if (!selectedItem.dragging) {
571570 return
572571 }
573572
qml/Panel/Indicators/IndicatorMenuItemFactory.qml+3−3
@@ -25,7 +25,7 @@ import Ubuntu.Components 1.3
2525import Unity.Session 0.1
2626import Unity.Platform 1.0
2727
28−Object {
28+Item {
2929 id: menuFactory
3030
3131 property string indicator
@@ -964,8 +964,8 @@ Object {
964964 QDBusActionGroup {
965965 id: actionGroup
966966 busType: 1
967− busName: rootModel.busName
968− objectPath: rootModel.actions["indicator"]
967+ busName: menuFactory.rootModel.busName
968+ objectPath: menuFactory.rootModel.actions["indicator"]
969969
970970 property var activateAction: action("activate-transfer")
971971 property var cancelAction: action("cancel-transfer")
qml/Panel/Indicators/IndicatorsLight.qml+2−2
@@ -204,11 +204,11 @@ console.log("no support for Multicolor LED. " + indicatorState)
204204 property variant deviceState: action("device-state").state
205205 Component.onCompleted: start()
206206 onBatteryLevelChanged: {
207− root.batteryLevel = batteryLevel
207+ root.batteryLevel = batteryLevel ? batteryLevel : 0.00
208208 updateLightState("onBatteryLevelChanged")
209209 }
210210 onDeviceStateChanged: {
211− root.deviceState = deviceState
211+ root.deviceState = deviceState ? deviceState : "unknown"
212212 updateLightState("onDeviceStateChanged")
213213 }
214214 }
qml/Panel/PanelMenuPage.qml+1−1
@@ -59,7 +59,7 @@ PageStack {
5959 function reset(clearModel) {
6060 if (clearModel) {
6161 clear();
62− var model = submenuIndex == undefined ? menuModel : menuModel.submenu(submenuIndex)
62+ var model = root.submenuIndex == undefined ? menuModel : menuModel.submenu(root.submenuIndex)
6363 if (model) {
6464 push(pageComponent, { "menuModel": model });
6565 }
qml/Shell.qml+1−1
@@ -90,7 +90,7 @@ StyledItem {
9090 } else if (showingGreeter || notifications.topmostIsFullscreen) {
9191 return Qt.PrimaryOrientation;
9292 } else {
93− return shell.orientations.map(stage.supportedOrientations);
93+ return shell.orientations ? shell.orientations.map(stage.supportedOrientations) : Qt.PrimaryOrientation;
9494 }
9595 }
9696
qml/Stage/MoveHandler.qml+7−7
@@ -47,13 +47,13 @@ QtObject {
4747 property bool moving
4848
4949 readonly property int triggerArea: units.gu(8)
50− property bool nearLeftEdge: target.maximizedLeft
51− property bool nearTopEdge: target.maximized
52− property bool nearRightEdge: target.maximizedRight
53− property bool nearTopLeftCorner: target.maximizedTopLeft
54− property bool nearTopRightCorner: target.maximizedTopRight
55− property bool nearBottomLeftCorner: target.maximizedBottomLeft
56− property bool nearBottomRightCorner: target.maximizedBottomRight
50+ property bool nearLeftEdge: target && target.maximizedLeft
51+ property bool nearTopEdge: target && target.maximized
52+ property bool nearRightEdge: target && target.maximizedRight
53+ property bool nearTopLeftCorner: target && target.maximizedTopLeft
54+ property bool nearTopRightCorner: target && target.maximizedTopRight
55+ property bool nearBottomLeftCorner: target && target.maximizedBottomLeft
56+ property bool nearBottomRightCorner: target && target.maximizedBottomRight
5757
5858 property Timer mouseDownTimer: Timer {
5959 interval: 175
qml/Stage/Splash.qml+4−4
@@ -32,6 +32,9 @@ Item {
3232 property alias title: header.title
3333 property alias showHeader: header.visible
3434
35+ // Set clip to prevent drawing outside the window rectangle
36+ clip: true
37+
3538 Ambiance.Palette {
3639 id: ambiancePalette
3740 }
@@ -89,12 +92,9 @@ Item {
8992 id: overlaidImage
9093 anchors.centerIn: parent
9194 anchors.verticalCenterOffset: header.visible ? header.height / 2 : 0
92− sourceSize {
93− width: root.width
94− height: root.height
95− }
9695 asynchronous: true
9796 cache: false
97+ clip: true
9898 }
9999
100100 UbuntuShape {
qml/Stage/Stage.qml+2−2
@@ -2210,8 +2210,8 @@ FocusScope {
22102210 consumesInput: false
22112211 interactive: false
22122212 focus: false
2213− requestedWidth: appDelegate.requestedWidth
2214− requestedHeight: appDelegate.requestedHeight
2213+ requestedWidth: appDelegate ? appDelegate.requestedWidth : 0
2214+ requestedHeight: appDelegate ? appDelegate.requestedHeight : 0
22152215
22162216 width: units.gu(40)
22172217 height: units.gu(40)
qml/Stage/WindowDecoration.qml+5−6
@@ -99,13 +99,12 @@ MouseArea {
9999 spacing: units.gu(3)
100100
101101 WindowControlButtons {
102+ Layout.fillHeight: true
103+ Layout.fillWidth: false
104+ Layout.topMargin: units.gu(0.5)
105+ Layout.bottomMargin: units.gu(0.5)
106+
102107 id: buttons
103− anchors {
104− top: parent.top
105− bottom: parent.bottom
106− topMargin: units.gu(0.5)
107− bottomMargin: units.gu(0.5)
108− }
109108 active: root.active
110109 onCloseClicked: root.closeClicked();
111110 onMinimizeClicked: root.minimizeClicked();
qml/Tutorial/TutorialContent.qml+8−8
@@ -77,7 +77,7 @@ Item {
7777
7878 readonly property bool skipped: !d.mobileScenario || d.haveShown("top")
7979 readonly property bool shown: item && item.shown
80− active: !skipped || (item && item.visible)
80+ active: !skipped
8181 onSkippedChanged: if (skipped && shown) item.hide()
8282
8383 sourceComponent: TutorialTop {
@@ -85,7 +85,7 @@ Item {
8585 objectName: "tutorialTop"
8686 anchors.fill: parent
8787 panel: root.panel
88− hides: [launcher, panel.indicators]
88+ hides: [root.launcher, panel.indicators]
8989 paused: root.paused
9090
9191 skipped: tutorialTopLoader.skipped
@@ -111,7 +111,7 @@ Item {
111111
112112 readonly property bool skipped: !d.mobileScenario || d.haveShown("left")
113113 readonly property bool shown: item && item.shown
114− active: !skipped || (item && item.visible)
114+ active: !skipped
115115 onSkippedChanged: if (skipped && shown) item.hide()
116116
117117 sourceComponent: TutorialLeft {
@@ -119,7 +119,7 @@ Item {
119119 objectName: "tutorialLeft"
120120 anchors.fill: parent
121121 launcher: root.launcher
122− hides: [launcher, panel.indicators]
122+ hides: [launcher, root.panel.indicators]
123123 paused: root.paused
124124
125125 isReady: !tutorialLeftLoader.skipped
@@ -151,7 +151,7 @@ Item {
151151
152152 readonly property bool skipped: !d.mobileScenario || d.haveShown("left-drawer")
153153 readonly property bool shown: item && item.shown
154− active: !skipped || (item && item.visible)
154+ active: !skipped
155155 onSkippedChanged: if (skipped && shown) item.hide()
156156
157157 sourceComponent: TutorialLeftLong {
@@ -159,7 +159,7 @@ Item {
159159 objectName: "tutorialLeftLong"
160160 anchors.fill: parent
161161 launcher: root.launcher
162− hides: [launcher, panel.indicators]
162+ hides: [launcher, root.panel.indicators]
163163 paused: root.paused
164164
165165 skipped: tutorialLeftLongLoader.skipped
@@ -189,7 +189,7 @@ Item {
189189
190190 readonly property bool skipped: d.haveShown("right")
191191 readonly property bool shown: item && item.shown
192− active: !skipped || (item && item.visible)
192+ active: !skipped
193193 onSkippedChanged: if (skipped && shown) item.hide()
194194
195195 sourceComponent: TutorialRight {
@@ -198,7 +198,7 @@ Item {
198198 anchors.fill: parent
199199 stage: root.stage
200200 usageScenario: root.usageScenario
201− hides: [launcher, panel.indicators]
201+ hides: [root.launcher, panel.indicators]
202202 paused: root.paused
203203
204204 skipped: tutorialRightLoader.skipped
qml/Tutorial/TutorialLeft.qml+1−1
@@ -26,7 +26,7 @@ TutorialPage {
2626 opacityOverride: 1 - launcher.visibleWidth / launcher.panelWidth
2727
2828 mouseArea {
29− anchors.leftMargin: launcher.dragAreaWidth
29+ anchors.leftMargin: root.launcher.dragAreaWidth
3030 }
3131
3232 background {
qml/Tutorial/TutorialLeftLong.qml+1−1
@@ -28,7 +28,7 @@ TutorialPage {
2828 opacityOverride: shown ? 1 - launcher.dragDistance / (launcher.panelWidth * 3) : 1
2929
3030 mouseArea {
31− anchors.leftMargin: launcher.dragAreaWidth
31+ anchors.leftMargin: root.launcher.dragAreaWidth
3232 }
3333
3434 background {
qml/Tutorial/TutorialTop.qml+2−2
@@ -28,11 +28,11 @@ TutorialPage {
2828 QtObject {
2929 id: d
3030 readonly property bool landscape: root.width > units.gu(50)
31− readonly property real columnWidth: landscape ? panel.indicators.width : root.width
31+ readonly property real columnWidth: landscape ? root.panel.indicators.width : root.width
3232 }
3333
3434 mouseArea {
35− anchors.topMargin: panel.indicators.minimizedPanelHeight
35+ anchors.topMargin: root.panel.indicators.minimizedPanelHeight
3636 }
3737
3838 background {
qml/Wizard/Pages/30-wifi.qml+4−5
@@ -163,8 +163,8 @@ LocalComponents.Page {
163163
164164 Label {
165165 id: label
166− anchors.left: parent.left
167− anchors.right: parent.right
166+ Layout.fillWidth: true
167+ Layout.fillHeight: false
168168 anchors.leftMargin: column.anchors.leftMargin == 0 ? staticMargin : 0
169169 font.weight: Font.Light
170170 color: textColor
@@ -176,11 +176,10 @@ LocalComponents.Page {
176176 ListView {
177177 id: listview
178178 objectName: "accessPointsListView"
179− anchors.left: parent.left
180− anchors.right: parent.right
179+ Layout.fillWidth: true
180+ Layout.fillHeight: true
181181 clip: true
182182 model: menuModel
183− Layout.fillHeight: true
184183
185184 delegate: Loader {
186185 readonly property bool isAccessPoint: model.type === "unity.widgets.systemsettings.tablet.accesspoint"
qml/Wizard/Pages/50-timezone.qml+9−11
@@ -174,10 +174,9 @@ LocalComponents.Page {
174174 width: Math.min(parent.width, units.gu(34))
175175
176176 LocalComponents.WizardTextField {
177+ Layout.fillWidth: true
177178 id: searchField
178179 objectName: "tzFilter"
179− anchors.left: parent.left
180− anchors.right: parent.right
181180 anchors.leftMargin: !showingMap && !wideMode ? staticMargin : undefined
182181 anchors.rightMargin: !showingMap && !wideMode ? staticMargin : undefined
183182 placeholderText: i18n.tr("Enter your city")
@@ -186,12 +185,11 @@ LocalComponents.Page {
186185 }
187186
188187 ListView {
188+ Layout.fillWidth: true
189189 Layout.fillHeight: true
190190 id: tzList
191191 objectName: "tzList"
192192 clip: true
193− anchors.left: parent.left
194− anchors.right: parent.right
195193 currentIndex: -1
196194 model: TimeZoneModel {
197195 id: timeZoneModel
@@ -199,14 +197,14 @@ LocalComponents.Page {
199197 country: i18n.language.split('_')[1].split('.')[0]
200198 }
201199 delegate: tzComponent
202− }
203200
204− ActivityIndicator {
205− anchors.centerIn: tzList
206− running: tzList.count == 0 &&
207− searchField.length > 0 &&
208− timeZoneModel.listUpdating
209− visible: running
201+ ActivityIndicator {
202+ anchors.centerIn: parent
203+ running: tzList.count == 0 &&
204+ searchField.length > 0 &&
205+ timeZoneModel.listUpdating
206+ visible: running
207+ }
210208 }
211209 }
212210
tests/mocks/GSettings.1.0/fake_gsettings.cpp+22−5
@@ -28,7 +28,7 @@ GSettingsControllerQml::GSettingsControllerQml()
2828 , m_launcherWidth(8)
2929 , m_edgeDragWidth(2)
3030 , m_enableIndicatorMenu(true)
31− , m_appstoreUri("http://uappexplorer.com")
31+ , m_oskSwitchVisible(false)
3232{
3333}
3434
@@ -160,9 +160,17 @@ void GSettingsControllerQml::setEnableIndicatorMenu(bool enableIndicatorMenu)
160160 }
161161}
162162
163−QString GSettingsControllerQml::appstoreUri() const
163+bool GSettingsControllerQml::oskSwitchVisible() const
164164{
165− return m_appstoreUri;
165+ return m_oskSwitchVisible;
166+}
167+
168+void GSettingsControllerQml::setOskSwitchVisible(bool oskSwitchVisible)
169+{
170+ if (m_oskSwitchVisible != oskSwitchVisible) {
171+ m_oskSwitchVisible = oskSwitchVisible;
172+ Q_EMIT oskSwitchVisibleChanged(oskSwitchVisible);
173+ }
166174}
167175
168176GSettingsSchemaQml::GSettingsSchemaQml(QObject *parent): QObject(parent) {
@@ -231,6 +239,8 @@ void GSettingsQml::componentComplete()
231239 this, &GSettingsQml::edgeDragWidthChanged);
232240 connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::enableIndicatorMenuChanged,
233241 this, &GSettingsQml::enableIndicatorMenuChanged);
242+ connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::oskSwitchVisibleChanged,
243+ this, &GSettingsQml::oskSwitchVisibleChanged);
234244
235245 Q_EMIT disableHeightChanged();
236246 Q_EMIT pictureUriChanged();
@@ -356,10 +366,10 @@ QVariant GSettingsQml::enableIndicatorMenu() const
356366 }
357367}
358368
359−QVariant GSettingsQml::appstoreUri() const
369+QVariant GSettingsQml::oskSwitchVisible() const
360370{
361371 if (m_valid && m_schema->id() == "com.canonical.Unity8") {
362− return GSettingsControllerQml::instance()->appstoreUri();
372+ return GSettingsControllerQml::instance()->oskSwitchVisible();
363373 }
364374 return QVariant();
365375}
@@ -398,3 +408,10 @@ void GSettingsQml::setEnableIndicatorMenu(const QVariant &enableIndicatorMenu)
398408 GSettingsControllerQml::instance()->setEnableIndicatorMenu(enableIndicatorMenu.toBool());
399409 }
400410}
411+
412+void GSettingsQml::setOskSwitchVisible(const QVariant &oskSwitchVisible)
413+{
414+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
415+ GSettingsControllerQml::instance()->setOskSwitchVisible(oskSwitchVisible.toBool());
416+ }
417+}
tests/mocks/GSettings.1.0/fake_gsettings.h+8−6
@@ -58,7 +58,7 @@ class GSettingsQml: public QObject, public QQmlParserStatus
5858 Q_PROPERTY(QVariant launcherWidth READ launcherWidth WRITE setLauncherWidth NOTIFY launcherWidthChanged)
5959 Q_PROPERTY(QVariant edgeDragWidth READ edgeDragWidth WRITE setEdgeDragWidth NOTIFY edgeDragWidthChanged)
6060 Q_PROPERTY(QVariant enableIndicatorMenu READ enableIndicatorMenu WRITE setEnableIndicatorMenu NOTIFY enableIndicatorMenuChanged)
61− Q_PROPERTY(QVariant appstoreUri READ appstoreUri NOTIFY appstoreUriChanged)
61+ Q_PROPERTY(QVariant oskSwitchVisible READ oskSwitchVisible WRITE setOskSwitchVisible NOTIFY oskSwitchVisibleChanged)
6262
6363public:
6464 GSettingsQml(QObject *parent = nullptr);
@@ -76,7 +76,7 @@ public:
7676 QVariant launcherWidth() const;
7777 QVariant edgeDragWidth() const;
7878 QVariant enableIndicatorMenu() const;
79− QVariant appstoreUri() const;
79+ QVariant oskSwitchVisible() const;
8080
8181 void setDisableHeight(const QVariant &val);
8282 void setPictureUri(const QVariant &str);
@@ -87,6 +87,7 @@ public:
8787 void setLauncherWidth(const QVariant &launcherWidth);
8888 void setEdgeDragWidth(const QVariant &edgeDragWidth);
8989 void setEnableIndicatorMenu(const QVariant &enableIndicatorMenu);
90+ void setOskSwitchVisible(const QVariant &oskSwitchVisible);
9091
9192Q_SIGNALS:
9293 void disableHeightChanged();
@@ -99,7 +100,7 @@ Q_SIGNALS:
99100 void launcherWidthChanged();
100101 void edgeDragWidthChanged();
101102 void enableIndicatorMenuChanged();
102− void appstoreUriChanged();
103+ void oskSwitchVisibleChanged();
103104
104105private:
105106 GSettingsSchemaQml* m_schema;
@@ -143,7 +144,8 @@ public:
143144 bool enableIndicatorMenu() const;
144145 Q_INVOKABLE void setEnableIndicatorMenu(bool enableIndicatorMenu);
145146
146− QString appstoreUri() const;
147+ bool oskSwitchVisible() const;
148+ Q_INVOKABLE void setOskSwitchVisible(bool oskSwitchVisible);
147149
148150Q_SIGNALS:
149151 void disableHeightChanged();
@@ -155,7 +157,7 @@ Q_SIGNALS:
155157 void launcherWidthChanged(int launcherWidth);
156158 void edgeDragWidthChanged(uint edgeDragWidth);
157159 void enableIndicatorMenuChanged(bool enableIndicatorMenu);
158− void appstoreUriChanged(const QString &appstoreUri);
160+ void oskSwitchVisibleChanged(bool oskSwitchVisible);
159161
160162private:
161163 GSettingsControllerQml();
@@ -169,7 +171,7 @@ private:
169171 int m_launcherWidth;
170172 uint m_edgeDragWidth;
171173 bool m_enableIndicatorMenu;
172− QString m_appstoreUri;
174+ bool m_oskSwitchVisible;
173175
174176 static GSettingsControllerQml* s_controllerInstance;
175177 QList<GSettingsQml *> m_registeredGSettings;
tests/mocks/Unity/Application/SurfaceManager.cpp+3
@@ -35,6 +35,9 @@ SurfaceManager *SurfaceManager::m_instance = nullptr;
3535
3636SurfaceManager *SurfaceManager::instance()
3737{
38+ if (m_instance == nullptr) {
39+ auto inst = new SurfaceManager();
40+ }
3841 return m_instance;
3942}
4043
tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.cpp+2−2
@@ -41,7 +41,7 @@ void MockApplicationMenuRegistry::RegisterSurfaceMenu(const QString &surface,
4141 service);
4242}
4343
44−void MockApplicationMenuRegistry::UnregisterSurfaceMenu(const QString &surfaceId, const QDBusObjectPath &menuObjectPath)
44+void MockApplicationMenuRegistry::UnregisterSurfaceMenu(const QString &surfaceId, const QString &menuObjectPath)
4545{
46− ApplicationMenuRegistry::UnregisterSurfaceMenu(surfaceId, menuObjectPath);
46+ ApplicationMenuRegistry::UnregisterSurfaceMenu(surfaceId, QDBusObjectPath(menuObjectPath));
4747}
tests/mocks/Unity/ApplicationMenu/mockapplicationmenuregistry.h+1−1
@@ -32,7 +32,7 @@ public:
3232 const QString &service);
3333
3434 Q_INVOKABLE void UnregisterSurfaceMenu(const QString &surfaceId,
35− const QDBusObjectPath &menuObjectPath);
35+ const QString &menuObjectPath);
3636
3737private:
3838 MockApplicationMenuRegistry(QObject *parent = 0);
tests/mocks/Wizard/CMakeLists.txt+1
@@ -8,6 +8,7 @@ include_directories(
88add_library(MockWizard-qml MODULE
99 mockplugin.cpp
1010 MockSystem.cpp
11+ ${CMAKE_SOURCE_DIR}/plugins/Wizard/Changelog.cpp
1112 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
1213 ${CMAKE_SOURCE_DIR}/plugins/Wizard/timezonemodel.cpp
1314 ${CMAKE_SOURCE_DIR}/plugins/Wizard/LocalePlugin.cpp
tests/mocks/Wizard/MockSystem.cpp+7−1
@@ -21,7 +21,8 @@
2121
2222MockSystem::MockSystem()
2323 : QObject(),
24− m_wizardEnabled(false)
24+ m_wizardEnabled(false),
25+ m_version("Lomiri 17.04.12")
2526{
2627}
2728
@@ -47,6 +48,11 @@ void MockSystem::setIsUpdate(bool update)
4748 Q_EMIT isUpdateChanged();
4849}
4950
51+QString MockSystem::version() const
52+{
53+ return m_version;
54+}
55+
5056void MockSystem::updateSessionLocale(const QString &locale)
5157{
5258 Q_EMIT updateSessionLocaleCalled(locale);
tests/mocks/Wizard/MockSystem.h+4
@@ -24,6 +24,7 @@ class MockSystem : public QObject
2424{
2525 Q_OBJECT
2626 Q_PROPERTY(bool wizardEnabled READ wizardEnabled WRITE setWizardEnabled NOTIFY wizardEnabledChanged)
27+ Q_PROPERTY(QString version READ version NOTIFY versionChanged)
2728 Q_PROPERTY(bool isUpdate READ isUpdate WRITE setIsUpdate NOTIFY isUpdateChanged)
2829
2930public:
@@ -33,6 +34,7 @@ public:
3334 void setWizardEnabled(bool enabled);
3435 bool isUpdate() const;
3536 void setIsUpdate(bool enabled); // only in mock
37+ QString version() const;
3638
3739public Q_SLOTS:
3840 void updateSessionLocale(const QString &locale);
@@ -44,6 +46,7 @@ public Q_SLOTS:
4446Q_SIGNALS:
4547 void wizardEnabledChanged();
4648 void isUpdateChanged(); // only in mock
49+ void versionChanged();
4750 void updateSessionLocaleCalled(const QString &locale); // only in mock
4851 void wouldHaveSetSkipUntilFinish(); // only in mock
4952
@@ -52,6 +55,7 @@ private:
5255
5356 bool m_wizardEnabled = true;
5457 bool m_isUpdate = false;
58+ QString m_version;
5559};
5660
5761#endif
tests/mocks/Wizard/mockplugin.cpp+2
@@ -14,6 +14,7 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17+#include "Changelog.h"
1718#include "mockplugin.h"
1819#include "MockSystem.h"
1920#include "PageList.h"
@@ -30,6 +31,7 @@ void MockWizardPlugin::registerTypes(const char *uri)
3031 qmlRegisterType<PageList>(uri, 0, 1, "PageList");
3132 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new MockSystem; });
3233 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
34+ qmlRegisterSingletonType<Changelog>(uri, 0, 1, "Changelog", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Changelog; });
3335 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
3436 qmlRegisterType<KeyboardLayoutsModel>(uri, 0, 1, "KeyboardLayoutsModel");
3537 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
tests/plugins/Utils/WindowStateStorageTest.cpp+1−1
@@ -30,7 +30,7 @@ private Q_SLOTS:
3030
3131 void init()
3232 {
33− storage = new WindowStateStorage(this);
33+ storage = new WindowStateStorage(":memory:", this);
3434 }
3535
3636 void cleanup()
tests/qmltests/ApplicationMenuDataLoader.qml+1−1
@@ -20,7 +20,7 @@ import Unity.Application 0.1
2020import Unity.ApplicationMenu 0.1
2121import Unity.Indicators 0.1 as Indicators
2222
23−Object {
23+Item {
2424
2525 property alias surfaceManager: sMgrHandler.target
2626
tests/qmltests/CMakeLists.txt−1
@@ -20,7 +20,6 @@ add_unity8_qmltest(Components MediaServices)
2020add_unity8_qmltest(Components ModeSwitchWarningDialog)
2121add_unity8_qmltest(Components PhysicalKeysMapper)
2222add_unity8_qmltest(Components Rating)
23−add_unity8_qmltest(Components ResponsiveGridView)
2423add_unity8_qmltest(Components SharingPicker)
2524add_unity8_qmltest(Components Showable)
2625add_unity8_qmltest(Components VirtualTouchPad)
tests/qmltests/Components/tst_ResponsiveGridView.qmldeleted−157
@@ -1,157 +0,0 @@
1−/*
2− * Copyright 2013 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 QtTest 1.0
19−import ".."
20−import "../../../qml/Components"
21−import Ubuntu.Components.ListItems 1.3 as ListItem
22−import Ubuntu.Components 1.3
23−import Unity.Test 0.1 as UT
24−
25−Item {
26− width: gridRect.width + controls.width
27− height: units.gu(80)
28−
29− Column {
30− id: controls
31− width: units.gu(40)
32− height: parent.height
33− anchors.top: parent.top
34− anchors.right: parent.right
35− ListItem.ValueSelector {
36− id: minHSpacingSelector
37− text: "minHorizontalSpacing"
38− values: [0,units.gu(2),units.gu(8),units.gu(25)]
39− selectedIndex: 0
40− }
41− }
42−
43− ListModel {
44− id: fakeModel
45− ListElement { name: "A" }
46− ListElement { name: "B" }
47− ListElement { name: "C" }
48− ListElement { name: "D" }
49− ListElement { name: "E" }
50− ListElement { name: "F" }
51− ListElement { name: "G" }
52− ListElement { name: "H" }
53− ListElement { name: "I" }
54− ListElement { name: "J" }
55− ListElement { name: "K" }
56− ListElement { name: "L" }
57− ListElement { name: "M" }
58− ListElement { name: "N" }
59− ListElement { name: "O" }
60− ListElement { name: "P" }
61− ListElement { name: "Q" }
62− ListElement { name: "R" }
63− ListElement { name: "S" }
64− ListElement { name: "T" }
65− ListElement { name: "U" }
66− }
67−
68− Rectangle {
69− id: gridRect
70− width: units.gu(80)
71− height: parent.height
72− color: "grey"
73− anchors.top: parent.top
74− anchors.left: parent.left
75−
76− ResponsiveGridView {
77− id: grid
78− anchors.fill: parent
79− model: fakeModel
80− minimumHorizontalSpacing:
81− minHSpacingSelector.values[minHSpacingSelector.selectedIndex]
82− verticalSpacing: units.gu(2)
83− delegateWidth: units.gu(6)
84− delegateHeight: units.gu(6)
85−
86− delegate: Rectangle {
87− // So that it can be identified by test code
88− property bool isGridDelegate: true
89− color: "grey"
90− border.color: "red"
91− border.width: 1
92−
93− // IMPORTANT: always use grid's cellWidth and cellHeight here to get
94− // ResponsiveGridView's intended result
95− width: grid.cellWidth
96− height: grid.cellHeight
97−
98− Rectangle {
99− color: "green"
100− anchors.centerIn: parent
101− width: units.gu(6)
102− height: units.gu(6)
103− Text {
104− anchors.centerIn: parent
105− text: name
106− }
107− }
108−
109− Text { x:0; y:0; text:"(" + parent.x + ", " + parent.y + ")"}
110− }
111− }
112− }
113−
114− UT.UnityTestCase {
115− name: "ResponsiveGridView"
116− when: windowShown
117−
118− function test_minimumHorizontalSpacing_data() {
119− var data = new Array()
120−
121− data.push({selectedIndex: 0, minHSpacing:0, columnCount: 13})
122− data.push({selectedIndex: 1, minHSpacing:units.gu(2), columnCount: 10})
123− data.push({selectedIndex: 2, minHSpacing:units.gu(8), columnCount: 5})
124− data.push({selectedIndex: 3, minHSpacing:units.gu(25), columnCount: 2})
125−
126− return data
127− }
128−
129− /* Change ResponsiveGridView's minimumHorizontalSpacing property and check
130− that the resulting number of columns matches expectations */
131− function test_minimumHorizontalSpacing(data) {
132− // sanity checks
133− compare(minHSpacingSelector.values[data.selectedIndex], data.minHSpacing)
134−
135− minHSpacingSelector.selectedIndex = data.selectedIndex
136− tryCompareFunction(countGridDelegatesOnFirstRow, data.columnCount);
137− compare(grid.columns, data.columnCount)
138− }
139−
140−
141− function countGridDelegatesOnFirstRow() {
142− return __countGridDelegatesOnFirstRow(grid.visibleChildren, 0)
143− }
144−
145− function __countGridDelegatesOnFirstRow(objList, total) {
146− for (var i = 0; i < objList.length; ++i) {
147− var child = objList[i];
148− if (child.isGridDelegate !== undefined && child.y === 0) {
149− ++total;
150− } else {
151− total = __countGridDelegatesOnFirstRow(child.visibleChildren, total)
152− }
153− }
154− return total
155− }
156− }
157−}
tests/qmltests/Launcher/tst_Launcher.qml+91−31
@@ -253,6 +253,24 @@ Rectangle {
253253 target: clickThroughTester
254254 }
255255
256+ SignalSpy {
257+ id: startedSpy
258+ target: null
259+ signalName: "started"
260+ }
261+
262+ SignalSpy {
263+ id: stoppedSpy
264+ target: null
265+ signalName: "stopped"
266+ }
267+
268+ SignalSpy {
269+ id: stoppedSpy2
270+ target: null
271+ signalName: "stopped"
272+ }
273+
256274 Item {
257275 id: fakeDismissTimer
258276 property bool running: false
@@ -276,6 +294,12 @@ Rectangle {
276294 function cleanup() {
277295 signalSpy.clear();
278296 clickThroughSpy.clear();
297+ startedSpy.clear();
298+ startedSpy.target = null;
299+ stoppedSpy.clear();
300+ stoppedSpy.target = null;
301+ stoppedSpy2.clear();
302+ stoppedSpy2.target = null;
279303 launcherLoader.active = false;
280304 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
281305 // item might still be alive. So if we set Loader.active back to true
@@ -358,16 +382,6 @@ Rectangle {
358382 tryCompare(panel, "x", -panel.width, 1000);
359383 }
360384
361− function waitForWiggleToStart(appIcon) {
362− verify(appIcon != undefined)
363− tryCompare(appIcon, "wiggling", true, 1000, "wiggle-anim should not be in stopped state")
364− }
365−
366− function waitForWiggleToStop(appIcon) {
367− verify(appIcon != undefined)
368− tryCompare(appIcon, "wiggling", false, 1000, "wiggle-anim should not be in running state")
369− }
370−
371385 function positionLauncherListAtBeginning() {
372386 var listView = testCase.findChild(launcherLoader.item, "launcherListView");
373387 var moveAnimation = findInvisibleChild(listView, "moveAnimation")
@@ -793,6 +807,7 @@ Rectangle {
793807 }
794808
795809 function test_dragndrop_with_other_quicklist_open() {
810+ skip("Failing on Qt 5.12");
796811 dragLauncherIntoView();
797812 var draggedItem = findChild(launcher, "launcherDelegate4")
798813 var item0 = findChild(launcher, "launcherDelegate0")
@@ -941,7 +956,7 @@ Rectangle {
941956 tryCompare(quickListShape, "opacity", 0.95);
942957 mouseRelease(draggedItem);
943958
944− tryVerify(function() {return (quickList.y >= units.gu(1))});
959+ tryVerify(function() {return (quickList.y >= units.gu(0.5))});
945960 tryVerify(function() {return (quickList.y + quickList.height + units.gu(1) <= launcher.height)});
946961 compare(quickList.width, units.gu(30));
947962
@@ -1015,7 +1030,7 @@ Rectangle {
10151030 // Doing longpress
10161031 mousePress(clickedItem)
10171032 tryCompare(clickedItem, "itemOpacity", 0) // Wait for longpress to happen
1018− verify(quickList, "state", "open")
1033+ tryCompare(quickList, "state", "open")
10191034
10201035 launcher.hide();
10211036
@@ -1035,13 +1050,13 @@ Rectangle {
10351050 // Doing RMB click
10361051 mouseClick(clickedItem, clickedItem.width / 2, clickedItem.height / 2, Qt.RightButton)
10371052 tryCompare(quickListShape, "visible", true)
1038− verify(quickList, "state", "open")
1039− verify(dndArea, "dragging", false)
1053+ tryCompare(quickList, "state", "open")
1054+ tryCompare(dndArea, "dragging", false)
10401055
10411056 // Click somewhere in the empty space to dismiss the quicklist
10421057 mouseClick(launcher, launcher.width - units.gu(1), units.gu(1));
10431058 tryCompare(quickListShape, "visible", false);
1044− verify(quickList, "state", "")
1059+ tryCompare(quickList, "state", "")
10451060 }
10461061
10471062 function test_revealByEdgePush() {
@@ -1089,10 +1104,13 @@ Rectangle {
10891104 verify(listView != undefined)
10901105 var appIcon6 = findChild(launcher, "launcherDelegate6")
10911106 verify(appIcon6 != undefined)
1107+
1108+ startedSpy.target = appIcon6.wiggleAnim
1109+ stoppedSpy.target = appIcon6.wiggleAnim
10921110 LauncherModel.setAlerting(LauncherModel.get(6).appId, true)
1093− waitForWiggleToStart(appIcon6)
1111+ tryCompare(startedSpy, "count", 1);
10941112 LauncherModel.setAlerting(LauncherModel.get(6).appId, false)
1095− waitForWiggleToStop(appIcon6)
1113+ tryCompare(stoppedSpy, "count", 1);
10961114 tryCompare(appIcon6, "x", 0, 1000, "x-value of appId #6 should not be non-zero")
10971115 waitForRendering(listView)
10981116 }
@@ -1138,48 +1156,60 @@ Rectangle {
11381156 function test_alertMoveIconIntoView() {
11391157 dragLauncherIntoView();
11401158 var appIcon1 = findChild(launcher, "launcherDelegate1");
1159+ verify(appIcon1);
11411160 var appIcon7 = findChild(launcher, "launcherDelegate7");
1161+ verify(appIcon7);
1162+ stoppedSpy.target = appIcon1.wiggleAnim;
1163+ stoppedSpy2.target = appIcon7.wiggleAnim;
1164+
1165+ startedSpy.target = appIcon1.wiggleAnim;
11421166 LauncherModel.setAlerting(LauncherModel.get(1).appId, true)
11431167 tryCompare(appIcon1, "angle", 0, 1000, "angle of appId #1 should not be non-zero")
1144− waitForWiggleToStart(appIcon1)
1168+ tryCompare(startedSpy, "count", 1);
1169+ startedSpy.clear();
1170+
1171+ startedSpy.target = appIcon7.wiggleAnim;
11451172 LauncherModel.setAlerting(LauncherModel.get(7).appId, true)
11461173 tryCompare(appIcon7, "angle", 0, 1000, "angle of appId #7 should not be non-zero")
1147− waitForWiggleToStart(appIcon7)
1174+ tryCompare(startedSpy, "count", 1);
11481175 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
1149− waitForWiggleToStop(appIcon1)
11501176 LauncherModel.setAlerting(LauncherModel.get(7).appId, false)
1151− waitForWiggleToStop(appIcon7)
1177+ tryCompare(stoppedSpy, "count", 1);
1178+ tryCompare(stoppedSpy2, "count", 1);
11521179 }
11531180
11541181 function test_alertWigglePeekDrag() {
11551182 var appIcon5 = findChild(launcher, "launcherDelegate5");
1156− var listView = findChild(launcher, "launcherListView")
1183+ var listView = findChild(launcher, "launcherListView");
1184+ startedSpy.target = appIcon5.wiggleAnim;
1185+ stoppedSpy.target = appIcon5.wiggleAnim;
1186+
11571187 verify(listView != undefined)
11581188 LauncherModel.setAlerting(LauncherModel.get(5).appId, true)
11591189 tryCompare(listView, "peekingIndex", 5, 1000, "Wrong appId set as peeking-index")
1160− waitForWiggleToStart(appIcon5)
1161− tryCompare(appIcon5, "wiggling", true, 1000, "appId #6 should not be still")
1190+ tryCompare(startedSpy, "count", 1, 1000, "appId #6 should have wiggled")
11621191 dragLauncherIntoView();
11631192 tryCompare(listView, "peekingIndex", -1, 1000, "peeking-index should be -1")
11641193 LauncherModel.setAlerting(LauncherModel.get(5).appId, false)
1165− waitForWiggleToStop(appIcon5)
1166− tryCompare(appIcon5, "wiggling", false, 1000, "appId #1 should not be wiggling")
1194+ tryCompare(stoppedSpy, "count", 1, 1000, "appId #6 should have stopped wiggling");
11671195 }
11681196
11691197 function test_alertViaCountAndCountVisible() {
11701198 dragLauncherIntoView();
11711199 var appIcon1 = findChild(launcher, "launcherDelegate1")
11721200 var oldCount = LauncherModel.get(1).count
1201+ startedSpy.target = appIcon1.wiggleAnim;
11731202 LauncherModel.setCount(LauncherModel.get(1).appId, 42)
1174− tryCompare(appIcon1, "wiggling", false, 1000, "appId #1 should be still")
1203+ tryCompare(appIcon1.wiggleAnim, "running", false, 1000, "appId #1 should be still")
11751204 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 1)
1176− tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still")
1205+ tryCompare(startedSpy, "count", 1);
11771206 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
1178− waitForWiggleToStop(appIcon1)
1207+ appIcon1.wiggleAnim.complete();
1208+
11791209 LauncherModel.setCount(LauncherModel.get(1).appId, 4711)
1180− tryCompare(appIcon1, "wiggling", true, 1000, "appId #1 should not be still")
1210+ tryCompare(startedSpy, "count", 2);
11811211 LauncherModel.setAlerting(LauncherModel.get(1).appId, false)
1182− waitForWiggleToStop(appIcon1)
1212+ appIcon1.wiggleAnim.complete();
11831213 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 0)
11841214 LauncherModel.setCount(LauncherModel.get(1).appId, oldCount)
11851215 }
@@ -1559,5 +1589,35 @@ Rectangle {
15591589
15601590 tryCompare(quickList, "selectedIndex", -1)
15611591 }
1592+
1593+ // Regression test for https://github.com/ubports/ubuntu-touch/issues/1441
1594+ // Short problem description: If the Launcher is dragged out while the
1595+ // Peek animation is running, the Launcher disappears after the peek
1596+ // animation ends. The Launcher does not appear until it is dismissed.
1597+ // To check for a regression: Start the peek animation and show the
1598+ // Launcher while it's running. Once the animation is done, check if
1599+ // it's still visible.
1600+ function test_peekCompletionDoesNotHideLauncher() {
1601+ var launcherPanel = findChild(launcher, "launcherPanel");
1602+ verify(launcherPanel);
1603+ var peekingAnimation = findInvisibleChild(launcherPanel, "peekingAnimation5");
1604+ verify(peekingAnimation);
1605+ startedSpy.target = peekingAnimation;
1606+
1607+ LauncherModel.setAlerting(LauncherModel.get(5).appId, true);
1608+ // The timing of this test is very exact! The animation still needs
1609+ // to be running when the Launcher is out...
1610+ tryCompare(startedSpy, "count", 1);
1611+ launcher.show();
1612+ // ...the Launcher should be visible while the animation is
1613+ // running...
1614+ compare(peekingAnimation.running, true);
1615+ compare(launcherPanel.visible, true);
1616+ tryCompare(peekingAnimation, "running", false);
1617+ // ..and we need to make sure the Launcher completes its next frame
1618+ // after the animation completes
1619+ waitForRendering(launcherPanel);
1620+ compare(launcherPanel.visible, true);
1621+ }
15621622 }
15631623}
tests/qmltests/Notifications/tst_Notifications.qml+2−1
@@ -264,8 +264,9 @@ Item {
264264 id: fakeMouseCB
265265 }
266266 Label {
267+ Layout.fillWidth: true
268+ Layout.fillHeight: true
267269 text: "With fake mouse"
268− anchors.verticalCenter: parent.verticalCenter
269270 }
270271 }
271272
tests/qmltests/Notifications/tst_SwipeToAct.qml+2−1
@@ -149,7 +149,8 @@ Item {
149149 }
150150 Label {
151151 text: "With fake mouse"
152− anchors.verticalCenter: parent.verticalCenter
152+ Layout.fillWidth: true
153+ Layout.fillHeight: true
153154 }
154155 }
155156
tests/qmltests/Panel/PanelUI.qml+1−1
@@ -117,7 +117,7 @@ PanelTest {
117117
118118 ListItem.ItemSelector {
119119 id: modeSelector
120− anchors { left: parent.left; right: parent.right }
120+ Layout.fillWidth: true
121121 activeFocusOnPress: false
122122 text: "Mode"
123123 model: ["staged", "windowed" ]
tests/qmltests/Panel/tst_PanelMenuPage.qml+1−1
@@ -40,7 +40,7 @@ Item {
4040 menuModel: unityMenuModel
4141 submenuIndex: 0
4242
43− factory: Object {
43+ factory: Item {
4444 function load(model) {
4545 return standardMenuComponent;
4646 }
tests/qmltests/Stage/ApplicationCheckBox.qml+6−6
@@ -95,11 +95,12 @@ Column {
9595 }
9696 }
9797 Label {
98+ Layout.alignment: Qt.AlignVCenter
9899 id: appIdLabel
99100 text: root.appId
100− anchors.verticalCenter: parent.verticalCenter
101101 }
102102 Rectangle {
103+ Layout.alignment: Qt.AlignVCenter
103104 color: {
104105 if (d.application) {
105106 if (d.application.state === ApplicationInfoInterface.Starting) {
@@ -117,13 +118,12 @@ Column {
117118 }
118119 width: height
119120 height: appIdLabel.height * 0.7
120− anchors.verticalCenter: parent.verticalCenter
121121 }
122122
123123 MouseArea {
124+ Layout.alignment: Qt.AlignVCenter
124125 width: height
125126 height: appIdLabel.height * 0.7
126− anchors.verticalCenter: parent.verticalCenter
127127 onClicked: root.createSurface()
128128 enabled: d.application && d.application.state === ApplicationInfoInterface.Running
129129 visible: enabled
@@ -146,16 +146,16 @@ Column {
146146 text: promptCount + " prompts"
147147 }
148148 MouseArea {
149+ Layout.alignment: Qt.AlignVCenter
149150 width: height
150151 height: promptsLabel.height * 0.7
151− anchors.verticalCenter: parent.verticalCenter
152152 onClicked: d.application.createPromptSurface()
153153 Label { text: "➕"; anchors.centerIn: parent }
154154 }
155155 MouseArea {
156+ Layout.alignment: Qt.AlignVCenter
156157 width: height
157158 height: promptsLabel.height * 0.7
158− anchors.verticalCenter: parent.verticalCenter
159159 onClicked: d.application.promptSurfaceList.get(0).close()
160160 enabled: d.application && d.application.promptSurfaceList.count > 0
161161 Label { text: "➖"; anchors.centerIn: parent; enabled: parent.enabled }
@@ -173,9 +173,9 @@ Column {
173173 text: "- " + model.surface.name
174174 }
175175 MouseArea {
176+ Layout.alignment: Qt.AlignVCenter
176177 width: height
177178 height: appIdLabel.height * 0.7
178− anchors.verticalCenter: parent.verticalCenter
179179 enabled: model.surface.live
180180 visible: enabled
181181 onClicked: model.surface.setLive(false);
tests/qmltests/Stage/tst_ApplicationWindow.qml+3−2
@@ -99,8 +99,9 @@ Rectangle {
9999 }
100100 }
101101 Label {
102+ Layout.fillWidth: true
103+ Layout.fillHeight: true
102104 text: "Surface"
103− anchors.verticalCenter: parent.verticalCenter
104105 }
105106 }
106107
@@ -123,8 +124,8 @@ Rectangle {
123124
124125 ListItem.ItemSelector {
125126 id: appStateSelector
127+ Layout.fillWidth: true
126128 activeFocusOnPress: false
127− anchors { left: parent.left; right: parent.right }
128129 text: "Application state"
129130 model: ["Starting",
130131 "Running",
tests/qmltests/Stage/tst_PhoneStage.qml+5−4
@@ -251,10 +251,11 @@ Item {
251251 var appsToTest = 6;
252252 var apps = new Array();
253253 for (var i = 0; i < appsToTest; i++) {
254− var item = new Object();
255− item.tag = "App " + i;
256− item.index = i;
257− item.total = appsToTest;
254+ var item = {
255+ tag: "App " + i,
256+ index: i,
257+ total: appsToTest
258+ };
258259 apps.push(item)
259260 }
260261 return apps;
tests/qmltests/Stage/tst_SurfaceContainer.qml+2−1
@@ -125,7 +125,8 @@ Rectangle {
125125
126126 Label {
127127 text: "surface"
128− anchors.verticalCenter: parent.verticalCenter
128+ Layout.fillWidth: true
129+ Layout.fillHeight: true
129130 }
130131 }
131132
tests/qmltests/Stage/tst_WindowResizeArea.qml+2−1
@@ -154,7 +154,8 @@ Item {
154154 Label {
155155 color: "black"
156156 text: "Window loader active"
157− anchors.verticalCenter: parent.verticalCenter
157+ Layout.fillWidth: true
158+ Layout.fillHeight: true
158159 }
159160 }
160161 Label {
tests/qmltests/tst_OrientedShell.qml+261−221
@@ -39,6 +39,8 @@ Rectangle {
3939 width: units.gu(160) + controls.width
4040 height: units.gu(100)
4141
42+ property var tryShell: null
43+
4244 Binding {
4345 target: LightDMController
4446 property: "userMode"
@@ -93,7 +95,7 @@ Rectangle {
9395 State {
9496 name: "mako"
9597 PropertyChanges {
96− target: orientedShellLoader
98+ target: shellRect
9799 width: units.gu(40)
98100 height: units.gu(71)
99101 }
@@ -109,7 +111,7 @@ Rectangle {
109111 State {
110112 name: "manta"
111113 PropertyChanges {
112− target: orientedShellLoader
114+ target: shellRect
113115 width: units.gu(160)
114116 height: units.gu(60)
115117 }
@@ -125,7 +127,7 @@ Rectangle {
125127 State {
126128 name: "flo"
127129 PropertyChanges {
128− target: orientedShellLoader
130+ target: shellRect
129131 width: units.gu(60)
130132 height: units.gu(100)
131133 }
@@ -141,7 +143,7 @@ Rectangle {
141143 State {
142144 name: "desktop"
143145 PropertyChanges {
144− target: orientedShellLoader
146+ target: shellRect
145147 width: units.gu(100)
146148 height: units.gu(65)
147149 }
@@ -156,26 +158,21 @@ Rectangle {
156158 }
157159 ]
158160
159− Loader {
160− id: orientedShellLoader
161+ Component {
162+ id: shellComponent
163+ OrientedShell {
164+ anchors.fill: parent
165+ physicalOrientation: root.physicalOrientation0
166+ orientationLocked: orientationLockedCheckBox.checked
167+ orientationLock: mockOrientationLock
168+ }
169+ }
161170
171+ Rectangle {
172+ id: shellRect
173+ color: "black"
162174 x: ((root.width - controls.width) - width) / 2
163175 y: (root.height - height) / 2
164−
165− focus: true
166−
167− property bool itemDestroyed: false
168− sourceComponent: Component {
169− OrientedShell {
170− anchors.fill: parent
171− physicalOrientation: root.physicalOrientation0
172− orientationLocked: orientationLockedCheckBox.checked
173− orientationLock: mockOrientationLock
174− Component.onDestruction: {
175− orientedShellLoader.itemDestroyed = true;
176− }
177− }
178− }
179176 }
180177
181178 function orientationsToStr(orientations) {
@@ -224,11 +221,19 @@ Rectangle {
224221 id: controlsColumn
225222 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
226223 spacing: units.gu(1)
224+
225+ Button {
226+ text: "Load shell"
227+ onClicked: {
228+ createTryShell();
229+ }
230+ }
231+
227232 Button {
228233 text: "Show Greeter"
229234 activeFocusOnPress: false
230235 onClicked: {
231− if (orientedShellLoader.status !== Loader.Ready)
236+ if (tryShell === null)
232237 return;
233238
234239 LightDM.Greeter.showGreeter();
@@ -241,10 +246,8 @@ Rectangle {
241246 id: rotate0Button
242247 text: root.orientationsToStr(root.physicalOrientation0) + " (0)"
243248 activeFocusOnPress: false
244− onClicked: {
245− orientedShellLoader.item.physicalOrientation = root.physicalOrientation0;
246− }
247− color: orientedShellLoader.item && orientedShellLoader.item.physicalOrientation === root.physicalOrientation0 ?
249+ onClicked: rotate0(tryShell)
250+ color: tryShell && tryShell.physicalOrientation === root.physicalOrientation0 ?
248251 UbuntuColors.green :
249252 __styleInstance.defaultColor
250253 }
@@ -252,10 +255,8 @@ Rectangle {
252255 id: rotate90Button
253256 text: root.orientationsToStr(root.physicalOrientation90) + " (90)"
254257 activeFocusOnPress: false
255− onClicked: {
256− orientedShellLoader.item.physicalOrientation = root.physicalOrientation90;
257− }
258− color: orientedShellLoader.item && orientedShellLoader.item.physicalOrientation === root.physicalOrientation90 ?
258+ onClicked: rotate90(tryShell)
259+ color: tryShell && tryShell.physicalOrientation === root.physicalOrientation90 ?
259260 UbuntuColors.green :
260261 __styleInstance.defaultColor
261262 }
@@ -263,10 +264,8 @@ Rectangle {
263264 id: rotate180Button
264265 text: root.orientationsToStr(root.physicalOrientation180) + " (180)"
265266 activeFocusOnPress: false
266− onClicked: {
267− orientedShellLoader.item.physicalOrientation = root.physicalOrientation180;
268− }
269− color: orientedShellLoader.item && orientedShellLoader.item.physicalOrientation === root.physicalOrientation180 ?
267+ onClicked: rotate180(tryShell)
268+ color: tryShell && tryShell.physicalOrientation === root.physicalOrientation180 ?
270269 UbuntuColors.green :
271270 __styleInstance.defaultColor
272271 }
@@ -274,10 +273,8 @@ Rectangle {
274273 id: rotate270Button
275274 text: root.orientationsToStr(root.physicalOrientation270) + " (270)"
276275 activeFocusOnPress: false
277− onClicked: {
278− orientedShellLoader.item.physicalOrientation = root.physicalOrientation270;
279− }
280− color: orientedShellLoader.item && orientedShellLoader.item.physicalOrientation === root.physicalOrientation270 ?
276+ onClicked: rotate270(tryShell)
277+ color: tryShell && tryShell.physicalOrientation === root.physicalOrientation270 ?
281278 UbuntuColors.green :
282279 __styleInstance.defaultColor
283280 }
@@ -289,14 +286,15 @@ Rectangle {
289286 activeFocusOnPress: false
290287 }
291288 Label {
289+ Layout.fillWidth: true
290+ Layout.fillHeight: true
292291 text: "Orientation Locked"
293− anchors.verticalCenter: parent.verticalCenter
294292 }
295293 }
296294 Button {
297295 text: "Power dialog"
298296 activeFocusOnPress: false
299− onClicked: { testCase.showPowerDialog(); }
297+ onClicked: { testCase.showPowerDialog(tryShell); }
300298 }
301299 ListItem.ItemSelector {
302300 id: deviceNameSelector
@@ -305,9 +303,9 @@ Rectangle {
305303 text: "Device Name"
306304 model: ["mako", "manta", "flo", "desktop"]
307305 onSelectedIndexChanged: {
308− testCase.tearDown();
306+ destroyShell();
309307 applicationArguments.deviceName = model[selectedIndex];
310− orientedShellLoader.active = true;
308+ createTryShell();
311309 }
312310 }
313311 ListItem.ItemSelector {
@@ -350,10 +348,12 @@ Rectangle {
350348 }
351349 }
352350 Label {
351+ Layout.fillWidth: true
352+ Layout.fillHeight: true
353353 text: "Input Method"
354− anchors.verticalCenter: parent.verticalCenter
355354 }
356355 }
356+
357357 Button {
358358 text: Powerd.status === Powerd.On ? "Display ON" : "Display OFF"
359359 activeFocusOnPress: false
@@ -438,15 +438,43 @@ Rectangle {
438438 }
439439 }
440440
441+ function createTryShell() {
442+ if (root.tryShell === null) {
443+ root.tryShell = shellComponent.createObject(shellRect);
444+ }
445+ }
446+
447+ function destroyShell() {
448+ if (root.tryShell === null) {
449+ return;
450+ }
451+ tryShell.destroy();
452+ testCase.wait(100); // Need to wait for things like the SurfaceManager to be destroyed
453+
454+ testCase.tearDown();
455+ }
456+
457+ function rotate0(orientedShell) {
458+ orientedShell.physicalOrientation = root.physicalOrientation0;
459+ }
460+
461+ function rotate90(orientedShell) {
462+ orientedShell.physicalOrientation = root.physicalOrientation90;
463+ }
464+
465+ function rotate180(orientedShell) {
466+ orientedShell.physicalOrientation = root.physicalOrientation180;
467+ }
468+
469+ function rotate270(orientedShell) {
470+ orientedShell.physicalOrientation = root.physicalOrientation270;
471+ }
472+
441473 UnityTestCase {
442474 id: testCase
443475 name: "OrientedShell"
444476 when: windowShown
445477
446− property Item orientedShell: orientedShellLoader.status === Loader.Ready ? orientedShellLoader.item : null
447− property Item shell
448− property QtObject topLevelSurfaceList
449−
450478 SignalSpy { id: signalSpy }
451479 SignalSpy { id: signalSpy2 }
452480
@@ -462,62 +490,41 @@ Rectangle {
462490 }
463491
464492 function init() {
465− if (orientedShellLoader.active) {
466− // happens for the very first test function as shell
467− // is loaded by default
468− tearDown();
469− }
470− }
471−
472− function tearDown() {
473− orientedShellLoader.itemDestroyed = false;
474− orientedShellLoader.active = false;
475−
476− tryCompare(orientedShellLoader, "status", Loader.Null);
477− tryCompare(orientedShellLoader, "item", null);
478− // Loader.status might be Loader.Null and Loader.item might be null but the Loader
479− // actually took place. Likely because Loader waits until the next event loop
480− // iteration to do its work. So to ensure the reload, we will wait until the
481− // Shell instance gets destroyed.
482− tryCompare(orientedShellLoader, "itemDestroyed", true);
483−
484− // kill all (fake) running apps
485− killApps();
486−
487493 while (miceModel.count > 0)
488494 MockInputDeviceBackend.removeDevice("/mouse" + (miceModel.count - 1));
489495 while (touchpadModel.count > 0)
490496 MockInputDeviceBackend.removeDevice("/touchpad" + (touchpadModel.count - 1));
491497 while (keyboardsModel.count > 0)
492498 MockInputDeviceBackend.removeDevice("/kbd" + (keyboardsModel.count - 1))
499+ usageModeSelector.selectStaged();
500+ }
493501
494− appRepeaterConnections.target = null;
495− appRepeaterConnections.itemAddedCallback = null;
496− signalSpy.target = null;
497− signalSpy.signalName = "";
498−
502+ function tearDown() {
503+ // kill all (fake) running apps
504+ testCase.killApps();
499505 LightDM.Greeter.authenticate(""); // reset greeter
500−
501− usageModeSelector.selectStaged();
502506 }
503507
504508 function cleanup() {
505− tryCompare(shell, "waitingOnGreeter", false, 10000); // make sure greeter didn't leave us in disabled state
506− shell = null;
507− topLevelSurfaceList = null;
509+ appRepeaterConnections.target = null;
510+ appRepeaterConnections.itemAddedCallback = null;
511+ signalSpy.target = null;
512+ signalSpy.signalName = "";
508513
509514 tearDown();
510515 }
511516
512517 function test_appSupportingOnlyPrimaryOrientationMakesPhoneShellStayPut() {
513− loadShell("mako");
518+ var orientedShell = loadShell("mako");
519+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
520+ var shell = findChild(orientedShell, "shell");
514521
515522 var primarySurfaceId = topLevelSurfaceList.nextId;
516523 var primaryApp = ApplicationManager.startApplication("primary-oriented-app");
517524 verify(primaryApp);
518− waitUntilAppWindowIsFullyLoaded(primarySurfaceId);
525+ waitUntilAppWindowIsFullyLoaded(primarySurfaceId, orientedShell);
519526
520− var primaryAppWindow = findAppWindowForSurfaceId(primarySurfaceId);
527+ var primaryAppWindow = findAppWindowForSurfaceId(primarySurfaceId, orientedShell);
521528 verify(primaryAppWindow)
522529 var primaryDelegate = findChild(shell, "appDelegate_" + primarySurfaceId);
523530
@@ -526,22 +533,22 @@ Rectangle {
526533 compare(primaryApp.supportedOrientations, Qt.PrimaryOrientation);
527534
528535 tryVerify(function(){return primaryDelegate.surface});
529− verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle));
536+ verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell));
530537
531538 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
532− rotateTo(90);
539+ rotateTo(90, orientedShell);
533540
534− verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle));
541+ verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell));
535542 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
536543
537− rotateTo(180);
544+ rotateTo(180, orientedShell);
538545
539− verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle));
546+ verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell));
540547 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
541548
542− rotateTo(270);
549+ rotateTo(270, orientedShell);
543550
544− verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle));
551+ verify(checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell));
545552 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
546553 }
547554
@@ -552,14 +559,16 @@ Rectangle {
552559 ];
553560 }
554561 function test_appSupportingOnlyPrimaryOrientationWillOnlyRotateInLandscape(data) {
555− loadShell(data.deviceName);
562+ var orientedShell = loadShell(data.deviceName);
563+ var shell = findChild(orientedShell, "shell");
564+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
556565
557566 var primarySurfaceId = topLevelSurfaceList.nextId;
558567 var primaryApp = ApplicationManager.startApplication("primary-oriented-app");
559568 verify(primaryApp);
560− waitUntilAppWindowIsFullyLoaded(primarySurfaceId);
569+ waitUntilAppWindowIsFullyLoaded(primarySurfaceId, orientedShell);
561570
562− var primaryAppWindow = findAppWindowForSurfaceId(primarySurfaceId);
571+ var primaryAppWindow = findAppWindowForSurfaceId(primarySurfaceId, orientedShell);
563572 verify(primaryAppWindow)
564573
565574 // primary-oriented-app supports only primary orientation
@@ -572,22 +581,22 @@ Rectangle {
572581
573582 tryCompareFunction(function(){return primaryApp.surfaceList.count > 0;}, true);
574583
575− tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle)}, true);
584+ tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell)}, true);
576585 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
577586
578− rotateTo(90);
587+ rotateTo(90, orientedShell);
579588
580− tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle)}, true);
589+ tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle, orientedShell)}, true);
581590 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
582591
583− rotateTo(180);
592+ rotateTo(180, orientedShell);
584593
585− tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle + 180)}, true);
594+ tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle + 180, orientedShell)}, true);
586595 compare(shell.transformRotationAngle, root.primaryOrientationAngle + 180);
587596
588− rotateTo(270);
597+ rotateTo(270, orientedShell);
589598
590− tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle + 180)}, true);
599+ tryCompareFunction(function(){return checkAppSurfaceOrientation(primaryAppWindow, primaryApp, root.primaryOrientationAngle + 180, orientedShell)}, true);
591600 compare(shell.transformRotationAngle, root.primaryOrientationAngle + 180);
592601 }
593602
@@ -599,7 +608,8 @@ Rectangle {
599608 ];
600609 }
601610 function test_greeterRemainsInPrimaryOrientation(data) {
602− loadShell(data.deviceName);
611+ var orientedShell = loadShell(data.deviceName);
612+ var shell = findChild(orientedShell, "shell");
603613
604614 var gmailApp = ApplicationManager.startApplication("gmail-webapp");
605615 verify(gmailApp);
@@ -613,17 +623,17 @@ Rectangle {
613623 tryCompare(shell, "orientationChangesEnabled", true);
614624
615625 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
616− rotateTo(90);
626+ rotateTo(90, orientedShell);
617627 tryCompare(shell, "transformRotationAngle", root.primaryOrientationAngle + 90);
618628
619− showGreeter();
629+ showGreeter(orientedShell);
620630
621631 tryCompare(shell, "transformRotationAngle", root.primaryOrientationAngle);
622− rotateTo(180);
632+ rotateTo(180, orientedShell);
623633 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
624− rotateTo(270);
634+ rotateTo(270, orientedShell);
625635 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
626− rotateTo(0);
636+ rotateTo(0, orientedShell);
627637 compare(shell.transformRotationAngle, root.primaryOrientationAngle);
628638 }
629639
@@ -638,7 +648,9 @@ Rectangle {
638648 ];
639649 }
640650 function test_appRotatesWindowContents(data) {
641− loadShell(data.deviceName);
651+ var orientedShell = loadShell(data.deviceName);
652+ var shell = findChild(orientedShell, "shell");
653+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
642654
643655 if (data.windowed) {
644656 usageModeSelector.selectWindowed();
@@ -658,7 +670,7 @@ Rectangle {
658670 compare(cameraApp.supportedOrientations, Qt.PortraitOrientation | Qt.LandscapeOrientation
659671 | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation);
660672
661− waitUntilAppWindowIsFullyLoaded(cameraSurfaceId);
673+ waitUntilAppWindowIsFullyLoaded(cameraSurfaceId, orientedShell);
662674
663675 var focusChangedSpy = signalSpy;
664676 focusChangedSpy.clear();
@@ -686,7 +698,7 @@ Rectangle {
686698 transitionSpy.signalName = "runningChanged";
687699 verify(transitionSpy.valid);
688700
689− rotateTo(90);
701+ rotateTo(90, orientedShell);
690702
691703 tryCompare(cameraSurface, "orientationAngle", data.orientationAngleAfterRotation);
692704
@@ -724,7 +736,9 @@ Rectangle {
724736 ];
725737 }
726738 function test_switchingToAppWithDifferentRotation(data) {
727− loadShell(data.deviceName);
739+ var orientedShell = loadShell(data.deviceName);
740+ var shell = findChild(orientedShell, "shell");
741+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
728742 var gmailSurfaceId = topLevelSurfaceList.nextId;
729743 var gmailApp = ApplicationManager.startApplication("gmail-webapp");
730744 verify(gmailApp);
@@ -734,7 +748,7 @@ Rectangle {
734748 compare(gmailApp.supportedOrientations, Qt.PortraitOrientation | Qt.LandscapeOrientation
735749 | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation);
736750
737− waitUntilAppWindowIsFullyLoaded(gmailSurfaceId);
751+ waitUntilAppWindowIsFullyLoaded(gmailSurfaceId, orientedShell);
738752
739753 var musicSurfaceId = topLevelSurfaceList.nextId;
740754 var musicApp = ApplicationManager.startApplication("music-app");
@@ -749,13 +763,13 @@ Rectangle {
749763 compare(musicDelegate.stage, ApplicationInfoInterface.MainStage);
750764 }
751765
752− waitUntilAppWindowIsFullyLoaded(musicSurfaceId);
766+ waitUntilAppWindowIsFullyLoaded(musicSurfaceId, orientedShell);
753767 tryCompare(shell, "orientationChangesEnabled", true);
754768
755− rotateTo(90);
769+ rotateTo(90, orientedShell);
756770 tryCompare(shell, "transformRotationAngle", data.shellAngleAfterRotation);
757771
758− performEdgeSwipeToSwitchToPreviousApp();
772+ performEdgeSwipeToSwitchToPreviousApp(orientedShell);
759773
760774 tryCompare(shell, "mainAppWindowOrientationAngle", data.shellAngleAfterRotation);
761775 compare(shell.transformRotationAngle, data.shellAngleAfterRotation);
@@ -783,7 +797,9 @@ Rectangle {
783797 orientation (Screen.orientation), so they are both equally good alternatives
784798 */
785799 function test_rotateToUnsupportedDeviceOrientation(data) {
786− loadShell("mako");
800+ var orientedShell = loadShell("mako");
801+ var shell = findChild(orientedShell, "shell");
802+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
787803 var twitterSurfaceId = topLevelSurfaceList.nextId;
788804 var twitterApp = ApplicationManager.startApplication("twitter-webapp");
789805 verify(twitterApp);
@@ -793,12 +809,12 @@ Rectangle {
793809 compare(twitterApp.supportedOrientations, Qt.PortraitOrientation | Qt.LandscapeOrientation
794810 | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation);
795811
796− waitUntilAppWindowIsFullyLoaded(twitterSurfaceId);
812+ waitUntilAppWindowIsFullyLoaded(twitterSurfaceId, orientedShell);
797813
798− rotateTo(data.rotationAngle);
814+ rotateTo(data.rotationAngle, orientedShell);
799815 tryCompare(shell, "transformRotationAngle", data.rotationAngle);
800816
801− rotateTo(180);
817+ rotateTo(180, orientedShell);
802818 tryCompare(shell, "transformRotationAngle", data.rotationAngle);
803819 }
804820 function test_rotateToUnsupportedDeviceOrientation_data() {
@@ -809,7 +825,9 @@ Rectangle {
809825 }
810826
811827 function test_launchLandscapeOnlyAppFromPortrait() {
812− loadShell("mako");
828+ var orientedShell = loadShell("mako");
829+ var shell = findChild(orientedShell, "shell");
830+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
813831 var weatherSurfaceId = topLevelSurfaceList.nextId;
814832 var weatherApp = ApplicationManager.startApplication("ubuntu-weather-app");
815833 verify(weatherApp);
@@ -817,7 +835,7 @@ Rectangle {
817835 // ensure the mock app is as we expect
818836 compare(weatherApp.supportedOrientations, Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation);
819837
820− waitUntilAppWindowIsFullyLoaded(weatherSurfaceId);
838+ waitUntilAppWindowIsFullyLoaded(weatherSurfaceId, orientedShell);
821839
822840 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
823841 waitUntilTransitionsEnd(rotationStates);
@@ -849,13 +867,15 @@ Rectangle {
849867 have an opacity > 0.
850868 */
851869 function test_greeterStaysAwayAfterRotation() {
852− loadShell("mako");
870+ var orientedShell = loadShell("mako");
871+ var shell = findChild(orientedShell, "shell");
872+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
853873
854874 // Load an app which only supports primary
855875 var primarySurfaceId = topLevelSurfaceList.nextId;
856876 var primaryApp = ApplicationManager.startApplication("primary-oriented-app");
857877 verify(primaryApp);
858− waitUntilAppWindowIsFullyLoaded(primarySurfaceId);
878+ waitUntilAppWindowIsFullyLoaded(primarySurfaceId, orientedShell);
859879
860880 var twitterSurfaceId = topLevelSurfaceList.nextId;
861881 var twitterApp = ApplicationManager.startApplication("twitter-webapp");
@@ -866,17 +886,17 @@ Rectangle {
866886 compare(twitterApp.supportedOrientations, Qt.PortraitOrientation | Qt.LandscapeOrientation
867887 | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation);
868888
869− waitUntilAppWindowIsFullyLoaded(twitterSurfaceId);
870− waitUntilAppWindowCanRotate(twitterSurfaceId);
889+ waitUntilAppWindowIsFullyLoaded(twitterSurfaceId, orientedShell);
890+ waitUntilAppWindowCanRotate(twitterSurfaceId, orientedShell);
871891
872892 // go back to primary-oriented-app
873− performEdgeSwipeToSwitchToPreviousApp();
893+ performEdgeSwipeToSwitchToPreviousApp(orientedShell);
874894
875− rotateTo(90);
895+ rotateTo(90, orientedShell);
876896 wait(1); // spin the event loop to let all bindings do their thing
877897 tryCompare(shell, "transformRotationAngle", 0);
878898
879− performEdgeSwipeToShowAppSpread();
899+ performEdgeSwipeToShowAppSpread(shell);
880900
881901 // wait until things have settled
882902 var greeter = findChild(shell, "greeter");
@@ -901,7 +921,9 @@ Rectangle {
901921 }
902922 function test_appInSideStageDoesntRotateOnStartUp(data) {
903923 WindowStateStorage.saveStage("twitter-webapp", ApplicationInfoInterface.SideStage)
904− loadShell(data.deviceName);
924+ var orientedShell = loadShell(data.deviceName);
925+ var shell = findChild(orientedShell, "shell");
926+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
905927
906928 var twitterSurfaceId = topLevelSurfaceList.nextId;
907929 var twitterApp = ApplicationManager.startApplication("twitter-webapp");
@@ -931,7 +953,8 @@ Rectangle {
931953 ];
932954 }
933955 function test_portraitOnlyAppInSideStage(data) {
934− loadShell(data.deviceName);
956+ var orientedShell = loadShell(data.deviceName);
957+ var shell = findChild(orientedShell, "shell");
935958
936959 var dialerDelegate = null;
937960 verify(appRepeaterConnections.target);
@@ -972,12 +995,13 @@ Rectangle {
972995 ];
973996 }
974997 function test_launchedAppHasActiveFocus(data) {
975− loadShell(data.deviceName);
998+ var orientedShell = loadShell(data.deviceName);
999+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
9761000
9771001 var gmailSurfaceId = topLevelSurfaceList.nextId;
9781002 var gmailApp = ApplicationManager.startApplication("gmail-webapp");
9791003 verify(gmailApp);
980− waitUntilAppWindowIsFullyLoaded(gmailSurfaceId);
1004+ waitUntilAppWindowIsFullyLoaded(gmailSurfaceId, orientedShell);
9811005
9821006 var gmailSurface = gmailApp.surfaceList.get(0);
9831007 verify(gmailSurface);
@@ -986,12 +1010,14 @@ Rectangle {
9861010 }
9871011
9881012 function test_launchLandscapeOnlyAppOverPortraitOnlyDashThenSwitchToDash() {
989− loadShell("mako");
1013+ var orientedShell = loadShell("mako");
1014+ var shell = findChild(orientedShell, "shell");
1015+ var topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
9901016
9911017 var dashSurfaceId = topLevelSurfaceList.nextId;
9921018 var dashApp = ApplicationManager.startApplication("unity8-dash");
9931019 verify(dashApp);
994− waitUntilAppWindowIsFullyLoaded(dashSurfaceId);
1020+ waitUntilAppWindowIsFullyLoaded(dashSurfaceId, orientedShell);
9951021
9961022 // starts as portrait, as unity8-dash is portrait only
9971023 tryCompare(shell, "transformRotationAngle", 0);
@@ -1003,7 +1029,7 @@ Rectangle {
10031029 // ensure the mock app is as we expect
10041030 compare(weatherApp.supportedOrientations, Qt.LandscapeOrientation | Qt.InvertedLandscapeOrientation);
10051031
1006− waitUntilAppWindowIsFullyLoaded(weatherSurfaceId);
1032+ waitUntilAppWindowIsFullyLoaded(weatherSurfaceId, orientedShell);
10071033
10081034 // should have rotated to landscape
10091035 tryCompareFunction(function () { return shell.transformRotationAngle == 270
@@ -1036,13 +1062,13 @@ Rectangle {
10361062 }
10371063
10381064 function test_attachRemoveInputDevices(data) {
1039− loadShell("mako")
1040− MockInputDeviceBackend.removeDevice("/indicator_kbd0");
1065+ var orientedShell = loadShell("mako");
10411066 var shell = findChild(orientedShell, "shell");
1067+ MockInputDeviceBackend.removeDevice("/indicator_kbd0");
10421068 var inputMethod = findChild(shell, "inputMethod");
10431069
1044− var oldWidth = orientedShellLoader.width;
1045− orientedShellLoader.width = data.screenWidth;
1070+ var oldWidth = shellRect.width;
1071+ shellRect.width = data.screenWidth;
10461072
10471073 tryCompare(shell, "usageScenario", "phone");
10481074 tryCompare(inputMethod, "enabled", true);
@@ -1060,17 +1086,17 @@ Rectangle {
10601086 tryCompare(oskSettings, "disableHeight", data.expectedMode == "desktop" || data.kbd);
10611087
10621088 // Restore width
1063− orientedShellLoader.width = oldWidth;
1089+ shellRect.width = oldWidth;
10641090 }
10651091
10661092 function test_screenSizeChanges() {
1067− loadShell("mako")
1093+ var orientedShell = loadShell("mako");
10681094 var shell = findChild(orientedShell, "shell");
10691095
10701096 tryCompare(shell, "usageScenario", "phone");
10711097
10721098 // make screen larger
1073− orientedShellLoader.width = units.gu(90);
1099+ shellRect.width = units.gu(90);
10741100 tryCompare(shell, "usageScenario", "phone");
10751101
10761102 // plug a mouse
@@ -1078,17 +1104,18 @@ Rectangle {
10781104 tryCompare(shell, "usageScenario", "desktop");
10791105
10801106 // make the screen smaller again, it should go back to staged even though there's still a mouse around
1081− orientedShellLoader.width = units.gu(40);
1107+ shellRect.width = units.gu(40);
10821108
10831109 tryCompare(shell, "usageScenario", "phone");
10841110 }
10851111
10861112 function test_overrideStaged() {
1087− loadShell("mako")
1113+ var orientedShell = loadShell("mako");
1114+ var shell = findChild(orientedShell, "shell");
10881115
10891116 // make sure we're big enough so that the automatism starts working
1090− var oldWidth = orientedShellLoader.width;
1091− orientedShellLoader.width = units.gu(100);
1117+ var oldWidth = shellRect.width;
1118+ shellRect.width = units.gu(100);
10921119
10931120 // start off by plugging a mouse, we should switch to windowed
10941121 MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
@@ -1115,7 +1142,7 @@ Rectangle {
11151142 tryCompare(shell, "usageScenario", "phone");
11161143
11171144 // Restore width
1118− orientedShellLoader.width = oldWidth;
1145+ shellRect.width = oldWidth;
11191146 }
11201147
11211148 function test_setsUsageModeOnStartup() {
@@ -1125,17 +1152,19 @@ Rectangle {
11251152 compare(unity8Settings.usageMode, "Staged");
11261153
11271154 // Load shell, and have it pick desktop
1128− loadShell("desktop");
1155+ var orientedShell = loadShell("desktop");
1156+ var shell = findChild(orientedShell, "shell");
11291157 compare(shell.usageScenario, "desktop");
11301158 compare(unity8Settings.usageMode, "Windowed");
11311159 }
11321160
11331161 function test_overrideWindowed() {
1134− loadShell("mako")
1162+ var orientedShell = loadShell("mako")
1163+ var shell = findChild(orientedShell, "shell");
11351164
11361165 // make sure we're big enough so that the automatism starts working
1137− var oldWidth = orientedShellLoader.width;
1138− orientedShellLoader.width = units.gu(100);
1166+ var oldWidth = shellRect.width;
1167+ shellRect.width = units.gu(100);
11391168
11401169 // No mouse attached... we should be in staged
11411170 tryCompare(shell, "usageScenario", "phone");
@@ -1153,7 +1182,7 @@ Rectangle {
11531182 tryCompare(shell, "usageScenario", "phone");
11541183
11551184 // Restore width
1156− orientedShellLoader.width = oldWidth;
1185+ shellRect.width = oldWidth;
11571186 }
11581187
11591188 /*
@@ -1178,7 +1207,8 @@ Rectangle {
11781207 hence the bug.
11791208 */
11801209 function test_phoneWithSpreadInLandscapeWhenGreeterShowsUp() {
1181− loadShell("mako");
1210+ var orientedShell = loadShell("mako");
1211+ var shell = findChild(orientedShell, "shell");
11821212
11831213 var gmailApp = ApplicationManager.startApplication("gmail-webapp");
11841214 verify(gmailApp);
@@ -1191,12 +1221,12 @@ Rectangle {
11911221 // wait until it's able to rotate
11921222 tryCompare(shell, "orientationChangesEnabled", true);
11931223
1194− rotateTo(90);
1224+ rotateTo(90, orientedShell);
11951225 tryCompare(shell, "transformRotationAngle", root.primaryOrientationAngle + 90);
11961226
1197− performEdgeSwipeToShowAppSpread();
1227+ performEdgeSwipeToShowAppSpread(shell);
11981228
1199− showGreeter();
1229+ showGreeter(orientedShell);
12001230
12011231 tryCompare(shell, "transformRotationAngle", root.primaryOrientationAngle);
12021232 }
@@ -1221,22 +1251,24 @@ Rectangle {
12211251 - The portrait-only application rotates freely
12221252 */
12231253 function test_lockPhoneAfterClosingAppInSpreadThenUnlockAndRotate() {
1224− loadShell("mako");
1254+ var orientedShell = loadShell("mako");
1255+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
1256+ var shell = findChild(orientedShell, "shell");
12251257
12261258 var primarySurfaceId = topLevelSurfaceList.nextId;
12271259 var primaryApp = ApplicationManager.startApplication("primary-oriented-app");
12281260 verify(primaryApp);
1229− waitUntilAppWindowIsFullyLoaded(primarySurfaceId);
1261+ waitUntilAppWindowIsFullyLoaded(primarySurfaceId, orientedShell);
12301262
12311263 var gmailSurfaceId = topLevelSurfaceList.nextId;
12321264 var gmailApp = ApplicationManager.startApplication("gmail-webapp");
12331265 verify(gmailApp);
12341266
1235− waitUntilAppWindowIsFullyLoaded(gmailSurfaceId);
1267+ waitUntilAppWindowIsFullyLoaded(gmailSurfaceId, orientedShell);
12361268
1237− performEdgeSwipeToShowAppSpread();
1269+ performEdgeSwipeToShowAppSpread(shell);
12381270
1239− swipeToCloseCurrentAppInSpread();
1271+ swipeToCloseCurrentAppInSpread(orientedShell);
12401272
12411273 // press the power key once
12421274 Powerd.setStatus(Powerd.Off, Powerd.Unknown);
@@ -1246,23 +1278,24 @@ Rectangle {
12461278 // and a second time to turn the display back on
12471279 Powerd.setStatus(Powerd.On, Powerd.Unknown);
12481280
1249− swipeAwayGreeter();
1281+ swipeAwayGreeter(orientedShell);
12501282
1251− tryCompareFunction(function() { return isAppSurfaceFocused(primarySurfaceId)}, true, 10000)
1283+ tryCompareFunction(function() { return isAppSurfaceFocused(topLevelSurfaceList, primarySurfaceId)}, true, 10000)
12521284
12531285 signalSpy.clear();
12541286 signalSpy.target = shell;
12551287 signalSpy.signalName = "widthChanged";
12561288 verify(signalSpy.valid);
12571289
1258− rotateTo(90);
1290+ rotateTo(90, orientedShell);
12591291
12601292 // shell shouldn't have change its orientation at any moment
12611293 compare(signalSpy.count, 0);
12621294 }
12631295
12641296 function test_moveToExternalMonitor() {
1265− loadShell("flo");
1297+ var orientedShell = loadShell("flo");
1298+ var shell = findChild(orientedShell, "shell");
12661299
12671300 compare(orientedShell.orientation, Qt.InvertedLandscapeOrientation);
12681301 compare(shell.transformRotationAngle, 90);
@@ -1296,7 +1329,9 @@ Rectangle {
12961329 ];
12971330 }
12981331 function test_portraitOnlyAppInLandscapeDesktop(data) {
1299− loadShell(data.deviceName);
1332+ var orientedShell = loadShell(data.deviceName);
1333+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
1334+ var shell = findChild(orientedShell, "shell");
13001335
13011336 ////
13021337 // setup preconditions (put shell in Desktop mode and landscape)
@@ -1304,8 +1339,8 @@ Rectangle {
13041339 usageModeSelector.selectWindowed();
13051340
13061341 orientedShell.physicalOrientation = orientedShell.orientations.landscape;
1307− waitUntilShellIsInOrientation(orientedShell.orientations.landscape);
1308− waitForRotationAnimationsToFinish();
1342+ waitUntilShellIsInOrientation(orientedShell.orientations.landscape, orientedShell);
1343+ waitForRotationAnimationsToFinish(orientedShell);
13091344
13101345 ////
13111346 // Launch a portrait-only application
@@ -1318,39 +1353,39 @@ Rectangle {
13181353 compare(dialerApp.rotatesWindowContents, false);
13191354 compare(dialerApp.supportedOrientations, Qt.PortraitOrientation | Qt.InvertedPortraitOrientation);
13201355
1321− waitUntilAppWindowIsFullyLoaded(dialerSurfaceId);
1322− waitUntilAppWindowCanRotate(dialerSurfaceId);
1323− verify(isAppSurfaceFocused(dialerSurfaceId));
1356+ waitUntilAppWindowIsFullyLoaded(dialerSurfaceId, orientedShell);
1357+ waitUntilAppWindowCanRotate(dialerSurfaceId, orientedShell);
1358+ verify(isAppSurfaceFocused(topLevelSurfaceList, dialerSurfaceId));
13241359
13251360 ////
13261361 // check outcome (shell should stay in landscape)
13271362
1328− waitForRotationAnimationsToFinish();
1363+ waitForRotationAnimationsToFinish(orientedShell);
13291364 compare(shell.orientation, orientedShell.orientations.landscape);
13301365 }
13311366
13321367 // angle - rotation angle in degrees clockwise, relative to the primary orientation.
1333− function rotateTo(angle) {
1368+ function rotateTo(angle, orientedShell) {
13341369 switch (angle) {
13351370 case 0:
1336− rotate0Button.clicked();
1371+ root.rotate0(orientedShell);
13371372 break;
13381373 case 90:
1339− rotate90Button.clicked();
1374+ root.rotate90(orientedShell);
13401375 break;
13411376 case 180:
1342− rotate180Button.clicked();
1377+ root.rotate180(orientedShell);
13431378 break;
13441379 case 270:
1345− rotate270Button.clicked();
1380+ root.rotate270(orientedShell);
13461381 break;
13471382 default:
13481383 verify(false);
13491384 }
1350− waitForRotationAnimationsToFinish();
1385+ waitForRotationAnimationsToFinish(orientedShell);
13511386 }
13521387
1353− function waitForRotationAnimationsToFinish() {
1388+ function waitForRotationAnimationsToFinish(orientedShell) {
13541389 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
13551390 verify(rotationStates.d);
13561391 verify(rotationStates.d.stateUpdateTimer);
@@ -1372,8 +1407,8 @@ Rectangle {
13721407 tryCompare(appWindowStates, "state", "surface");
13731408 }
13741409
1375− function findAppWindowForSurfaceId(surfaceId) {
1376− var delegate = findChild(shell, "appDelegate_" + surfaceId);
1410+ function findAppWindowForSurfaceId(surfaceId, orientedShell) {
1411+ var delegate = findChild(orientedShell, "appDelegate_" + surfaceId);
13771412 verify(delegate);
13781413 var appWindow = findChild(delegate, "appWindow");
13791414 return appWindow;
@@ -1381,25 +1416,28 @@ Rectangle {
13811416
13821417 // Wait until the ApplicationWindow for the given Application object is fully loaded
13831418 // (ie, the real surface has replaced the splash screen)
1384− function waitUntilAppWindowIsFullyLoaded(surfaceId) {
1385− var appWindow = findAppWindowForSurfaceId(surfaceId);
1419+ function waitUntilAppWindowIsFullyLoaded(surfaceId, orientedShell) {
1420+ var appWindow = findAppWindowForSurfaceId(surfaceId, orientedShell);
13861421 var appWindowStateGroup = findInvisibleChild(appWindow, "applicationWindowStateGroup");
13871422 tryCompareFunction(function() { return appWindowStateGroup.state === "surface" }, true);
13881423 waitUntilTransitionsEnd(appWindowStateGroup);
13891424 }
13901425
1391− function waitUntilAppWindowCanRotate(surfaceId) {
1392− var appWindow = findAppWindowForSurfaceId(surfaceId);
1426+ function waitUntilAppWindowCanRotate(surfaceId, orientedShell) {
1427+ var appWindow = findAppWindowForSurfaceId(surfaceId, orientedShell);
13931428 tryCompare(appWindow, "orientationChangesEnabled", true);
13941429 }
13951430
1396− function waitUntilShellIsInOrientation(orientation) {
1431+ function waitUntilShellIsInOrientation(orientation, orientedShell) {
1432+ var shell = findInvisibleChild(orientedShell, "shell");
13971433 tryCompare(shell, "orientation", orientation);
13981434 var rotationStates = findInvisibleChild(orientedShell, "rotationStates");
13991435 waitUntilTransitionsEnd(rotationStates);
14001436 }
14011437
1402− function performEdgeSwipeToSwitchToPreviousApp() {
1438+ function performEdgeSwipeToSwitchToPreviousApp(orientedShell) {
1439+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
1440+ var shell = findChild(orientedShell, "shell");
14031441 // swipe just enough to ensure an app switch action.
14041442 // If we swipe too much we will trigger the spread mode
14051443 // and we don't want that.
@@ -1414,41 +1452,43 @@ Rectangle {
14141452 tryCompareFunction(function(){ return topLevelSurfaceList.idAt(0); }, previousSurfaceId);
14151453 }
14161454
1417− function performEdgeSwipeToShowAppSpread() {
1418− var touchStartY = shell.height / 2;
1419− touchFlick(shell,
1420− shell.width - 1, touchStartY,
1455+ function performEdgeSwipeToShowAppSpread(orientedShell) {
1456+ var touchStartY = orientedShell.height / 2;
1457+ touchFlick(orientedShell,
1458+ orientedShell.width - 1, touchStartY,
14211459 0, touchStartY);
14221460
1423− var stage = findChild(shell, "stage");
1461+ var stage = findChild(orientedShell, "stage");
14241462 tryCompare(stage, "state", "spread");
14251463 waitForRendering(stage);
14261464 }
14271465
1428− function showPowerDialog() {
1466+ function showPowerDialog(orientedShell) {
14291467 var dialogs = findChild(orientedShell, "dialogs");
14301468 var dialogsPrivate = findInvisibleChild(dialogs, "dialogsPrivate");
14311469 dialogsPrivate.showPowerDialog();
14321470 }
14331471
1434− function swipeAwayGreeter() {
1472+ function swipeAwayGreeter(orientedShell) {
1473+ var shell = findChild(orientedShell, "shell");
14351474 var greeter = findChild(shell, "greeter");
1475+ verify(greeter);
14361476 tryCompare(greeter, "fullyShown", true);
14371477 waitForRendering(greeter)
14381478
14391479 var touchX = shell.width * .75;
14401480 var touchY = shell.height / 2;
1441− touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
1481+ touchFlick(shell, touchX, touchY, orientedShell.width * 0.1, touchY);
14421482
14431483 // wait until the animation has finished
14441484 tryCompare(greeter, "shown", false);
14451485 waitForRendering(greeter);
14461486 }
14471487
1448− function showGreeter() {
1488+ function showGreeter(orientedShell) {
14491489 LightDM.Greeter.showGreeter();
14501490 // wait until the animation has finished
1451− var greeter = findChild(shell, "greeter");
1491+ var greeter = findChild(orientedShell, "greeter");
14521492 tryCompare(greeter, "fullyShown", true);
14531493 }
14541494
@@ -1456,32 +1496,29 @@ Rectangle {
14561496 applicationArguments.deviceName = deviceName;
14571497
14581498 // reload our test subject to get it in a fresh state once again
1459− orientedShellLoader.active = true;
1460−
1461− tryCompare(orientedShellLoader, "status", Loader.Ready);
1462− removeTimeConstraintsFromSwipeAreas(orientedShellLoader.item);
1499+ var orientedShell = createTemporaryObject(shellComponent, shellRect);
14631500
1464− shell = findChild(orientedShell, "shell");
1501+ removeTimeConstraintsFromSwipeAreas(orientedShell);
14651502
1466− topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
1467− verify(topLevelSurfaceList);
1503+ var shell = findChild(orientedShell, "shell");
14681504
14691505 tryCompare(shell, "waitingOnGreeter", false); // reset by greeter when ready
14701506
1471− waitUntilShellIsInOrientation(root.physicalOrientation0);
1507+ waitUntilShellIsInOrientation(root.physicalOrientation0, orientedShell);
14721508
1473− waitForGreeterToStabilize();
1509+ waitForGreeterToStabilize(orientedShell);
14741510
1475− swipeAwayGreeter();
1511+ swipeAwayGreeter(orientedShell);
14761512
14771513 var appRepeater = findChild(shell, "appRepeater");
14781514 if (appRepeater) {
14791515 appRepeaterConnections.target = appRepeater;
14801516 }
1517+ return orientedShell;
14811518 }
14821519
1483− function waitForGreeterToStabilize() {
1484− var greeter = findChild(shell, "greeter");
1520+ function waitForGreeterToStabilize(orientedShell) {
1521+ var greeter = findChild(orientedShell, "greeter");
14851522 verify(greeter);
14861523
14871524 var loginList = findChild(greeter, "loginList");
@@ -1494,7 +1531,7 @@ Rectangle {
14941531 }
14951532
14961533 // expectedAngle is in orientedShell's coordinate system
1497− function checkAppSurfaceOrientation(item, app, expectedAngle) {
1534+ function checkAppSurfaceOrientation(item, app, expectedAngle, orientedShell) {
14981535 var surface = app.surfaceList.get(0);
14991536 if (!surface) {
15001537 console.warn("no surface");
@@ -1537,8 +1574,9 @@ Rectangle {
15371574 return null;
15381575 }
15391576
1540− function swipeToCloseCurrentAppInSpread() {
1541− var delegateToClose = findChild(shell, "appDelegate_" + topLevelSurfaceList.idAt(0));
1577+ function swipeToCloseCurrentAppInSpread(orientedShell) {
1578+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
1579+ var delegateToClose = findChild(orientedShell, "appDelegate_" + topLevelSurfaceList.idAt(0));
15421580 verify(delegateToClose);
15431581
15441582 var appIdToClose = ApplicationManager.get(0).appId;
@@ -1555,7 +1593,7 @@ Rectangle {
15551593 compare(ApplicationManager.findApplication(appIdToClose), null);
15561594 }
15571595
1558− function isAppSurfaceFocused(surfaceId) {
1596+ function isAppSurfaceFocused(topLevelSurfaceList, surfaceId) {
15591597 var index = topLevelSurfaceList.indexForId(surfaceId);
15601598 var surface = topLevelSurfaceList.surfaceAt(index);
15611599 verify(surface);
@@ -1570,9 +1608,9 @@ Rectangle {
15701608 }
15711609
15721610 function test_tabCyclyingInShutdownDialog(data) {
1573− loadShell("mako");
1611+ var orientedShell = loadShell("mako");
15741612
1575− testCase.showPowerDialog();
1613+ testCase.showPowerDialog(orientedShell);
15761614
15771615 var dialogs = findChild(orientedShell, "dialogs");
15781616 var buttons = findChildsByType(dialogs, "Button");
@@ -1598,9 +1636,9 @@ Rectangle {
15981636 }
15991637
16001638 function test_escClosesShutdownDialog() {
1601− loadShell("mako");
1639+ var orientedShell = loadShell("mako");
16021640
1603− testCase.showPowerDialog();
1641+ testCase.showPowerDialog(orientedShell);
16041642
16051643 var dialogLoader = findChild(orientedShell, "dialogLoader");
16061644 tryCompareFunction(function() { return dialogLoader.item !== null }, true);
@@ -1611,20 +1649,21 @@ Rectangle {
16111649 }
16121650
16131651 function test_focusOnShutdownDialogClose() {
1614− loadShell("manta");
1652+ var orientedShell = loadShell("manta");
1653+ var topLevelSurfaceList = findInvisibleChild(orientedShell, "topLevelSurfaceList");
16151654 usageModeSelector.selectWindowed();
16161655
16171656 var surfaceId = topLevelSurfaceList.nextId;
16181657 var app = ApplicationManager.startApplication("twitter-webapp");
1619− waitUntilAppWindowIsFullyLoaded(surfaceId);
1658+ waitUntilAppWindowIsFullyLoaded(surfaceId, orientedShell);
16201659
1621− var primaryAppWindow = findAppWindowForSurfaceId(surfaceId);
1660+ var primaryAppWindow = findAppWindowForSurfaceId(surfaceId, orientedShell);
16221661 var surface = app.surfaceList.get(0);
16231662 var surfaceItem = findSurfaceItem(primaryAppWindow, surface);
16241663
16251664 compare(window.activeFocusItem, surfaceItem);
16261665
1627− testCase.showPowerDialog();
1666+ testCase.showPowerDialog(orientedShell);
16281667
16291668 var dialogLoader = findChild(orientedShell, "dialogLoader");
16301669 tryVerify(function() { return dialogLoader.item !== null });
@@ -1635,7 +1674,7 @@ Rectangle {
16351674 compare(window.activeFocusItem, surfaceItem);
16361675
16371676 // Do it twice, our previous solution failed the second time ^_^
1638− testCase.showPowerDialog();
1677+ testCase.showPowerDialog(orientedShell);
16391678
16401679 tryVerify(function() { return dialogLoader.item !== null });
16411680
@@ -1646,7 +1685,8 @@ Rectangle {
16461685 }
16471686
16481687 function test_tutorialDisabledWithNoTouchscreen() {
1649− loadShell("desktop");
1688+ var orientedShell = loadShell("desktop");
1689+ var shell = findChild(orientedShell, "shell");
16501690 usageModeSelector.selectWindowed();
16511691
16521692 MockInputDeviceBackend.addMockDevice("/touchscreen", InputInfo.TouchScreen);
tests/qmltests/tst_ShellWithPin.qml+67−77
@@ -1,5 +1,6 @@
11/*
22 * Copyright (C) 2014-2016 Canonical, Ltd.
3+ * Copyright (C) 2021 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -36,7 +37,6 @@ Item {
3637 Component.onCompleted: {
3738 // must set the mock mode before loading the Shell
3839 LightDMController.userMode = "single-pin";
39− shellLoader.active = true;
4040 }
4141
4242 QtObject {
@@ -55,35 +55,43 @@ Item {
5555 }
5656 }
5757
58+ property var tryShell: null
59+
60+ Component {
61+ id: shellComponent
62+ Shell {
63+ anchors.fill: parent
64+ hasTouchscreen: true
65+ }
66+ }
67+
5868 Row {
5969 id: contentRow
6070
61− Loader {
62− id: shellLoader
63− active: false
64−
71+ Rectangle {
72+ id: shellRect
73+ color: "black"
6574 width: units.gu(40)
6675 height: units.gu(71)
67−
68− property bool itemDestroyed: false
69− sourceComponent: Component {
70− Shell {
71− hasTouchscreen: true
72− Component.onDestruction: {
73− shellLoader.itemDestroyed = true
74− }
75− }
76− }
7776 }
7877
7978 Rectangle {
8079 color: "white"
8180 width: units.gu(30)
82− height: shellLoader.height
81+ height: shellRect.height
8382
8483 Column {
8584 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
8685 spacing: units.gu(1)
86+ Button {
87+ anchors { left: parent.left; right: parent.right }
88+ text: "Load shell"
89+ onClicked: {
90+ if (root.tryShell === null) {
91+ root.tryShell = shellComponent.createObject(shellRect);
92+ }
93+ }
94+ }
8795 Button {
8896 anchors { left: parent.left; right: parent.right }
8997 text: "Show Greeter"
@@ -122,13 +130,13 @@ Item {
122130 name: "ShellWithPin"
123131 when: windowShown
124132
125− property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
126−
127− function init() {
133+ function createShell() {
134+ var shell = createTemporaryObject(shellComponent, shellRect);
135+ removeTimeConstraintsFromSwipeAreas(shell);
128136 tryCompare(shell, "waitingOnGreeter", false); // will be set when greeter is all ready
129137 var greeter = findChild(shell, "greeter");
130138 sessionSpy.target = greeter;
131− swipeAwayGreeter(true);
139+ swipeAwayGreeter(true, shell);
132140 greeter.failedLoginsDelayAttempts = -1;
133141
134142 var launcher = findChild(shell, "launcher");
@@ -140,44 +148,20 @@ Item {
140148 stage = findChild(shell, "stage");
141149 topLevelSurfaceList = findInvisibleChild(shell, "topLevelSurfaceList");
142150 verify(topLevelSurfaceList);
151+ return shell;
143152 }
144153
145154 function cleanup() {
146− tryCompare(shell, "waitingOnGreeter", false); // make sure greeter didn't leave us in disabled state
147−
148155 topLevelSurfaceList = null;
149−
150− shellLoader.itemDestroyed = false
151−
152− shellLoader.active = false
153−
154− tryCompare(shellLoader, "status", Loader.Null)
155− tryCompare(shellLoader, "item", null)
156− // Loader.status might be Loader.Null and Loader.item might be null but the Loader
157− // item might still be alive. So if we set Loader.active back to true
158− // again right now we will get the very same Shell instance back. So no reload
159− // actually took place. Likely because Loader waits until the next event loop
160− // iteration to do its work. So to ensure the reload, we will wait until the
161− // Shell instance gets destroyed.
162− tryCompare(shellLoader, "itemDestroyed", true)
163−
164− // kill all (fake) running apps
165− killApps()
166−
167− AccountsService.enableLauncherWhileLocked = true
168− AccountsService.enableIndicatorsWhileLocked = true
169− AccountsService.demoEdges = false
170− callManager.foregroundCall = null
156+ killApps();
157+ AccountsService.enableLauncherWhileLocked = true;
158+ AccountsService.enableIndicatorsWhileLocked = true;
159+ AccountsService.demoEdges = false;
160+ callManager.foregroundCall = null;
171161 LightDM.Greeter.authenticate(""); // reset greeter
172−
173− // reload our test subject to get it in a fresh state once again
174− shellLoader.active = true
175−
176− tryCompare(shellLoader, "status", Loader.Ready)
177− removeTimeConstraintsFromSwipeAreas(shellLoader.item)
178162 }
179163
180− function swipeAwayGreeter(waitForCoverPage) {
164+ function swipeAwayGreeter(waitForCoverPage, shell) {
181165 var greeter = findChild(shell, "greeter");
182166 waitForRendering(greeter)
183167 var coverPage = findChild(shell, "coverPage");
@@ -198,7 +182,7 @@ Item {
198182 typeString(pin);
199183 }
200184
201− function showGreeter() {
185+ function showGreeter(shell) {
202186 LightDM.Greeter.showGreeter();
203187 tryCompare(shell, "waitingOnGreeter", false);
204188 var coverPage = findChild(shell, "coverPage");
@@ -206,7 +190,7 @@ Item {
206190 removeTimeConstraintsFromSwipeAreas(shell);
207191 }
208192
209− function confirmLockedApp(app) {
193+ function confirmLockedApp(app, shell) {
210194 var greeter = findChild(shell, "greeter")
211195 tryCompare(greeter, "shown", false)
212196 tryCompare(greeter, "hasLockedApp", true)
@@ -218,13 +202,14 @@ Item {
218202 function test_greeterChangesIndicatorProfile() {
219203 skip("Not supported yet, waiting on design for new settings panel");
220204
205+ var shell = createShell();
221206 var panel = findChild(shell, "panel");
222207 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile + "_greeter");
223208
224209 LightDM.Greeter.hideGreeter();
225210 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile);
226211
227− showGreeter();
212+ showGreeter(shell);
228213 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile + "_greeter");
229214
230215 LightDM.Greeter.hideGreeter();
@@ -232,6 +217,7 @@ Item {
232217 }
233218
234219 function test_login() {
220+ var shell = createShell();
235221 sessionSpy.clear()
236222 tryCompare(sessionSpy, "count", 0)
237223 enterPin("1234")
@@ -239,6 +225,7 @@ Item {
239225 }
240226
241227 function test_disabledEdges() {
228+ var shell = createShell();
242229 var launcher = findChild(shell, "launcher")
243230 tryCompare(launcher, "available", true)
244231 AccountsService.enableLauncherWhileLocked = false
@@ -251,6 +238,7 @@ Item {
251238 }
252239
253240 function test_emergencyCall() {
241+ var shell = createShell();
254242 var greeter = findChild(shell, "greeter")
255243 var panel = findChild(shell, "panel")
256244 var indicators = findChild(shell, "indicators")
@@ -269,7 +257,7 @@ Item {
269257
270258 // Cancel emergency mode, and go back to normal
271259 waitForRendering(greeter)
272− showGreeter()
260+ showGreeter(shell);
273261
274262 tryCompare(greeter, "shown", true)
275263 tryCompare(greeter, "lockedApp", "")
@@ -282,6 +270,7 @@ Item {
282270 }
283271
284272 function test_emergencyCallCrash() {
273+ var shell = createShell();
285274 var dialerSurfaceId = topLevelSurfaceList.nextId;
286275 var greeter = findChild(shell, "greeter");
287276 var emergencyButton = findChild(greeter, "emergencyCallLabel");
@@ -297,6 +286,7 @@ Item {
297286 }
298287
299288 function test_emergencyCallAppLaunch() {
289+ var shell = createShell();
300290 var greeter = findChild(shell, "greeter");
301291 var emergencyButton = findChild(greeter, "emergencyCallLabel");
302292 tap(emergencyButton)
@@ -307,6 +297,7 @@ Item {
307297 }
308298
309299 function test_emergencyCallPausesTutorial() {
300+ var shell = createShell();
310301 var greeter = findChild(shell, "greeter");
311302 var tutorial = findChild(shell, "tutorial");
312303
@@ -314,15 +305,16 @@ Item {
314305 enterPin("1234");
315306 tryCompare(tutorial, "paused", false);
316307
317− showGreeter();
308+ showGreeter(shell);
318309 verify(tutorial.paused);
319310
320− swipeAwayGreeter(true);
311+ swipeAwayGreeter(true, shell);
321312 tap(findChild(greeter, "emergencyCallLabel"));
322313 verify(tutorial.paused);
323314 }
324315
325316 function test_failedLoginsCount() {
317+ var shell = createShell();
326318 AccountsService.failedLogins = 0
327319
328320 enterPin("1111")
@@ -333,6 +325,7 @@ Item {
333325 }
334326
335327 function test_wrongEntries() {
328+ var shell = createShell();
336329 var greeter = findChild(shell, "greeter");
337330 greeter.failedLoginsDelayAttempts = 3;
338331
@@ -357,13 +350,14 @@ Item {
357350 // dialer to a side stage and give access to other apps. So just
358351 // confirm that such an attack doesn't work.
359352
353+ var shell = createShell();
360354 var stage = findChild(shell, "stage")
361355
362356 // We start in phone mode
363357 compare(stage.usageScenario, "phone");
364358
365359 tap(findChild(shell, "emergencyCallLabel"));
366− confirmLockedApp("dialer-app")
360+ confirmLockedApp("dialer-app", shell);
367361
368362 // OK, we're in. Now try (but fail) to switch to tablet mode
369363 shell.usageScenario = "tablet";
@@ -377,8 +371,9 @@ Item {
377371 }
378372
379373 function test_emergencyDialerIncoming() {
374+ var shell = createShell();
380375 callManager.foregroundCall = phoneCall
381− confirmLockedApp("dialer-app")
376+ confirmLockedApp("dialer-app", shell);
382377 }
383378
384379 function test_emergencyDialerActiveCallPanel() {
@@ -388,13 +383,14 @@ Item {
388383 // - Click on active call panel
389384 // - Should be back in emergency mode dialer
390385
386+ var shell = createShell();
391387 var greeter = findChild(shell, "greeter");
392388
393389 tap(findChild(shell, "emergencyCallLabel"));
394− confirmLockedApp("dialer-app");
390+ confirmLockedApp("dialer-app", shell);
395391 callManager.foregroundCall = phoneCall;
396392
397− showGreeter();
393+ showGreeter(shell);
398394 var lockscreen = findChild(shell, "lockscreen");
399395 tryCompare(lockscreen, "shown", true);
400396 tryCompare(greeter, "hasLockedApp", false);
@@ -402,7 +398,7 @@ Item {
402398 // simulate a callHint press, the real thing requires dialer: url support
403399 ApplicationManager.requestFocusApplication("dialer-app");
404400
405− confirmLockedApp("dialer-app");
401+ confirmLockedApp("dialer-app", shell);
406402 }
407403
408404 function test_normalDialerActiveCallPanel() {
@@ -414,6 +410,7 @@ Item {
414410 // - Should be back in normal dialer
415411 // (we've had a bug where we locked screen in this case)
416412
413+ var shell = createShell();
417414 startApplication("gallery-app");
418415
419416 var greeter = findChild(shell, "greeter");
@@ -431,7 +428,6 @@ Item {
431428 tryCompare(ApplicationManager, "focusedApplicationId", "gallery-app");
432429 var callHint = findChild(panel, "callHint");
433430 tryCompare(callHint, "visible", true);
434− wait(10000)
435431
436432 // simulate a callHint press, the real thing requires dialer: url support
437433 ApplicationManager.requestFocusApplication("dialer-app");
@@ -442,7 +438,8 @@ Item {
442438 }
443439
444440 function test_focusRequestedHidesCoverPage() {
445− showGreeter();
441+ var shell = createShell();
442+ showGreeter(shell);
446443
447444 startApplication("gallery-app");
448445
@@ -452,7 +449,7 @@ Item {
452449 tryCompare(coverPage, "showProgress", 0);
453450 tryCompare(greeter, "fullyShown", true);
454451
455− showGreeter();
452+ showGreeter(shell);
456453
457454 // Make sure focusing same app triggers same behavior
458455 ApplicationManager.requestFocusApplication("gallery-app");
@@ -461,6 +458,7 @@ Item {
461458 }
462459
463460 function test_suspend() {
461+ var shell = createShell();
464462 var greeter = findChild(shell, "greeter");
465463 var stage = findChild(shell, "stage")
466464
@@ -475,7 +473,7 @@ Item {
475473 tryCompare(greeter, "fullyShown", true);
476474
477475 // Swipe away greeter to focus app
478− swipeAwayGreeter(true);
476+ swipeAwayGreeter(true, shell);
479477
480478 // We have a lockscreen, make sure we're still suspended
481479 tryCompare(stage, "suspended", true);
@@ -490,14 +488,7 @@ Item {
490488 loaded, they would be able to get into the session before the
491489 lockscreen appeared. Make sure that doesn't happen. */
492490 function test_earlyDisable() {
493− // Kill current shell
494− shellLoader.itemDestroyed = false;
495− shellLoader.active = false;
496− tryCompare(shellLoader, "itemDestroyed", true);
497−
498− // Create new shell
499− shellLoader.active = true;
500− tryCompareFunction(function() {return shell !== null}, true);
491+ var shell = createTemporaryObject(shellComponent, shellRect);
501492
502493 // Confirm that we start disabled
503494 compare(LightDM.Prompts.count, 0);
@@ -513,6 +504,7 @@ Item {
513504 }
514505
515506 function test_bfbOnLockedDevice() {
507+ var shell = createShell();
516508 var launcher = findChild(shell, "launcher");
517509 touchFlick(shell, units.gu(.5), shell.height / 2, units.gu(10), shell.height / 2);
518510
@@ -534,6 +526,7 @@ Item {
534526 appear over the Greeter. This was caused by logic that would normally
535527 cause the Launcher to be shown over the empty Background. */
536528 function test_launcherShowCulledWhenLocked() {
529+ var shell = createShell();
537530 var launcher = findChild(shell, "launcher");
538531
539532 // Ensure the Launcher is sane
@@ -542,9 +535,6 @@ Item {
542535 tap(shell);
543536 tryCompare(launcher, "state", "");
544537
545− console.log("I AM LOGGING NOW");
546− console.log(ApplicationManager.count);
547−
548538 // Start and kill an app to cause the Launcher to be triggered (in error state)
549539 startApplication("gallery-app");
550540 tryCompare(ApplicationManager, "count", 1);
tests/utils/modules/Unity/Test/MouseTouchEmulationCheckbox.qml+1−1
@@ -37,9 +37,9 @@ RowLayout {
3737 activeFocusOnPress: false
3838 }
3939 Label {
40+ Layout.alignment: Qt.AlignVCenter
4041 id: label
4142 text: "Mouse emulates touch"
42− anchors.verticalCenter: parent.verticalCenter
4343 AbstractButton {
4444 anchors.fill: parent
4545 onClicked: checkbox.checked = !checkbox.checked
tests/utils/modules/Unity/Test/StageTestCase.qml+14−18
@@ -42,27 +42,23 @@ UnityTestCase {
4242 Returns the appDelegate of the first surface created by the app with the specified appId
4343 */
4444 function startApplication(appId) {
45− try {
46− var app = ApplicationManager.findApplication(appId);
47− if (app) {
48− for (var i = 0; i < topLevelSurfaceList.count; i++) {
49− if (topLevelSurfaceList.applicationAt(i).appId === appId) {
50− var appRepeater = findChild(stage, "appRepeater");
51− verify(appRepeater);
52− return appRepeater.itemAt(i);
53− }
45+ var app = ApplicationManager.findApplication(appId);
46+ if (app) {
47+ for (var i = 0; i < topLevelSurfaceList.count; i++) {
48+ if (topLevelSurfaceList.applicationAt(i).appId === appId) {
49+ var appRepeater = findChild(stage, "appRepeater");
50+ verify(appRepeater);
51+ return appRepeater.itemAt(i);
5452 }
5553 }
54+ }
5655
57− var surfaceId = topLevelSurfaceList.nextId;
58− app = ApplicationManager.startApplication(appId);
59− verify(app);
60− waitUntilAppWindowIsFullyLoaded(surfaceId);
61− compare(app.surfaceList.count, 1);
56+ var surfaceId = topLevelSurfaceList.nextId;
57+ app = ApplicationManager.startApplication(appId);
58+ verify(app);
59+ waitUntilAppWindowIsFullyLoaded(surfaceId);
60+ compare(app.surfaceList.count, 1);
6261
63− return findChild(stage, "appDelegate_" + surfaceId);
64− } catch(err) {
65− throw new Error("startApplication("+appId+") called from line " + util.callerLine(1) + " failed!");
66− }
62+ return findChild(stage, "appDelegate_" + surfaceId);
6763 }
6864}