Merge lp:~mterry/unity8/usage-mode-fixes into lp:unity8

Proposed by Michael Terry
Status: Merged
Approved by: Michael Zanetti
Approved revision: 2328
Merged at revision: 2329
Proposed branch: lp:~mterry/unity8/usage-mode-fixes
Merge into: lp:unity8
Diff against target: 603 lines (+230/-134)
4 files modified
qml/OrientedShell.qml (+27/-12)
tests/mocks/GSettings.1.0/fake_gsettings.cpp (+130/-75)
tests/mocks/GSettings.1.0/fake_gsettings.h (+41/-25)
tests/qmltests/tst_OrientedShell.qml (+32/-22)
To merge this branch: bzr merge lp:~mterry/unity8/usage-mode-fixes
Reviewer Review Type Date Requested Status
Michael Zanetti (community) Approve
Unity8 CI Bot continuous-integration Needs Fixing
Review via email: mp+290780@code.launchpad.net

Commit message

Make sure that usageMode is set on startup, fixing a problem with the tutorial not noticing that it is running on a desktop.

Description of the change

Make sure that usageMode is set on startup, fixing a problem with the tutorial not noticing that it is running on a desktop.

In the course of this, I made our mock GSettings class act more like the real GSettings class by returning "undefined" values for all properties until it is constructed. Without this, the above fix is impossible to catch. And not doing that may hide more test problems in future.

 * Are there any related MPs required for this MP to build/function as expected? Please list.
 No

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

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

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

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

To post a comment you must log in.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2324
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/920/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/504
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/504
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/504/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1248
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1219
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1219
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1217/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1217/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1217/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1217/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1217/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1217
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1217/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/920/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

I'm wondering if we shouldn't fix GSettings instead... wdyt?

review: Needs Information
Revision history for this message
Michael Terry (mterry) wrote :

It seems like very intentional behavior on gsettings-qt's part, rather than a bug. They wait until componentComplete() to finish initializing. Which is totally valid qml lifecycling right? I figured we were in the wrong for assuming an object would be usable before construction.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

Hmm... Dunno... it's certainly the only QML component I know that behaves like this... It's perhaps "valid" given that the changed signal is emitted when it updates, but it certainly doesn't help with improving application startup times etc, given everyone constructs things in an unknown state and later changes it.

Revision history for this message
Michael Terry (mterry) wrote :

Well... if a Qml object isn't constructed, how can you expect it to give out good values? Isn't that the definition of constructed? That it's ready to be used by outside components?

I'm assuming in this case, our problem is exacerbated by the definition of the GSettings object in Shell.qml:

property var unity8Settings: GSettings { schema.id: "com.canonical.Unity8" }

I assume if that were an actual top-level GSettings object, the timing would be more like we expect.

And in fact, that odd construction is just to help cheaply mock GSettings values (yet another bad way to mock GSettings when we have a lovely mock class already present).

Let me drop this weird usage since we don't need it anymore. That should also fix the original problem a second way.

lp:~mterry/unity8/usage-mode-fixes updated
2325. By Michael Terry

Drop mock property points for cleanliness

Revision history for this message
Michael Terry (mterry) wrote :

OK, I got rid of the override-able gsettings properties used as a quick way to mock gsettings.

Didn't fix the timing issue that caused the original bug though. So I left the rest of the MP as is.

lp:~mterry/unity8/usage-mode-fixes updated
2326. By Michael Terry

Add a quick sanity check to new test

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2325
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/938/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1276
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1247
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1247
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1245
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1245/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1245/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1245
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1245/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1245
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1245/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1245
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1245/artifact/output/*zip*/output.zip
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1245/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/938/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2326
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/939/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/524
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/524
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/524/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1278
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1249
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1249
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1247/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1247
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1247/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/939/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

Looks good to me now. I've tested it and it works.

I've left one inline comment which isn't really an issue of this branch, but needs to be fixed too and fits in here quite well.

review: Needs Fixing
lp:~mterry/unity8/usage-mode-fixes updated
2327. By Michael Terry

Fix long-screen-edge check, per mzanetti

Revision history for this message
Michael Terry (mterry) wrote :

I fixed the size-of-screen check, like you asked. Should be good now.

Revision history for this message
Michael Terry (mterry) wrote :

Uh... let me run tests actually to make sure they still work with that change... Silly me.

lp:~mterry/unity8/usage-mode-fixes updated
2328. By Michael Terry

Fix tests

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2328
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/975/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/548
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/548
    FAILURE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/548/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1317
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1288
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1288
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1286/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1286/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1286/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1286/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1286/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1286
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1286/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/975/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Terry (mterry) wrote :

OK, qml tests passed, please re-review.

Revision history for this message
Michael Zanetti (mzanetti) wrote :

Tested, works.

Tags clean

CI tests ok.

code looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/OrientedShell.qml'
2--- qml/OrientedShell.qml 2016-03-11 18:20:46 +0000
3+++ qml/OrientedShell.qml 2016-04-12 13:59:10 +0000
4@@ -57,9 +57,17 @@
5 invertedPortrait: deviceConfiguration.invertedPortraitOrientation
6 }
7 }
8- // to be overwritten by tests
9- property var unity8Settings: GSettings { schema.id: "com.canonical.Unity8" }
10- property var oskSettings: GSettings { schema.id: "com.canonical.keyboard.maliit" }
11+
12+ GSettings {
13+ id: unity8Settings
14+ schema.id: "com.canonical.Unity8"
15+ }
16+
17+ GSettings {
18+ id: oskSettings
19+ objectName: "oskSettings"
20+ schema.id: "com.canonical.keyboard.maliit"
21+ }
22
23 property int physicalOrientation: Screen.orientation
24 property bool orientationLocked: OrientationLock.enabled
25@@ -90,22 +98,26 @@
26 }
27
28 readonly property int pointerInputDevices: miceModel.count + touchPadModel.count
29- onPointerInputDevicesChanged: {
30- console.log("Pointer input devices changed:", pointerInputDevices, "current mode:", root.unity8Settings.usageMode, "old device count", miceModel.oldCount + touchPadModel.oldCount)
31- if (root.unity8Settings.usageMode === "Windowed") {
32+ onPointerInputDevicesChanged: calculateUsageMode()
33+
34+ function calculateUsageMode() {
35+ if (unity8Settings.usageMode === undefined)
36+ return; // gsettings isn't loaded yet, we'll try again in Component.onCompleted
37+
38+ console.log("Pointer input devices changed:", pointerInputDevices, "current mode:", unity8Settings.usageMode, "old device count", miceModel.oldCount + touchPadModel.oldCount)
39+ if (unity8Settings.usageMode === "Windowed") {
40 if (pointerInputDevices === 0) {
41 // All pointer devices have been unplugged. Move to staged.
42- root.unity8Settings.usageMode = "Staged";
43+ unity8Settings.usageMode = "Staged";
44 }
45 } else {
46- var longEdgeWidth = Math.max(root.width, root.height)
47- if (longEdgeWidth > units.gu(90)){
48+ if (Math.min(root.width, root.height) > units.gu(60)) {
49 if (pointerInputDevices > 0 && pointerInputDevices > miceModel.oldCount + touchPadModel.oldCount) {
50- root.unity8Settings.usageMode = "Windowed";
51+ unity8Settings.usageMode = "Windowed";
52 }
53 } else {
54 // Make sure we initialize to something sane
55- root.unity8Settings.usageMode = "Staged";
56+ unity8Settings.usageMode = "Staged";
57 }
58 }
59 miceModel.oldCount = miceModel.count;
60@@ -154,6 +166,9 @@
61 if (orientationLocked) {
62 orientation = orientationLock.savedOrientation;
63 }
64+
65+ calculateUsageMode();
66+
67 // We need to manually update this on startup as the binding
68 // below doesn't seem to have any effect at that stage
69 oskSettings.disableHeight = !shell.oskEnabled || shell.usageScenario == "desktop"
70@@ -248,7 +263,7 @@
71 forceOSKEnabled
72
73 usageScenario: {
74- if (root.unity8Settings.usageMode === "Windowed") {
75+ if (unity8Settings.usageMode === "Windowed") {
76 return "desktop";
77 } else {
78 if (deviceConfiguration.category === "phone") {
79
80=== modified file 'tests/mocks/GSettings.1.0/fake_gsettings.cpp'
81--- tests/mocks/GSettings.1.0/fake_gsettings.cpp 2016-01-14 15:44:57 +0000
82+++ tests/mocks/GSettings.1.0/fake_gsettings.cpp 2016-04-12 13:59:10 +0000
83@@ -21,7 +21,8 @@
84 GSettingsControllerQml* GSettingsControllerQml::s_controllerInstance = 0;
85
86 GSettingsControllerQml::GSettingsControllerQml()
87- : m_usageMode("Staged")
88+ : m_disableHeight(false)
89+ , m_usageMode("Staged")
90 , m_autohideLauncher(false)
91 , m_launcherWidth(8)
92 {
93@@ -38,6 +39,19 @@
94 return s_controllerInstance;
95 }
96
97+bool GSettingsControllerQml::disableHeight() const
98+{
99+ return m_disableHeight;
100+}
101+
102+void GSettingsControllerQml::setDisableHeight(bool val)
103+{
104+ if (val != m_disableHeight) {
105+ m_disableHeight = val;
106+ Q_EMIT disableHeightChanged();
107+ }
108+}
109+
110 QString GSettingsControllerQml::pictureUri() const
111 {
112 return m_pictureUri;
113@@ -146,9 +160,26 @@
114 }
115
116 GSettingsQml::GSettingsQml(QObject *parent)
117- : QObject(parent)
118+ : QObject(parent),
119+ m_valid(false)
120 {
121 m_schema = new GSettingsSchemaQml(this);
122+}
123+
124+void GSettingsQml::classBegin()
125+{
126+}
127+
128+void GSettingsQml::componentComplete()
129+{
130+ // Emulate what the real GSettings module does, and only return undefined
131+ // values until we are completed loading.
132+ m_valid = true;
133+
134+ // FIXME: We should make this dynamic, instead of hard-coding all possible
135+ // properties in one object. We should create properties based on the schema.
136+ connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::disableHeightChanged,
137+ this, &GSettingsQml::disableHeightChanged);
138 connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::pictureUriChanged,
139 this, &GSettingsQml::pictureUriChanged);
140 connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::usageModeChanged,
141@@ -161,104 +192,128 @@
142 this, &GSettingsQml::autohideLauncherChanged);
143 connect(GSettingsControllerQml::instance(), &GSettingsControllerQml::launcherWidthChanged,
144 this, &GSettingsQml::launcherWidthChanged);
145+
146+ Q_EMIT disableHeightChanged();
147+ Q_EMIT pictureUriChanged();
148+ Q_EMIT usageModeChanged();
149+ Q_EMIT lockedOutTimeChanged();
150+ Q_EMIT lifecycleExemptAppidsChanged();
151+ Q_EMIT autohideLauncherChanged();
152+ Q_EMIT launcherWidthChanged();
153 }
154
155 GSettingsSchemaQml * GSettingsQml::schema() const {
156 return m_schema;
157 }
158
159-QString GSettingsQml::pictureUri() const
160-{
161- if (m_schema->id() == "org.gnome.desktop.background") {
162+QVariant GSettingsQml::disableHeight() const
163+{
164+ if (m_valid && m_schema->id() == "com.canonical.keyboard.maliit") {
165+ return GSettingsControllerQml::instance()->disableHeight();
166+ } else {
167+ return QVariant();
168+ }
169+}
170+
171+void GSettingsQml::setDisableHeight(const QVariant &val)
172+{
173+ if (m_valid && m_schema->id() == "com.canonical.keyboard.maliit") {
174+ GSettingsControllerQml::instance()->setDisableHeight(val.toBool());
175+ }
176+}
177+
178+QVariant GSettingsQml::pictureUri() const
179+{
180+ if (m_valid && m_schema->id() == "org.gnome.desktop.background") {
181 return GSettingsControllerQml::instance()->pictureUri();
182 } else {
183- return "";
184- }
185-}
186-
187-void GSettingsQml::setPictureUri(const QString &str)
188-{
189- if (m_schema->id() == "org.gnome.desktop.background") {
190- GSettingsControllerQml::instance()->setPictureUri(str);
191- }
192-}
193-
194-QString GSettingsQml::usageMode() const
195-{
196- if (m_schema->id() == "com.canonical.Unity8") {
197+ return QVariant();
198+ }
199+}
200+
201+void GSettingsQml::setPictureUri(const QVariant &str)
202+{
203+ if (m_valid && m_schema->id() == "org.gnome.desktop.background") {
204+ GSettingsControllerQml::instance()->setPictureUri(str.toString());
205+ }
206+}
207+
208+QVariant GSettingsQml::usageMode() const
209+{
210+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
211 return GSettingsControllerQml::instance()->usageMode();
212 } else {
213- return "";
214- }
215-}
216-
217-void GSettingsQml::setUsageMode(const QString &usageMode)
218-{
219- if (m_schema->id() == "com.canonical.Unity8") {
220- GSettingsControllerQml::instance()->setUsageMode(usageMode);
221- }
222-}
223-
224-qint64 GSettingsQml::lockedOutTime() const
225-{
226- if (m_schema->id() == "com.canonical.Unity8.Greeter") {
227+ return QVariant();
228+ }
229+}
230+
231+void GSettingsQml::setUsageMode(const QVariant &usageMode)
232+{
233+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
234+ GSettingsControllerQml::instance()->setUsageMode(usageMode.toString());
235+ }
236+}
237+
238+QVariant GSettingsQml::lockedOutTime() const
239+{
240+ if (m_valid && m_schema->id() == "com.canonical.Unity8.Greeter") {
241 return GSettingsControllerQml::instance()->lockedOutTime();
242 } else {
243- return 0;
244- }
245-}
246-
247-void GSettingsQml::setLockedOutTime(qint64 timestamp)
248-{
249- if (m_schema->id() == "com.canonical.Unity8.Greeter") {
250- GSettingsControllerQml::instance()->setLockedOutTime(timestamp);
251- }
252-}
253-
254-QStringList GSettingsQml::lifecycleExemptAppids() const
255-{
256- if (m_schema->id() == "com.canonical.qtmir") {
257+ return QVariant();
258+ }
259+}
260+
261+void GSettingsQml::setLockedOutTime(const QVariant &timestamp)
262+{
263+ if (m_valid && m_schema->id() == "com.canonical.Unity8.Greeter") {
264+ GSettingsControllerQml::instance()->setLockedOutTime(timestamp.value<qint64>());
265+ }
266+}
267+
268+QVariant GSettingsQml::lifecycleExemptAppids() const
269+{
270+ if (m_valid && m_schema->id() == "com.canonical.qtmir") {
271 return GSettingsControllerQml::instance()->lifecycleExemptAppids();
272 } else {
273- return QStringList();
274+ return QVariant();
275 }
276 }
277
278-bool GSettingsQml::autohideLauncher() const
279+QVariant GSettingsQml::autohideLauncher() const
280 {
281- if (m_schema->id() == "com.canonical.Unity8") {
282+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
283 return GSettingsControllerQml::instance()->autohideLauncher();
284 } else {
285- return false;
286+ return QVariant();
287 }
288 }
289
290-int GSettingsQml::launcherWidth() const
291+QVariant GSettingsQml::launcherWidth() const
292 {
293- if (m_schema->id() == "com.canonical.Unity8") {
294+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
295 return GSettingsControllerQml::instance()->launcherWidth();
296 } else {
297- return false;
298- }
299-}
300-
301-void GSettingsQml::setLifecycleExemptAppids(const QStringList &appIds)
302-{
303- if (m_schema->id() == "com.canonical.qtmir") {
304- GSettingsControllerQml::instance()->setLifecycleExemptAppids(appIds);
305- }
306-}
307-
308-void GSettingsQml::setAutohideLauncher(bool autohideLauncher)
309-{
310- if (m_schema->id() == "com.canonical.Unity8") {
311- GSettingsControllerQml::instance()->setAutohideLauncher(autohideLauncher);
312- }
313-}
314-
315-void GSettingsQml::setLauncherWidth(int launcherWidth)
316-{
317- if (m_schema->id() == "com.canonical.Unity8") {
318- GSettingsControllerQml::instance()->setLauncherWidth(launcherWidth);
319+ return QVariant();
320+ }
321+}
322+
323+void GSettingsQml::setLifecycleExemptAppids(const QVariant &appIds)
324+{
325+ if (m_valid && m_schema->id() == "com.canonical.qtmir") {
326+ GSettingsControllerQml::instance()->setLifecycleExemptAppids(appIds.toStringList());
327+ }
328+}
329+
330+void GSettingsQml::setAutohideLauncher(const QVariant &autohideLauncher)
331+{
332+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
333+ GSettingsControllerQml::instance()->setAutohideLauncher(autohideLauncher.toBool());
334+ }
335+}
336+
337+void GSettingsQml::setLauncherWidth(const QVariant &launcherWidth)
338+{
339+ if (m_valid && m_schema->id() == "com.canonical.Unity8") {
340+ GSettingsControllerQml::instance()->setLauncherWidth(launcherWidth.toInt());
341 }
342 }
343
344=== modified file 'tests/mocks/GSettings.1.0/fake_gsettings.h'
345--- tests/mocks/GSettings.1.0/fake_gsettings.h 2016-01-08 11:28:53 +0000
346+++ tests/mocks/GSettings.1.0/fake_gsettings.h 2016-04-12 13:59:10 +0000
347@@ -19,7 +19,9 @@
348
349 #include <QList>
350 #include <QObject>
351+#include <QQmlParserStatus>
352 #include <QStringList>
353+#include <QVariant>
354
355 class GSettingsSchemaQml: public QObject
356 {
357@@ -41,47 +43,56 @@
358 QByteArray m_path;
359 };
360
361-class GSettingsQml: public QObject
362+class GSettingsQml: public QObject, public QQmlParserStatus
363 {
364 Q_OBJECT
365+ Q_INTERFACES(QQmlParserStatus)
366
367 Q_PROPERTY(GSettingsSchemaQml* schema READ schema NOTIFY schemaChanged)
368- Q_PROPERTY(QString pictureUri READ pictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
369- Q_PROPERTY(QString usageMode READ usageMode WRITE setUsageMode NOTIFY usageModeChanged)
370- Q_PROPERTY(qint64 lockedOutTime READ lockedOutTime WRITE setLockedOutTime NOTIFY lockedOutTimeChanged)
371- Q_PROPERTY(QStringList lifecycleExemptAppids READ lifecycleExemptAppids WRITE setLifecycleExemptAppids NOTIFY lifecycleExemptAppidsChanged)
372- Q_PROPERTY(bool autohideLauncher READ autohideLauncher WRITE setAutohideLauncher NOTIFY autohideLauncherChanged)
373- Q_PROPERTY(int launcherWidth READ launcherWidth WRITE setLauncherWidth NOTIFY launcherWidthChanged)
374+ Q_PROPERTY(QVariant disableHeight READ disableHeight WRITE setDisableHeight NOTIFY disableHeightChanged)
375+ Q_PROPERTY(QVariant pictureUri READ pictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
376+ Q_PROPERTY(QVariant usageMode READ usageMode WRITE setUsageMode NOTIFY usageModeChanged)
377+ Q_PROPERTY(QVariant lockedOutTime READ lockedOutTime WRITE setLockedOutTime NOTIFY lockedOutTimeChanged)
378+ Q_PROPERTY(QVariant lifecycleExemptAppids READ lifecycleExemptAppids WRITE setLifecycleExemptAppids NOTIFY lifecycleExemptAppidsChanged)
379+ Q_PROPERTY(QVariant autohideLauncher READ autohideLauncher WRITE setAutohideLauncher NOTIFY autohideLauncherChanged)
380+ Q_PROPERTY(QVariant launcherWidth READ launcherWidth WRITE setLauncherWidth NOTIFY launcherWidthChanged)
381
382 public:
383 GSettingsQml(QObject *parent = nullptr);
384
385+ void classBegin();
386+ void componentComplete();
387+
388 GSettingsSchemaQml * schema() const;
389- QString pictureUri() const;
390- QString usageMode() const;
391- qint64 lockedOutTime() const;
392- QStringList lifecycleExemptAppids() const;
393- bool autohideLauncher() const;
394- int launcherWidth() const;
395+ QVariant disableHeight() const;
396+ QVariant pictureUri() const;
397+ QVariant usageMode() const;
398+ QVariant lockedOutTime() const;
399+ QVariant lifecycleExemptAppids() const;
400+ QVariant autohideLauncher() const;
401+ QVariant launcherWidth() const;
402
403- void setPictureUri(const QString &str);
404- void setUsageMode(const QString &usageMode);
405- void setLockedOutTime(qint64 timestamp);
406- void setLifecycleExemptAppids(const QStringList &appIds);
407- void setAutohideLauncher(bool autohideLauncher);
408- void setLauncherWidth(int launcherWidth);
409+ void setDisableHeight(const QVariant &val);
410+ void setPictureUri(const QVariant &str);
411+ void setUsageMode(const QVariant &usageMode);
412+ void setLockedOutTime(const QVariant &timestamp);
413+ void setLifecycleExemptAppids(const QVariant &appIds);
414+ void setAutohideLauncher(const QVariant &autohideLauncher);
415+ void setLauncherWidth(const QVariant &launcherWidth);
416
417 Q_SIGNALS:
418+ void disableHeightChanged();
419 void schemaChanged();
420- void pictureUriChanged(const QString&);
421- void usageModeChanged(const QString&);
422- void lockedOutTimeChanged(qint64);
423- void lifecycleExemptAppidsChanged(const QStringList &);
424- void autohideLauncherChanged(bool);
425- void launcherWidthChanged(int launcherWidth);
426+ void pictureUriChanged();
427+ void usageModeChanged();
428+ void lockedOutTimeChanged();
429+ void lifecycleExemptAppidsChanged();
430+ void autohideLauncherChanged();
431+ void launcherWidthChanged();
432
433 private:
434 GSettingsSchemaQml* m_schema;
435+ bool m_valid;
436
437 friend class GSettingsSchemaQml;
438 };
439@@ -94,6 +105,9 @@
440 static GSettingsControllerQml* instance();
441 ~GSettingsControllerQml();
442
443+ bool disableHeight() const;
444+ Q_INVOKABLE void setDisableHeight(bool val);
445+
446 QString pictureUri() const;
447 Q_INVOKABLE void setPictureUri(const QString &str);
448
449@@ -113,6 +127,7 @@
450 Q_INVOKABLE void setLauncherWidth(int launcherWidth);
451
452 Q_SIGNALS:
453+ void disableHeightChanged();
454 void pictureUriChanged(const QString&);
455 void usageModeChanged(const QString&);
456 void lockedOutTimeChanged(qint64 timestamp);
457@@ -123,6 +138,7 @@
458 private:
459 GSettingsControllerQml();
460
461+ bool m_disableHeight;
462 QString m_pictureUri;
463 QString m_usageMode;
464 qint64 m_lockedOutTime;
465
466=== modified file 'tests/qmltests/tst_OrientedShell.qml'
467--- tests/qmltests/tst_OrientedShell.qml 2016-03-23 09:52:49 +0000
468+++ tests/qmltests/tst_OrientedShell.qml 2016-04-12 13:59:10 +0000
469@@ -17,6 +17,7 @@
470 import QtQuick 2.4
471 import QtQuick.Layouts 1.1
472 import QtTest 1.0
473+import GSettings 1.0
474 import Ubuntu.Components 1.3
475 import Ubuntu.Components.ListItems 1.3 as ListItem
476 import Unity.Application 0.1
477@@ -44,18 +45,17 @@
478 property int savedOrientation
479 }
480
481- QtObject {
482- id: mockUnity8Settings
483- property string usageMode: usageModeSelector.model[usageModeSelector.selectedIndex]
484+ GSettings {
485+ id: unity8Settings
486+ schema.id: "com.canonical.Unity8"
487 onUsageModeChanged: {
488 usageModeSelector.selectedIndex = usageModeSelector.model.indexOf(usageMode)
489 }
490 }
491
492- QtObject{
493- id: mockOskSettings
494- property bool stayHidden: false
495- property bool disableHeight: false
496+ GSettings {
497+ id: oskSettings
498+ schema.id: "com.canonical.keyboard.maliit"
499 }
500
501 InputDeviceModel {
502@@ -100,7 +100,7 @@
503 PropertyChanges {
504 target: orientedShellLoader
505 width: units.gu(160)
506- height: units.gu(100)
507+ height: units.gu(60)
508 }
509 PropertyChanges {
510 target: root
511@@ -115,7 +115,7 @@
512 name: "flo"
513 PropertyChanges {
514 target: orientedShellLoader
515- width: units.gu(62)
516+ width: units.gu(60)
517 height: units.gu(100)
518 }
519 PropertyChanges {
520@@ -132,7 +132,7 @@
521 PropertyChanges {
522 target: orientedShellLoader
523 width: units.gu(100)
524- height: units.gu(56)
525+ height: units.gu(65)
526 }
527 PropertyChanges {
528 target: root
529@@ -157,8 +157,6 @@
530 sourceComponent: Component {
531 OrientedShell {
532 anchors.fill: parent
533- unity8Settings: mockUnity8Settings
534- oskSettings: mockOskSettings
535 physicalOrientation: root.physicalOrientation0
536 orientationLocked: orientationLockedCheckBox.checked
537 orientationLock: mockOrientationLock
538@@ -311,7 +309,7 @@
539 function selectWindowed() {selectedIndex = 1;}
540 function selectAutomatic() {selectedIndex = 2;}
541 onSelectedIndexChanged: {
542- mockUnity8Settings.usageMode = usageModeSelector.model[usageModeSelector.selectedIndex]
543+ GSettingsController.setUsageMode(usageModeSelector.model[usageModeSelector.selectedIndex]);
544 }
545 }
546 MouseTouchEmulationCheckbox {
547@@ -472,6 +470,13 @@
548 // kill all (fake) running apps
549 killApps();
550
551+ while (miceModel.count > 0)
552+ MockInputDeviceBackend.removeDevice("/mouse" + (miceModel.count - 1));
553+ while (touchpadModel.count > 0)
554+ MockInputDeviceBackend.removeDevice("/touchpad" + (touchpadModel.count - 1));
555+ while (keyboardsModel.count > 0)
556+ MockInputDeviceBackend.removeDevice("/kbd" + (keyboardsModel.count - 1))
557+
558 spreadRepeaterConnections.target = null;
559 spreadRepeaterConnections.itemAddedCallback = null;
560 signalSpy.target = null;
561@@ -1081,7 +1086,7 @@
562
563 tryCompare(shell, "usageScenario", "phone");
564 tryCompare(inputMethod, "enabled", true);
565- tryCompare(mockOskSettings, "disableHeight", false);
566+ tryCompare(oskSettings, "disableHeight", false);
567
568 if (data.kbd) {
569 MockInputDeviceBackend.addMockDevice("/kbd0", InputInfo.Keyboard);
570@@ -1092,14 +1097,7 @@
571
572 tryCompare(shell, "usageScenario", data.expectedMode);
573 tryCompare(inputMethod, "enabled", data.oskExpected);
574- tryCompare(mockOskSettings, "disableHeight", data.expectedMode == "desktop" || data.kbd);
575-
576- if (data.kbd) {
577- MockInputDeviceBackend.removeDevice("/kbd0");
578- }
579- if (data.mouse) {
580- MockInputDeviceBackend.removeDevice("/mouse0");
581- }
582+ tryCompare(oskSettings, "disableHeight", data.expectedMode == "desktop" || data.kbd);
583
584 // Restore width
585 orientedShellLoader.width = oldWidth;
586@@ -1140,6 +1138,18 @@
587 orientedShellLoader.width = oldWidth;
588 }
589
590+ function test_setsUsageModeOnStartup() {
591+ // Prepare inconsistent beginning (mouse & staged mode)
592+ MockInputDeviceBackend.addMockDevice("/mouse0", InputInfo.Mouse);
593+ usageModeSelector.selectStaged();
594+ compare(unity8Settings.usageMode, "Staged");
595+
596+ // Load shell, and have it pick desktop
597+ loadShell("desktop");
598+ compare(shell.usageScenario, "desktop");
599+ compare(unity8Settings.usageMode, "Windowed");
600+ }
601+
602 function test_overrideWindowed() {
603 loadShell("mako")
604

Subscribers

People subscribed via source and target branches