Merge lp:~unity-team/unity8/tutorial-redesign into lp:unity8

Proposed by Michael Terry
Status: Superseded
Proposed branch: lp:~unity-team/unity8/tutorial-redesign
Merge into: lp:unity8
Prerequisite: lp:~unity-team/unity8/side-stage-redesign
Diff against target: 5045 lines (+1824/-1529)
66 files modified
plugins/AccountsService/AccountsService.cpp (+16/-0)
plugins/AccountsService/AccountsService.h (+7/-0)
plugins/AccountsService/AccountsService.qmltypes (+5/-0)
plugins/AccountsService/com.canonical.unity.AccountsService.xml (+5/-0)
plugins/ScreenGrabber/screengrabber.cpp (+0/-2)
plugins/Ubuntu/Gestures/DirectionalDragArea.cpp (+40/-5)
plugins/Ubuntu/Gestures/DirectionalDragArea.h (+8/-0)
plugins/Ubuntu/Gestures/DirectionalDragArea_p.h (+2/-0)
plugins/Utils/CMakeLists.txt (+1/-1)
plugins/Utils/Utils.qmltypes (+2/-2)
plugins/Utils/plugin.cpp (+2/-2)
plugins/Utils/windowinputfilter.cpp (+14/-16)
plugins/Utils/windowinputfilter.h (+11/-11)
qml/Components/InputMethod.qml (+4/-1)
qml/Greeter/Greeter.qml (+10/-6)
qml/Launcher/Launcher.qml (+2/-3)
qml/Panel/IndicatorsMenu.qml (+0/-2)
qml/Shell.qml (+32/-46)
qml/Stages/AbstractStage.qml (+3/-0)
qml/Stages/ApplicationWindow.qml (+0/-2)
qml/Stages/DesktopStage.qml (+61/-9)
qml/Stages/PhoneStage.qml (+12/-6)
qml/Stages/StagedFullscreenPolicy.qml (+58/-0)
qml/Stages/TabletStage.qml (+18/-5)
qml/Stages/WindowResizeArea.qml (+1/-1)
qml/Stages/WindowedFullscreenPolicy.qml (+41/-0)
qml/Tutorial/Arrow.qml (+0/-56)
qml/Tutorial/InactivityTimer.qml (+62/-0)
qml/Tutorial/Slider.qml (+0/-123)
qml/Tutorial/Tick.qml (+0/-29)
qml/Tutorial/Tutorial.qml (+43/-18)
qml/Tutorial/TutorialBottom.qml (+0/-104)
qml/Tutorial/TutorialBottomFinish.qml (+0/-41)
qml/Tutorial/TutorialContent.qml (+250/-80)
qml/Tutorial/TutorialLeft.qml (+28/-75)
qml/Tutorial/TutorialLeftFinish.qml (+0/-41)
qml/Tutorial/TutorialLeftLong.qml (+54/-0)
qml/Tutorial/TutorialPage.qml (+66/-190)
qml/Tutorial/TutorialRight.qml (+0/-223)
qml/Tutorial/TutorialTop.qml (+61/-0)
qml/Tutorial/graphics/arrow.svg (+19/-0)
tests/autopilot/unity8/shell/emulators.py (+0/-2)
tests/autopilot/unity8/shell/tests/test_tutorial.py (+0/-57)
tests/autopilot/unity8/tutorial.py (+0/-73)
tests/mocks/AccountsService/AccountsService.cpp (+20/-0)
tests/mocks/AccountsService/AccountsService.h (+10/-0)
tests/mocks/AccountsService/AccountsService.qmltypes (+5/-0)
tests/mocks/Unity/Application/ApplicationInfo.cpp (+21/-3)
tests/mocks/Unity/Application/ApplicationInfo.h (+6/-2)
tests/mocks/Unity/Application/ApplicationManager.cpp (+6/-4)
tests/mocks/Unity/Application/MirSurface.cpp (+16/-0)
tests/mocks/Unity/Application/MirSurface.h (+5/-3)
tests/mocks/Unity/Application/MirSurfaceItem.cpp (+9/-0)
tests/mocks/Unity/Application/MirSurfaceItem.h (+1/-0)
tests/mocks/Unity/Application/Session.cpp (+26/-1)
tests/mocks/Unity/Application/Session.h (+7/-0)
tests/mocks/Utils/CMakeLists.txt (+1/-1)
tests/mocks/Utils/Utils.qmltypes (+2/-2)
tests/mocks/Utils/plugin.cpp (+2/-2)
tests/plugins/AccountsService/PropertiesServer.cpp (+1/-0)
tests/plugins/AccountsService/client.cpp (+37/-0)
tests/qmltests/Components/tst_PhysicalKeysMapper.qml (+3/-3)
tests/qmltests/Greeter/tst_Greeter.qml (+7/-1)
tests/qmltests/Tutorial/tst_Tutorial.qml (+636/-245)
tests/qmltests/tst_Shell.qml (+65/-8)
tests/qmltests/tst_ShellWithPin.qml (+0/-22)
To merge this branch: bzr merge lp:~unity-team/unity8/tutorial-redesign
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing
Albert Astals Cid (community) Abstain
Michael Zanetti Pending
PS Jenkins bot continuous-integration Pending
Review via email: mp+288839@code.launchpad.net

This proposal supersedes a proposal from 2016-03-10.

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

Commit message

Redesign the first-boot edge tutorial

Description of the change

Based on new design specs [1], this is whole new tutorial code.

Some of the interesting things going on here:

- New DDA feature "monitorOnly" which lets input events "fall through" (i.e. it doesn't own them) but continues to monitor them. This is how we implement the bottom edge tutorial fading out without having to communicate with the app.

- New AccountsService key to keep track of which particular edges are done, now that they are presented separately. We still use the old key for overall "done" status.

- Renamed WindowKeysFilter to WindowInputFilter. I needed a way to keep track of input inactivity. And since WindowKeysFilter was already injecting itself into the event stream and already kept track of timestamps for us (which usually isn't exposed to Qml), I just modified it a bit. I felt like the new scope should be indicated in the name, so I renamed it.

- I took out some old hacks only needed for the old tutorial.

[1] https://docs.google.com/document/d/1pZ-Ro--2eaRzjZKNRoYAeDvQHMkCuyvVuPFWFQfPW4s/edit

== Checklist ==

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

 Yes. A new phablet-tools branch for your desktop [2] and a new upload of dbus-property-service (not in a VCS). Both are in silo 33.

 [2] https://code.launchpad.net/~mterry/phablet-tools/tutorial-redesign/+merge/277764

 * 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?
 Yes. Patricia is on board with this MP. She has another screen coming (long swipe on left), but I'll do that as a separate MP.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

<dandrader> mterry, DDA changes in lp:~mterry/unity8/tutorial-redesign look fine
<mterry> dandrader, awesome, thanks
 will quote you in the MP :)
<dandrader> mterry, only unsure about the property name. Because it will work all the same, only difference is that it won't claim ownership over the touch point once it recognizes it's performing a gesture
<mterry> dandrader, yeah. I'm happy to rename it. Got something you like better?
<dandrader> mterry, no :)

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

OK, I'm opening this up to review, although the final design review isn't done yet and I need to add a couple more qmltests. But I'd like to get the review train started on its way.

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

OK, added more tests and cleaned up existing ones. Hopefully this is "done-ish" from a technical POV and only design-related changes will happen now (like changes to strings or alignment).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1977
http://jenkins.qa.ubuntu.com/job/unity8-ci/6737/
Executed test runs:
    ABORTED: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5244/console
    ABORTED: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/152/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1450
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/152
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1344
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1345
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/151
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/151
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4164/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5264
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5264/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/33/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/152
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/152/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6737/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1978
http://jenkins.qa.ubuntu.com/job/unity8-ci/6739/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5250
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/154/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1452
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/154/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1346
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1347
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/153
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/153
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4168
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5270
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5270/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25246
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/34/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/154
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/154/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25244

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6739/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Hmm... I've just flashed a device and enabled the edges-intro with phablet-config. I could see the intro for left, top and bottom edges, however, still waiting for the right edge one to appear.

====

As you renamed WindowKeyFilter, please update this comment too

qml/Shell.qml: // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter

===

- readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0

Given that it's not obvious what the dragProgress is used for, please add a comment in the stages code to indicate it. otherwise it's likely to be removed at some point because noone knows what it does.

===

+ ////

Is there a purpose to this? :)

===
+ sourceSize.height: 1080
+ sourceSize.width: 1916

erm... can you explain the values? Looks wrong to me

review: Needs Fixing
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Notes for myself:

* test if CPU usage drops if screen locks during animation
* test what happens if plugging external screen while in tutorial

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal
Download full text (3.2 KiB)

OK, I've made some changes. One, I added some more space between tutorial text lines, per design request.

Second, also per design request, I've added unique helper text on the bottom edge tutorial for each supported app. This also means that we show the tutorial for each app rather than once for any of them. Since this meant that the tutorial might not formally "finish" for quite some time, I've optimized the rest of the tutorial to use Loaders. So that we're not loading three unused background images a week after the user unboxes their phone.

As for your comments:

> Hmm... I've just flashed a device and enabled the edges-intro
> with phablet-config. I could see the intro for left, top and
> bottom edges, however, still waiting for the right edge one to appear.

As discussed on IRC, we're guessing this was user error. Unless you've seen it again?

====

> As you renamed WindowKeyFilter, please update this comment too
>
> qml/Shell.qml: // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter

Done.

===

> - readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
> + dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0

> Given that it's not obvious what the dragProgress is used for,
> please add a comment in the stages code to indicate it. otherwise
> it's likely to be removed at some point because noone knows what it does.

Done.

===

> + ////
>
> Is there a purpose to this? :)

Ah, that's just a little visual separator I use between the public interface part of the object and the implementation parts. Qml doesn't use headers, and while we seem to use the placement of the QtObject component to separate the portions of code, sometimes an object doesn't warrant a QtObject, so it isn't a universal distinguisher. Plus, I like the extra visual space.

I can take it out if it will be as confusing to you as others. I know Cimi doesn't like that I do that.

===

> + sourceSize.height: 1080
> + sourceSize.width: 1916
>
> erm... can you explain the values? Looks wrong to me

Duh, I swapped height and width. Fixed.

===

> * test if CPU usage drops if screen locks during animation

Please do, but note that there isn't any animation anymore. So I expect no CPU difference.

===

> * test what happens if plugging external screen while in tutorial

Ah yes. Here's what I expect the code to do:

- Any visible tutorials that aren't marked for desktop use will fade out.
- The right edge tutorial will appear (or update itself) with desktop-specific text when you have enough apps open.
- If you finish the right edge tutorial while in desktop mode, the tutorial will be marked complete and you won't see any more coach marks. However, if you don't finish the right edge tutorial before undocking, you will continue to see all the tutorials you haven't seen yet, as normal.

How do you feel about that last behavior? It might be tricky to do something much smarter unless either (A) we know the "native" usageScenario of the device or (B) we stop marking the "whole-tutorial-is-complete" flag and accept that if we add new pages or redesign th...

Read more...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1979
http://jenkins.qa.ubuntu.com/job/unity8-ci/6745/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5277
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/160/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1458
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/160/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1352
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1353
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/159
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/159
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4186
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5297
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5297/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25290
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/37/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/160
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/160/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25292

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6745/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1981
http://jenkins.qa.ubuntu.com/job/unity8-ci/6749/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5285
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/164/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1462
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/164/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1356
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1357
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/163
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/163
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4194
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5305
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5305/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25309
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/40/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/164
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/164/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25308

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6749/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in tests/plugins/AccountsService/PropertiesServer.cpp
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Fixed conflicts.

Revision history for this message
Albert Astals Cid (aacid) : Posted in a previous version of this proposal
review: Abstain (merges fine)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1983
http://jenkins.qa.ubuntu.com/job/unity8-ci/6787/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5345
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/202/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1500
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/202/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1394
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1395
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/201
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/201
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4239
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5365
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5365/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25431
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/63/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/202
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/202/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25433

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6787/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1984
http://jenkins.qa.ubuntu.com/job/unity8-ci/6794/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5367
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/209/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1507
    FAILURE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/209/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1401
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1402
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/208
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/208
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4256
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5387
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5387/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25462
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/67/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/209
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/209/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25460

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6794/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1985
http://jenkins.qa.ubuntu.com/job/unity8-ci/6823/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5458
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/238/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1534
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/236
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1429
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1429
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/236
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/235
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4306
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5472
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5472/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25583
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/82/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/237
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/237/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25582

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6823/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1986
http://jenkins.qa.ubuntu.com/job/unity8-ci/6834/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5490
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/249/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1545
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/248
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1440
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1440
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/247
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/246
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4318
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5504
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5504/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25632
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/88/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/248
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/248/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/25631

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6834/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

+ i18n.tr("Hover your mouse on the right edge to view your open apps") :
+ i18n.tr("Short or long swipe from the right edge to view your open apps")

I know those have been given by design, but gotta point out some errors:
- In windowed mode, you need to push the mouse against the right edge and even overcome some resistance. Hovering is not enough.
- While at it, we might want to ask back on short swipe one too, but I guess that would be ok to oversimplify it in this case.

========

+ text: d.landscape ? i18n.tr("Swipe from the top right edge to open the notification bar")
+ : i18n.tr("Swipe from the top edge to open the notification bar")

this might needs a windowed mode special case too. We don't want to encourage clicking with a mouse so the indicators can also be revealed by clicking the icons. Although this is not wrong. If you have a touch screen too, you can also swipe then on a desktop.

========

+ text: i18n.tr("Swipe from the left edge to open the launcher")

same as for the right edge. With a mouse, it requires pushing towards the edge. Why not special cased here?

review: Needs Information
Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

Another question:

I figure it will take ages until completed goes to true. Some people might never open the calculator app which would leave us with the tutorial being enabled forever. What are the implications of that?

review: Needs Information
Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

You mention the wording on the left edge drag needing to be changed for desktop mode -- but we don't show that tutorial on desktop. So I'm guessing we can leave it as is.

And you asked about the tutorial never "completing". This is a small issue. And it's why I revised TutorialContent to use loaders for each tutorial page. I don't think it's a problem, per se. But it does mean that we'll likely have the TutorialBottom page loaded most of the time. Until they load all the bottom-supported apps anyway...

Revision history for this message
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal

On the right edge in windowed mode, it's not only the text, but the hoverMouseArea disappered and it's not possible to get past that step any more.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1987
http://jenkins.qa.ubuntu.com/job/unity8-ci/6940/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/5756
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/355/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1651
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/354
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1546
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1546
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/353
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/352
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4467
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5769
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/5769/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26035
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/130/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/354
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/354/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26036

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/6940/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in qml/Launcher/Launcher.qml
1 conflicts encountered.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1987
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/35/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1988
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/124/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1988
http://jenkins.qa.ubuntu.com/job/unity8-ci/7092/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6059
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/507/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1797
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/500
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1692
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1692
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/499
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/498
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4680
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6070
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6070/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26746
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/247/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/505
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/505/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26745

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7092/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
http://jenkins.qa.ubuntu.com/job/unity8-ci/7129/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6133
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/544/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1834
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/537
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1729
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1729
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/536
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/535
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4732
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6144
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6144/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26923
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/280/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/542
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/542/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26924

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7129/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1989
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/168/
Executed test runs:

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal

Text conflict in qml/Stages/PhoneStage.qml
Text conflict in qml/Stages/TabletStage.qml
2 conflicts encountered.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

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

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1990
http://jenkins.qa.ubuntu.com/job/unity8-ci/7260/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6417
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/675/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/1965
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/668
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1860
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1860
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/667
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/666
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4914
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6428
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6428/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27481
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/347/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/673
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/673/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27480

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7260/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1992
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/385/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/523
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/165
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/165
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/546
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/564
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/564
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/560/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/560
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/560/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1992
http://jenkins.qa.ubuntu.com/job/unity8-ci/7323/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6516
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/738/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2028
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/731
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1923
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1923
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/730
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/729
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4975
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6527
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6527/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27663
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/383/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/736
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/736/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27664

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7323/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1993
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/390/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/528
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/170
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/170
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/551
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/569
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/569
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/565/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/565
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/565/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1993
http://jenkins.qa.ubuntu.com/job/unity8-ci/7328/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6521
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/743/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2033
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/736
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1928
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1928
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/735
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/734
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/4980
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6532
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6532/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27677
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/388/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/741
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/741/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27678

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7328/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1995
https://unity8-jenkins.ubuntu.com/job/lp-unity8-1-ci/452/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/607
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay/191
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial/191
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/630
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/648
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/648
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/644/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/644
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/644/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1995
http://jenkins.qa.ubuntu.com/job/unity8-ci/7383/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-vivid-touch/6583
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-xenial-touch/798/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity-phablet-qmluitests-vivid/2088
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/unity8-qmluitest-xenial-amd64/791
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-amd64-ci/1983
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-vivid-i386-ci/1983
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-amd64-ci/790
    SUCCESS: http://jenkins.qa.ubuntu.com/job/unity8-xenial-i386-ci/789
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-vivid-touch/5009
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6594
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-vivid-armhf/6594/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27779
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-xenial-touch/410/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/796
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-xenial-armhf/796/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27778

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/unity8-ci/7383/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1996
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/628/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/356
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/356
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/356
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/832
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/848
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/848
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/846/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/846
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/846/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal

Tests need fixin ↑?

Revision history for this message
Michael Terry (mterry) wrote : Posted in a previous version of this proposal

Fixed the qmluitest, and removed the autopilot test. The tutorial is harder to test via one autopilot test now that the pages have been split up and separately triggered. Plus, we cover them well in qmluitests. And there's nothing autopilot-centric to test there.

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:1999
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/642/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/364
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/364
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/364
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/847
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/863
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/861/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/861
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/861/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2000
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/656/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/373
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/373
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/373
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/862
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/878
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/878
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/876/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/876
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/876/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2002
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/662/
Executed test runs:
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/377
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/377
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/377
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/869
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/885
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/885
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/883/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/883
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/883/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal

FAILED: Continuous integration, rev:2002
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/663/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/378
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/378
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/378
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/870
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/886
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/886
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/884/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/884
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/884/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) :
review: Abstain
2003. By Michael Terry

Patch from dednick, fixing my bad merge

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

merge from side-stage-redesign

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

Merge in shell_chrome

2006. By Michael Terry

Some test fixes

2007. By Michael Terry

Fix last failing test

2008. By Michael Zanetti

fix whitespace

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/AccountsService/AccountsService.cpp'
2--- plugins/AccountsService/AccountsService.cpp 2016-03-15 20:13:36 +0000
3+++ plugins/AccountsService/AccountsService.cpp 2016-03-15 20:13:37 +0000
4@@ -32,6 +32,7 @@
5
6 #define PROP_BACKGROUND_FILE QStringLiteral("BackgroundFile")
7 #define PROP_DEMO_EDGES QStringLiteral("demo-edges")
8+#define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted")
9 #define PROP_EMAIL QStringLiteral("Email")
10 #define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked")
11 #define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked")
12@@ -89,6 +90,7 @@
13 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged"));
14 registerProperty(IFACE_UBUNTU_SECURITY_OLD, PROP_STATS_WELCOME_SCREEN, QStringLiteral("statsWelcomeScreenChanged"));
15 registerProperty(IFACE_UNITY, PROP_DEMO_EDGES, QStringLiteral("demoEdgesChanged"));
16+ registerProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, QStringLiteral("demoEdgesCompletedChanged"));
17 registerProperty(IFACE_UNITY_PRIVATE, PROP_FAILED_LOGINS, QStringLiteral("failedLoginsChanged"));
18
19 registerProxy(IFACE_UBUNTU_INPUT, PROP_MOUSE_CURSOR_SPEED,
20@@ -152,6 +154,20 @@
21 setProperty(IFACE_UNITY, PROP_DEMO_EDGES, demoEdges);
22 }
23
24+QStringList AccountsService::demoEdgesCompleted() const
25+{
26+ auto value = getProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED);
27+ return value.toStringList();
28+}
29+
30+void AccountsService::markDemoEdgeCompleted(const QString &edge)
31+{
32+ auto currentList = demoEdgesCompleted();
33+ if (!currentList.contains(edge)) {
34+ setProperty(IFACE_UNITY, PROP_DEMO_EDGES_COMPLETED, currentList << edge);
35+ }
36+}
37+
38 bool AccountsService::enableLauncherWhileLocked() const
39 {
40 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
41
42=== modified file 'plugins/AccountsService/AccountsService.h'
43--- plugins/AccountsService/AccountsService.h 2016-03-15 20:13:36 +0000
44+++ plugins/AccountsService/AccountsService.h 2016-03-15 20:13:37 +0000
45@@ -20,6 +20,7 @@
46 #include <QHash>
47 #include <QObject>
48 #include <QString>
49+#include <QStringList>
50 #include <QVariant>
51
52 class AccountsServiceDBusAdaptor;
53@@ -37,6 +38,9 @@
54 READ demoEdges
55 WRITE setDemoEdges
56 NOTIFY demoEdgesChanged)
57+ Q_PROPERTY (QStringList demoEdgesCompleted
58+ READ demoEdgesCompleted
59+ NOTIFY demoEdgesCompletedChanged)
60 Q_PROPERTY (bool enableLauncherWhileLocked
61 READ enableLauncherWhileLocked
62 NOTIFY enableLauncherWhileLockedChanged)
63@@ -82,6 +86,8 @@
64 void setUser(const QString &user);
65 bool demoEdges() const;
66 void setDemoEdges(bool demoEdges);
67+ QStringList demoEdgesCompleted() const;
68+ Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
69 bool enableLauncherWhileLocked() const;
70 bool enableIndicatorsWhileLocked() const;
71 QString backgroundFile() const;
72@@ -101,6 +107,7 @@
73 Q_SIGNALS:
74 void userChanged();
75 void demoEdgesChanged();
76+ void demoEdgesCompletedChanged();
77 void enableLauncherWhileLockedChanged();
78 void enableIndicatorsWhileLockedChanged();
79 void backgroundFileChanged();
80
81=== modified file 'plugins/AccountsService/AccountsService.qmltypes'
82--- plugins/AccountsService/AccountsService.qmltypes 2015-02-13 09:01:16 +0000
83+++ plugins/AccountsService/AccountsService.qmltypes 2016-03-15 20:13:37 +0000
84@@ -23,6 +23,7 @@
85 }
86 Property { name: "user"; type: "string" }
87 Property { name: "demoEdges"; type: "bool" }
88+ Property { name: "demoEdgesCompleted"; type: "QStringList"; isReadonly: true }
89 Property { name: "enableLauncherWhileLocked"; type: "bool"; isReadonly: true }
90 Property { name: "enableIndicatorsWhileLocked"; type: "bool"; isReadonly: true }
91 Property { name: "backgroundFile"; type: "string"; isReadonly: true }
92@@ -32,5 +33,9 @@
93 Property { name: "hereEnabled"; type: "bool" }
94 Property { name: "hereLicensePath"; type: "string"; isReadonly: true }
95 Property { name: "hereLicensePathValid"; type: "bool"; isReadonly: true }
96+ Method {
97+ name: "markDemoEdgeCompleted"
98+ Parameter { name: "edge"; type: "string" }
99+ }
100 }
101 }
102
103=== modified file 'plugins/AccountsService/com.canonical.unity.AccountsService.xml'
104--- plugins/AccountsService/com.canonical.unity.AccountsService.xml 2015-02-04 15:12:36 +0000
105+++ plugins/AccountsService/com.canonical.unity.AccountsService.xml 2016-03-15 20:13:37 +0000
106@@ -14,6 +14,11 @@
107 <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/>
108 </property>
109
110+ <!-- List of tutorial pages that have been completed by the user -->
111+ <property name="DemoEdgesCompleted" type="as" access="readwrite">
112+ <annotation name="org.freedesktop.Accounts.DefaultValue" value="[]"/>
113+ </property>
114+
115 <property name="LauncherItems" type="aa{sv}" access="readwrite">
116 <annotation name="org.freedesktop.Accounts.DefaultValue" value="[{'defaults': <true>}]"/>
117 </property>
118
119=== modified file 'plugins/ScreenGrabber/screengrabber.cpp'
120--- plugins/ScreenGrabber/screengrabber.cpp 2015-11-18 18:38:36 +0000
121+++ plugins/ScreenGrabber/screengrabber.cpp 2016-03-15 20:13:37 +0000
122@@ -46,12 +46,10 @@
123
124 QDir screenshotsDir;
125 if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
126- qDebug() << "Using test environment";
127 QTemporaryDir tDir;
128 tDir.setAutoRemove(false);
129 screenshotsDir = tDir.path();
130 } else {
131- qDebug() << "Using real environment";
132 screenshotsDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
133 }
134 screenshotsDir.mkpath(QStringLiteral("Screenshots"));
135
136=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea.cpp'
137--- plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2016-03-15 20:13:36 +0000
138+++ plugins/Ubuntu/Gestures/DirectionalDragArea.cpp 2016-03-15 20:13:37 +0000
139@@ -194,6 +194,26 @@
140 }
141 }
142
143+bool DirectionalDragArea::monitorOnly() const
144+{
145+ return d->monitorOnly;
146+}
147+
148+void DirectionalDragArea::setMonitorOnly(bool monitorOnly)
149+{
150+ if (d->monitorOnly != monitorOnly) {
151+ d->monitorOnly = monitorOnly;
152+
153+ if (monitorOnly && d->status == DirectionalDragAreaPrivate::Undecided) {
154+ TouchRegistry::instance()->removeCandidateOwnerForTouch(d->touchId, this);
155+ // We still wanna know when it ends for keeping the composition time window up-to-date
156+ TouchRegistry::instance()->addTouchWatcher(d->touchId, this);
157+ }
158+
159+ Q_EMIT monitorOnlyChanged(monitorOnly);
160+ }
161+}
162+
163 void DirectionalDragArea::removeTimeConstraints()
164 {
165 d->setMaxTime(60 * 60 * 1000);
166@@ -260,7 +280,10 @@
167 unownedTouchEvent_undecided(unownedTouchEvent);
168 break;
169 default: // Recognized:
170- // do nothing
171+ if (monitorOnly) {
172+ // Treat unowned event as if we owned it, but we are really just watching it
173+ touchEvent_recognized(event);
174+ }
175 break;
176 }
177
178@@ -311,7 +334,9 @@
179 }
180
181 if (movedFarEnoughAlongGestureAxis()) {
182- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
183+ if (!monitorOnly) {
184+ TouchRegistry::instance()->requestTouchOwnership(touchId, q);
185+ }
186 setStatus(Recognized);
187 setPublicPos(touchPoint->pos());
188 setPublicScenePos(touchScenePos);
189@@ -411,12 +436,21 @@
190 if (recognitionIsDisabled()) {
191 // Behave like a dumb TouchArea
192 ddaDebug("Gesture recognition is disabled. Requesting touch ownership immediately.");
193- TouchRegistry::instance()->requestTouchOwnership(touchId, q);
194 setStatus(Recognized);
195- event->accept();
196+ if (monitorOnly) {
197+ watchPressedTouchPoints(touchPoints);
198+ event->ignore();
199+ } else {
200+ TouchRegistry::instance()->requestTouchOwnership(touchId, q);
201+ event->accept();
202+ }
203 } else {
204 // just monitor the touch points for now.
205- TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, q);
206+ if (monitorOnly) {
207+ watchPressedTouchPoints(touchPoints);
208+ } else {
209+ TouchRegistry::instance()->addCandidateOwnerForTouch(touchId, q);
210+ }
211
212 setStatus(Undecided);
213 // Let the item below have it. We will monitor it and grab it later if a gesture
214@@ -893,5 +927,6 @@
215 , recognitionTimer(nullptr)
216 , timeSource(new RealTimeSource)
217 , activeTouches(timeSource)
218+ , monitorOnly(false)
219 {
220 }
221
222=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea.h'
223--- plugins/Ubuntu/Gestures/DirectionalDragArea.h 2015-05-11 07:49:36 +0000
224+++ plugins/Ubuntu/Gestures/DirectionalDragArea.h 2016-03-15 20:13:37 +0000
225@@ -77,6 +77,10 @@
226 WRITE setImmediateRecognition
227 NOTIFY immediateRecognitionChanged)
228
229+ // Whether we are merely monitoring touch events (in which case, we don't
230+ // claim ownership of the touch).
231+ Q_PROPERTY(bool monitorOnly READ monitorOnly WRITE setMonitorOnly NOTIFY monitorOnlyChanged)
232+
233 Q_ENUMS(Direction)
234 public:
235 DirectionalDragArea(QQuickItem *parent = 0);
236@@ -100,6 +104,9 @@
237 bool immediateRecognition() const;
238 void setImmediateRecognition(bool enabled);
239
240+ bool monitorOnly() const;
241+ void setMonitorOnly(bool monitorOnly);
242+
243 bool event(QEvent *e) override;
244
245 /*
246@@ -123,6 +130,7 @@
247 void touchSceneXChanged(qreal value);
248 void touchSceneYChanged(qreal value);
249 void immediateRecognitionChanged(bool value);
250+ void monitorOnlyChanged(bool value);
251
252 protected:
253 void touchEvent(QTouchEvent *event) override;
254
255=== modified file 'plugins/Ubuntu/Gestures/DirectionalDragArea_p.h'
256--- plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 2015-11-20 15:01:39 +0000
257+++ plugins/Ubuntu/Gestures/DirectionalDragArea_p.h 2016-03-15 20:13:37 +0000
258@@ -160,6 +160,8 @@
259
260 ActiveTouchesInfo activeTouches;
261
262+ bool monitorOnly;
263+
264 Q_SIGNALS:
265 void statusChanged(Status value);
266 };
267
268=== modified file 'plugins/Utils/CMakeLists.txt'
269--- plugins/Utils/CMakeLists.txt 2016-03-15 20:13:36 +0000
270+++ plugins/Utils/CMakeLists.txt 2016-03-15 20:13:37 +0000
271@@ -17,7 +17,7 @@
272 unitysortfilterproxymodelqml.cpp
273 Timer.cpp
274 unitymenumodelpaths.cpp
275- windowkeysfilter.cpp
276+ windowinputfilter.cpp
277 windowscreenshotprovider.cpp
278 easingcurve.cpp
279 windowstatestorage.cpp
280
281=== modified file 'plugins/Utils/Utils.qmltypes'
282--- plugins/Utils/Utils.qmltypes 2015-09-03 11:08:46 +0000
283+++ plugins/Utils/Utils.qmltypes 2016-03-15 20:13:37 +0000
284@@ -147,10 +147,10 @@
285 }
286 }
287 Component {
288- name: "WindowKeysFilter"
289+ name: "WindowInputFilter"
290 defaultProperty: "data"
291 prototype: "QQuickItem"
292- exports: ["Utils/WindowKeysFilter 0.1"]
293+ exports: ["Utils/WindowInputFilter 0.1"]
294 exportMetaObjectRevisions: [0]
295 }
296 Component {
297
298=== modified file 'plugins/Utils/plugin.cpp'
299--- plugins/Utils/plugin.cpp 2016-03-15 20:13:36 +0000
300+++ plugins/Utils/plugin.cpp 2016-03-15 20:13:37 +0000
301@@ -30,7 +30,7 @@
302 #include "qlimitproxymodelqml.h"
303 #include "unitysortfilterproxymodelqml.h"
304 #include "unitymenumodelpaths.h"
305-#include "windowkeysfilter.h"
306+#include "windowinputfilter.h"
307 #include "windowscreenshotprovider.h"
308 #include "windowstatestorage.h"
309 #include "constants.h"
310@@ -69,7 +69,7 @@
311 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
312 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
313 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
314- qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
315+ qmlRegisterType<WindowInputFilter>(uri, 0, 1, "WindowInputFilter");
316 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
317 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
318 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
319
320=== renamed file 'plugins/Utils/windowkeysfilter.cpp' => 'plugins/Utils/windowinputfilter.cpp'
321--- plugins/Utils/windowkeysfilter.cpp 2015-10-22 17:37:26 +0000
322+++ plugins/Utils/windowinputfilter.cpp 2016-03-15 20:13:37 +0000
323@@ -16,36 +16,34 @@
324 * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
325 */
326
327-#include "windowkeysfilter.h"
328+#include "windowinputfilter.h"
329
330 #include <QQuickWindow>
331
332-WindowKeysFilter::WindowKeysFilter(QQuickItem *parent)
333+WindowInputFilter::WindowInputFilter(QQuickItem *parent)
334 : QQuickItem(parent),
335- m_currentEventTimestamp(0)
336+ m_lastInputTimestamp(0)
337 {
338 connect(this, &QQuickItem::windowChanged,
339- this, &WindowKeysFilter::setupFilterOnWindow);
340+ this, &WindowInputFilter::setupFilterOnWindow);
341 }
342
343-bool WindowKeysFilter::eventFilter(QObject *watched, QEvent *event)
344+bool WindowInputFilter::eventFilter(QObject *watched, QEvent *event)
345 {
346 Q_ASSERT(!m_filteredWindow.isNull());
347 Q_ASSERT(watched == static_cast<QObject*>(m_filteredWindow.data()));
348 Q_UNUSED(watched);
349
350+ QInputEvent *inputEvent = dynamic_cast<QInputEvent*>(event);
351+ if (inputEvent) {
352+ m_lastInputTimestamp = inputEvent->timestamp();
353+ Q_EMIT lastInputTimestampChanged();
354+ }
355+
356 if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
357 // Let QML see this event and decide if it does not want it
358 event->accept();
359-
360- m_currentEventTimestamp = static_cast<QInputEvent*>(event)->timestamp();
361- Q_EMIT currentEventTimestampChanged();
362-
363 QCoreApplication::sendEvent(this, event);
364-
365- m_currentEventTimestamp = 0;
366- Q_EMIT currentEventTimestampChanged();
367-
368 return event->isAccepted();
369 } else {
370 // Not interested
371@@ -53,7 +51,7 @@
372 }
373 }
374
375-void WindowKeysFilter::setupFilterOnWindow(QQuickWindow *window)
376+void WindowInputFilter::setupFilterOnWindow(QQuickWindow *window)
377 {
378 if (!m_filteredWindow.isNull()) {
379 m_filteredWindow->removeEventFilter(this);
380@@ -66,7 +64,7 @@
381 }
382 }
383
384-ulong WindowKeysFilter::currentEventTimestamp() const
385+ulong WindowInputFilter::lastInputTimestamp() const
386 {
387- return m_currentEventTimestamp;
388+ return m_lastInputTimestamp;
389 }
390
391=== renamed file 'plugins/Utils/windowkeysfilter.h' => 'plugins/Utils/windowinputfilter.h'
392--- plugins/Utils/windowkeysfilter.h 2015-10-22 17:37:26 +0000
393+++ plugins/Utils/windowinputfilter.h 2016-03-15 20:13:37 +0000
394@@ -16,8 +16,8 @@
395 * Author: Daniel d'Andrada <daniel.dandrada@canonical.com>
396 */
397
398-#ifndef UNITY_WINDOWKEYSFILTER_H
399-#define UNITY_WINDOWKEYSFILTER_H
400+#ifndef UNITY_WINDOWINPUTFILTER_H
401+#define UNITY_WINDOWINPUTFILTER_H
402
403 #include <QQuickItem>
404 #include <QPointer>
405@@ -29,30 +29,30 @@
406 accepted ones will be filtered out. Events are accepted by default, so make sure you reject
407 the keys you're not interested in.
408
409- If more than one WindowKeysFilter exist in the same QML scene (and thus in the same QQuickWindow)
410+ If more than one WindowInputFilter exist in the same QML scene (and thus in the same QQuickWindow)
411 they will be called in the order of creation, which can be tricky to assess. So the best practice
412- is to have at most one WindowKeysFilter per QML scene.
413+ is to have at most one WindowInputFilter per QML scene.
414 */
415-class WindowKeysFilter : public QQuickItem
416+class WindowInputFilter : public QQuickItem
417 {
418 Q_OBJECT
419- Q_PROPERTY(ulong currentEventTimestamp READ currentEventTimestamp NOTIFY currentEventTimestampChanged)
420+ Q_PROPERTY(ulong lastInputTimestamp READ lastInputTimestamp NOTIFY lastInputTimestampChanged)
421 public:
422- WindowKeysFilter(QQuickItem *parent = 0);
423+ WindowInputFilter(QQuickItem *parent = 0);
424
425 bool eventFilter(QObject *watched, QEvent *event) override;
426
427- ulong currentEventTimestamp() const;
428+ ulong lastInputTimestamp() const;
429
430 Q_SIGNALS:
431- void currentEventTimestampChanged();
432+ void lastInputTimestampChanged();
433
434 private Q_SLOTS:
435 void setupFilterOnWindow(QQuickWindow *window);
436
437 private:
438 QPointer<QQuickWindow> m_filteredWindow;
439- ulong m_currentEventTimestamp;
440+ ulong m_lastInputTimestamp;
441 };
442
443-#endif // UNITY_WINDOWKEYSFILTER_H
444+#endif // UNITY_WINDOWINPUTFILTER_H
445
446=== modified file 'qml/Components/InputMethod.qml'
447--- qml/Components/InputMethod.qml 2016-02-15 17:26:51 +0000
448+++ qml/Components/InputMethod.qml 2016-03-15 20:13:37 +0000
449@@ -51,7 +51,10 @@
450 }
451
452 state: {
453- if (surfaceItem.surface && surfaceItem.surfaceState != Mir.MinimizedState && root.enabled) {
454+ if (surfaceItem.surface &&
455+ surfaceItem.surfaceState != Mir.HiddenState &&
456+ surfaceItem.surfaceState != Mir.MinimizedState &&
457+ root.enabled) {
458 return "shown";
459 } else {
460 return "hidden";
461
462=== modified file 'qml/Greeter/Greeter.qml'
463--- qml/Greeter/Greeter.qml 2016-01-11 17:37:02 +0000
464+++ qml/Greeter/Greeter.qml 2016-03-15 20:13:37 +0000
465@@ -160,6 +160,14 @@
466 return false;
467 }
468 }
469+
470+ function checkForcedUnlock() {
471+ if (forcedUnlock && shown && loader.item) {
472+ // pretend we were just authenticated
473+ loader.item.notifyAuthenticationSucceeded();
474+ loader.item.hide();
475+ }
476+ }
477 }
478
479 onLauncherOffsetChanged: {
480@@ -168,12 +176,8 @@
481 }
482 }
483
484- onForcedUnlockChanged: {
485- if (forcedUnlock && shown) {
486- // pretend we were just authenticated
487- loader.item.notifyAuthenticationSucceeded();
488- }
489- }
490+ onForcedUnlockChanged: d.checkForcedUnlock()
491+ Component.onCompleted: d.checkForcedUnlock()
492
493 onRequiredChanged: {
494 if (required) {
495
496=== modified file 'qml/Launcher/Launcher.qml'
497--- qml/Launcher/Launcher.qml 2016-03-10 22:37:30 +0000
498+++ qml/Launcher/Launcher.qml 2016-03-15 20:13:37 +0000
499@@ -28,7 +28,6 @@
500 property bool lockedVisible: false
501 property bool available: true // can be used to disable all interactions
502 property alias inverted: panel.inverted
503- property bool shadeBackground: true // can be used to disable background shade when launcher is visible
504
505 property int panelWidth: units.gu(10)
506 property int dragAreaWidth: units.gu(1)
507@@ -298,7 +297,7 @@
508 InverseMouseArea {
509 id: closeMouseArea
510 anchors.fill: panel
511- enabled: root.shadeBackground && root.state == "visible" && (!root.lockedVisible || panel.highlightIndex >= -1)
512+ enabled: root.state == "visible" && (!root.lockedVisible || panel.highlightIndex >= -1)
513 visible: enabled
514 onPressed: {
515 panel.highlightIndex = -2
516@@ -310,7 +309,7 @@
517 id: backgroundShade
518 anchors.fill: parent
519 color: "black"
520- opacity: root.shadeBackground && root.state == "visible" && !root.lockedVisible ? 0.6 : 0
521+ opacity: root.state == "visible" && !root.lockedVisible ? 0.6 : 0
522
523 Behavior on opacity { NumberAnimation { duration: UbuntuAnimation.BriskDuration } }
524 }
525
526=== modified file 'qml/Panel/IndicatorsMenu.qml'
527--- qml/Panel/IndicatorsMenu.qml 2016-03-10 21:28:46 +0000
528+++ qml/Panel/IndicatorsMenu.qml 2016-03-15 20:13:37 +0000
529@@ -36,7 +36,6 @@
530 readonly property bool partiallyOpened: unitProgress > 0 && unitProgress < 1.0
531 readonly property bool fullyClosed: unitProgress == 0
532 property bool enableHint: true
533- property bool contentEnabled: true
534 property bool showOnClick: true
535 property color panelColor: UbuntuColors.jet
536
537@@ -86,7 +85,6 @@
538 height: openedHeight - bar.height - handle.height
539 indicatorsModel: root.indicatorsModel
540 visible: root.unitProgress > 0
541- enabled: contentEnabled
542 currentMenuIndex: bar.currentItemIndex
543 }
544
545
546=== modified file 'qml/Shell.qml'
547--- qml/Shell.qml 2016-03-15 20:13:36 +0000
548+++ qml/Shell.qml 2016-03-15 20:13:37 +0000
549@@ -24,7 +24,7 @@
550 import Ubuntu.Telephony 0.1 as Telephony
551 import Unity.Connectivity 0.1
552 import Unity.Launcher 0.1
553-import GlobalShortcut 1.0 // has to be before Utils, because of WindowKeysFilter
554+import GlobalShortcut 1.0 // has to be before Utils, because of WindowInputFilter
555 import GSettings 1.0
556 import Utils 0.1
557 import Powerd 0.1
558@@ -167,12 +167,13 @@
559 }
560
561 GlobalShortcut {
562- // dummy shortcut to force creation of GlobalShortcutRegistry before WindowKeyFilter
563+ // dummy shortcut to force creation of GlobalShortcutRegistry before WindowInputFilter
564 }
565
566- WindowKeysFilter {
567- Keys.onPressed: physicalKeysMapper.onKeyPressed(event, currentEventTimestamp);
568- Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
569+ WindowInputFilter {
570+ id: inputFilter
571+ Keys.onPressed: physicalKeysMapper.onKeyPressed(event, lastInputTimestamp);
572+ Keys.onReleased: physicalKeysMapper.onKeyReleased(event, lastInputTimestamp);
573 }
574
575 WindowInputMonitor {
576@@ -205,7 +206,7 @@
577 onFocusedApplicationIdChanged: {
578 var appId = ApplicationManager.focusedApplicationId;
579
580- if (tutorial.running && appId != "" && appId != "unity8-dash") {
581+ if (wizard.active && appId != "" && appId != "unity8-dash") {
582 // If this happens on first boot, we may be in edge
583 // tutorial or wizard while receiving a call. But a call
584 // is more important than wizard so just bail out of those.
585@@ -246,7 +247,7 @@
586 property string usageScenario: shell.usageScenario === "phone" || greeter.hasLockedApp
587 ? "phone"
588 : shell.usageScenario
589- source: {
590+ readonly property string qmlComponent: {
591 if(shell.mode === "greeter") {
592 return "Stages/ShimStage.qml"
593 } else if (applicationsDisplayLoader.usageScenario === "phone") {
594@@ -257,9 +258,12 @@
595 return "Stages/DesktopStage.qml";
596 }
597 }
598+ onQmlComponentChanged: {
599+ if (item) item.stageAboutToBeUnloaded();
600+ source = qmlComponent;
601+ }
602
603- property bool interactive: tutorial.spreadEnabled
604- && (!greeter || !greeter.shown)
605+ property bool interactive: (!greeter || !greeter.shown)
606 && panel.indicators.fullyClosed
607 && launcher.progress == 0
608 && !notifications.useModal
609@@ -353,30 +357,6 @@
610 value: shell.usageScenario == "desktop" && !settings.autohideLauncher ? launcher.panelWidth: 0
611 }
612 }
613-
614- Tutorial {
615- id: tutorial
616- objectName: "tutorial"
617- anchors.fill: parent
618-
619- // EdgeDragAreas don't work with mice. So to avoid trapping the user,
620- // we skip the tutorial on the Desktop to avoid using them. The
621- // Desktop doesn't use the same spread design anyway. The tutorial is
622- // all a bit of a placeholder on non-phone form factors right now.
623- // When the design team gives us more guidance, we can do something
624- // more clever here.
625- active: usageScenario != "desktop" && AccountsService.demoEdges
626-
627- paused: lightDM.greeter.active
628- launcher: launcher
629- panel: panel
630- edgeSize: shell.edgeSize
631-
632- onFinished: {
633- AccountsService.demoEdges = false;
634- active = false; // for immediate response / if AS is having problems
635- }
636- }
637 }
638
639 InputMethod {
640@@ -387,7 +367,7 @@
641 topMargin: panel.panelHeight
642 leftMargin: launcher.lockedVisible ? launcher.panelWidth : 0
643 }
644- z: notifications.useModal || panel.indicators.shown || wizard.active ? overlay.z + 1 : overlay.z - 1
645+ z: notifications.useModal || panel.indicators.shown || wizard.active || tutorial.running ? overlay.z + 1 : overlay.z - 1
646 }
647
648 Connections {
649@@ -418,7 +398,7 @@
650 hides: [launcher, panel.indicators]
651 tabletMode: shell.usageScenario != "phone"
652 launcherOffset: launcher.progress
653- forcedUnlock: tutorial.running
654+ forcedUnlock: wizard.active
655 background: wallpaperResolver.background
656
657 // avoid overlapping with Launcher's edge drag area
658@@ -475,7 +455,7 @@
659
660 onStatusChanged: {
661 if (Powerd.status === Powerd.Off && reason !== Powerd.Proximity &&
662- !callManager.hasCalls && !tutorial.running) {
663+ !callManager.hasCalls && !wizard.active) {
664 // We don't want to simply call greeter.showNow() here, because
665 // that will take too long. Qt will delay button event
666 // handling until the greeter is done loading and may think the
667@@ -491,10 +471,6 @@
668 }
669
670 function showHome() {
671- if (tutorial.running) {
672- return
673- }
674-
675 greeter.notifyAboutToFocusApp("unity8-dash");
676
677 var animate = !lightDM.greeter.active && !stages.shown
678@@ -528,7 +504,6 @@
679 available: tutorial.panelEnabled
680 && ((!greeter || !greeter.locked) || AccountsService.enableIndicatorsWhileLocked)
681 && (!greeter || !greeter.hasLockedApp)
682- contentEnabled: tutorial.panelContentEnabled
683 width: parent.width > units.gu(60) ? units.gu(40) : parent.width
684
685 minimizedPanelHeight: units.gu(3)
686@@ -567,7 +542,6 @@
687 && (!greeter.locked || AccountsService.enableLauncherWhileLocked)
688 && !greeter.hasLockedApp
689 inverted: shell.usageScenario !== "desktop"
690- shadeBackground: !tutorial.running
691 superPressed: physicalKeysMapper.superPressed
692 superTabPressed: physicalKeysMapper.superTabPressed
693 panelWidth: units.gu(settings.launcherWidth)
694@@ -581,10 +555,8 @@
695 }
696 }
697 onLauncherApplicationSelected: {
698- if (!tutorial.running) {
699- greeter.notifyAboutToFocusApp(appId);
700- shell.activateApplication(appId)
701- }
702+ greeter.notifyAboutToFocusApp(appId);
703+ shell.activateApplication(appId);
704 }
705 onShownChanged: {
706 if (shown) {
707@@ -624,6 +596,20 @@
708 }
709 }
710
711+ Tutorial {
712+ id: tutorial
713+ objectName: "tutorial"
714+ anchors.fill: parent
715+
716+ paused: callManager.hasCalls || greeter.shown
717+ keyboardVisible: inputMethod.state === "shown"
718+ usageScenario: shell.usageScenario
719+ lastInputTimestamp: inputFilter.lastInputTimestamp
720+ launcher: launcher
721+ panel: panel
722+ stage: applicationsDisplayLoader.item
723+ }
724+
725 Wizard {
726 id: wizard
727 objectName: "wizard"
728
729=== modified file 'qml/Stages/AbstractStage.qml'
730--- qml/Stages/AbstractStage.qml 2016-03-15 20:13:36 +0000
731+++ qml/Stages/AbstractStage.qml 2016-03-15 20:13:37 +0000
732@@ -28,6 +28,7 @@
733 property url background
734 property bool beingResized
735 property int dragAreaWidth
736+ property real dragProgress // How far left the stage has been dragged, used externally by tutorial code
737 property bool interactive
738 property real inverseProgress // This is the progress for left edge drags, in pixels.
739 property bool keepDashRunning: true
740@@ -51,6 +52,8 @@
741 | Qt.InvertedPortraitOrientation
742 | Qt.InvertedLandscapeOrientation
743
744+ signal stageAboutToBeUnloaded
745+
746 // Shared code for use in stage implementations
747 GSettings {
748 id: lifecycleExceptions
749
750=== modified file 'qml/Stages/ApplicationWindow.qml'
751--- qml/Stages/ApplicationWindow.qml 2016-03-15 20:13:36 +0000
752+++ qml/Stages/ApplicationWindow.qml 2016-03-15 20:13:37 +0000
753@@ -60,7 +60,6 @@
754 readonly property color splashColor: root.application ? root.application.splashColor : "#00000000"
755 readonly property color splashColorHeader: root.application ? root.application.splashColorHeader : "#00000000"
756 readonly property color splashColorFooter: root.application ? root.application.splashColorFooter : "#00000000"
757- readonly property url defaultScreenshot: (root.application && root.application.defaultScreenshot !== undefined) ? root.application.defaultScreenshot : ""
758
759 // Whether the Application had a surface before but lost it.
760 property bool hadSurface: sessionContainer.surfaceContainer.hadSurface
761@@ -112,7 +111,6 @@
762 Image {
763 id: screenshotImage
764 objectName: "screenshotImage"
765- source: d.defaultScreenshot
766 anchors.fill: parent
767 antialiasing: !root.interactive
768
769
770=== modified file 'qml/Stages/DesktopStage.qml'
771--- qml/Stages/DesktopStage.qml 2016-03-10 22:37:38 +0000
772+++ qml/Stages/DesktopStage.qml 2016-03-15 20:13:37 +0000
773@@ -255,8 +255,8 @@
774 focus: appId === priv.focusedAppId
775 width: decoratedWindow.width
776 height: decoratedWindow.height
777- property alias requestedWidth: decoratedWindow.requestedWidth
778- property alias requestedHeight: decoratedWindow.requestedHeight
779+ property int requestedWidth: -1
780+ property int requestedHeight: -1
781 property alias minimumWidth: decoratedWindow.minimumWidth
782 property alias minimumHeight: decoratedWindow.minimumHeight
783 property alias maximumWidth: decoratedWindow.maximumWidth
784@@ -388,20 +388,40 @@
785 PropertyChanges {
786 target: appDelegate;
787 x: root.leftMargin; y: 0;
788- requestedWidth: appContainer.width - root.leftMargin; requestedHeight: appContainer.height;
789 visuallyMinimized: false;
790 visuallyMaximized: true
791 }
792+ PropertyChanges {
793+ target: decoratedWindow
794+ requestedWidth: root.width;
795+ requestedHeight: root.height;
796+ }
797 },
798 State {
799 name: "maximizedLeft"; when: appDelegate.maximizedLeft && !appDelegate.minimized
800- PropertyChanges { target: appDelegate; x: root.leftMargin; y: PanelState.panelHeight;
801- requestedWidth: (appContainer.width - root.leftMargin)/2; requestedHeight: appContainer.height - PanelState.panelHeight }
802+ PropertyChanges {
803+ target: appDelegate
804+ x: root.leftMargin
805+ y: PanelState.panelHeight
806+ }
807+ PropertyChanges {
808+ target: decoratedWindow
809+ requestedWidth: (appContainer.width - root.leftMargin)/2
810+ requestedHeight: appContainer.height - PanelState.panelHeight
811+ }
812 },
813 State {
814 name: "maximizedRight"; when: appDelegate.maximizedRight && !appDelegate.minimized
815- PropertyChanges { target: appDelegate; x: (appContainer.width + root.leftMargin)/2; y: PanelState.panelHeight;
816- requestedWidth: (appContainer.width - root.leftMargin)/2; requestedHeight: appContainer.height - PanelState.panelHeight }
817+ PropertyChanges {
818+ target: appDelegate;
819+ x: (appContainer.width + root.leftMargin)/2
820+ y: PanelState.panelHeight
821+ }
822+ PropertyChanges {
823+ target: decoratedWindow
824+ requestedWidth: (appContainer.width - root.leftMargin)/2
825+ requestedHeight: appContainer.height - PanelState.panelHeight
826+ }
827 },
828 State {
829 name: "minimized"; when: appDelegate.minimized
830@@ -421,13 +441,17 @@
831 enabled: appDelegate.animationsEnabled
832 PropertyAction { target: appDelegate; properties: "visuallyMinimized,visuallyMaximized" }
833 UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
834+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
835 },
836 Transition {
837 to: "minimized"
838 enabled: appDelegate.animationsEnabled
839 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
840 SequentialAnimation {
841- UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
842+ ParallelAnimation {
843+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,scale"; duration: UbuntuAnimation.FastDuration }
844+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
845+ }
846 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
847 ScriptAction {
848 script: {
849@@ -443,7 +467,10 @@
850 enabled: appDelegate.animationsEnabled
851 PropertyAction { target: appDelegate; property: "visuallyMinimized" }
852 SequentialAnimation {
853- UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,requestedWidth,requestedHeight,scale"; duration: UbuntuAnimation.FastDuration }
854+ ParallelAnimation {
855+ UbuntuNumberAnimation { target: appDelegate; properties: "x,y,opacity,scale"; duration: UbuntuAnimation.FastDuration }
856+ UbuntuNumberAnimation { target: decoratedWindow; properties: "requestedWidth,requestedHeight"; duration: UbuntuAnimation.FastDuration }
857+ }
858 PropertyAction { target: appDelegate; property: "visuallyMaximized" }
859 }
860 }
861@@ -458,6 +485,7 @@
862 }
863
864 WindowResizeArea {
865+ id: resizeArea
866 objectName: "windowResizeArea"
867 target: appDelegate
868 minWidth: units.gu(10)
869@@ -469,6 +497,21 @@
870 leftMargin: root.leftMargin
871
872 onPressed: { ApplicationManager.focusApplication(model.appId) }
873+
874+ property bool saveStateOnDestruction: true
875+ Connections {
876+ target: root
877+ onStageAboutToBeUnloaded: {
878+ resizeArea.saveWindowState();
879+ resizeArea.saveStateOnDestruction = false;
880+ fullscreenPolicy.active = false;
881+ }
882+ }
883+ Component.onDestruction: {
884+ if (saveStateOnDestruction) {
885+ saveWindowState();
886+ }
887+ }
888 }
889
890 DecoratedWindow {
891@@ -480,12 +523,21 @@
892 active: ApplicationManager.focusedApplicationId === model.appId
893 focus: true
894
895+ requestedWidth: appDelegate.requestedWidth
896+ requestedHeight: appDelegate.requestedHeight
897+
898 onClose: ApplicationManager.stopApplication(model.appId)
899 onMaximize: appDelegate.maximized || appDelegate.maximizedLeft || appDelegate.maximizedRight
900 ? appDelegate.restoreFromMaximized() : appDelegate.maximize()
901 onMinimize: appDelegate.minimize()
902 onDecorationPressed: { ApplicationManager.focusApplication(model.appId) }
903 }
904+
905+ WindowedFullscreenPolicy {
906+ id: fullscreenPolicy
907+ active: true
908+ application: decoratedWindow.application
909+ }
910 }
911 }
912 }
913
914=== modified file 'qml/Stages/PhoneStage.qml'
915--- qml/Stages/PhoneStage.qml 2016-03-10 09:19:38 +0000
916+++ qml/Stages/PhoneStage.qml 2016-03-15 20:13:37 +0000
917@@ -120,14 +120,11 @@
918 : (Qt.PortraitOrientation | Qt.LandscapeOrientation
919 | Qt.InvertedPortraitOrientation | Qt.InvertedLandscapeOrientation)
920
921- // How far left the stage has been dragged
922- readonly property real dragProgress: spreadRepeater.count > 0 ? -spreadRepeater.itemAt(0).xTranslate : 0
923+ // How far left the stage has been dragged, used externally by tutorial code
924+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0
925
926 readonly property alias dragging: spreadDragArea.dragging
927
928- // Only used by the tutorial right now, when it is teasing the right edge
929- property real dragAreaOverlap
930-
931 signal opened()
932
933 function select(appId) {
934@@ -629,6 +626,15 @@
935 property: "focusedAppOrientationChangesEnabled"
936 value: orientationChangesEnabled
937 }
938+
939+ StagedFullscreenPolicy {
940+ id: fullscreenPolicy
941+ application: appDelegate.application
942+ }
943+ Connections {
944+ target: root
945+ onStageAboutToBeUnloaded: fullscreenPolicy.active = false
946+ }
947 }
948 }
949 }
950@@ -647,7 +653,7 @@
951 direction: Direction.Leftwards
952 enabled: (spreadView.phase != 2 && root.spreadEnabled) || dragging
953
954- anchors { top: parent.top; right: parent.right; bottom: parent.bottom; rightMargin: -root.dragAreaOverlap }
955+ anchors { top: parent.top; right: parent.right; bottom: parent.bottom; }
956 width: root.dragAreaWidth
957
958 property var gesturePoints: new Array()
959
960=== added file 'qml/Stages/StagedFullscreenPolicy.qml'
961--- qml/Stages/StagedFullscreenPolicy.qml 1970-01-01 00:00:00 +0000
962+++ qml/Stages/StagedFullscreenPolicy.qml 2016-03-15 20:13:37 +0000
963@@ -0,0 +1,58 @@
964+/*
965+ * Copyright (C) 2016 Canonical, Ltd.
966+ *
967+ * This program is free software; you can redistribute it and/or modify
968+ * it under the terms of the GNU General Public License as published by
969+ * the Free Software Foundation; version 3.
970+ *
971+ * This program is distributed in the hope that it will be useful,
972+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
973+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
974+ * GNU General Public License for more details.
975+ *
976+ * You should have received a copy of the GNU General Public License
977+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
978+ */
979+
980+import QtQuick 2.4
981+import Unity.Application 0.1
982+
983+// This component will change the state of the surface based on the surface
984+// state and shell chrome.
985+//
986+// Chrome changed to LowChrome -> server sets client window state to "fullscreen"
987+// Chrome changed to NormalChrome -> server sets client window to "restored" state.
988+// Chrome set and state change to restored -> server RESETS client window state to "fullscreen"
989+// Chrome not set and state change to restored -> client window stays "restored"
990+// Chrome not set and state change to fulscreen -> client window stays "fullscreen"
991+QtObject {
992+ property bool active: true
993+ property QtObject application: null
994+
995+ readonly property var lastSurface: application && application.session ?
996+ application.session.lastSurface : null
997+ onLastSurfaceChanged: {
998+ if (!active || !lastSurface) return;
999+ if (lastSurface.shellChrome === Mir.LowChrome) {
1000+ lastSurface.state = Mir.FullscreenState;
1001+ }
1002+ }
1003+
1004+ property var _connections: Connections {
1005+ target: lastSurface
1006+ onShellChromeChanged: {
1007+ if (!active || !lastSurface) return;
1008+ if (lastSurface.shellChrome === Mir.LowChrome) {
1009+ lastSurface.state = Mir.FullscreenState;
1010+ } else {
1011+ lastSurface.state = Mir.RestoredState;
1012+ }
1013+ }
1014+ onStateChanged: {
1015+ if (!active) return;
1016+ if (lastSurface.state === Mir.RestoredState && lastSurface.shellChrome === Mir.LowChrome) {
1017+ lastSurface.state = Mir.FullscreenState;
1018+ }
1019+ }
1020+ }
1021+}
1022
1023=== modified file 'qml/Stages/TabletStage.qml'
1024--- qml/Stages/TabletStage.qml 2016-03-15 20:13:36 +0000
1025+++ qml/Stages/TabletStage.qml 2016-03-15 20:13:37 +0000
1026@@ -27,6 +27,9 @@
1027 objectName: "stages"
1028 anchors.fill: parent
1029
1030+ property alias sideStageVisible: spreadView.sideStageVisible
1031+ property alias sideStageWidth: spreadView.sideStageWidth
1032+
1033 // Functions to be called from outside
1034 function updateFocusedAppOrientation() {
1035 var mainStageAppIndex = priv.indexOf(priv.mainStageAppId);
1036@@ -97,6 +100,9 @@
1037 }
1038 }
1039
1040+ // How far left the stage has been dragged, used externally by tutorial code
1041+ dragProgress: spreadRepeater.count > 0 ? spreadRepeater.itemAt(0).animatedProgress : 0
1042+
1043 onWidthChanged: {
1044 spreadView.selectedIndex = -1;
1045 spreadView.phase = 0;
1046@@ -318,8 +324,6 @@
1047 contentX: -shift
1048
1049 property int tileDistance: units.gu(20)
1050- property int sideStageWidth: units.gu(40)
1051- property bool sideStageVisible: priv.sideStageAppId
1052
1053 // This indicates when the spreadView is active. That means, all the animations
1054 // are activated and tiles need to line up for the spread.
1055@@ -382,6 +386,9 @@
1056 }
1057
1058 property real sideStageDragProgress: sideStage.progress
1059+ property bool sideStageVisible: priv.sideStageAppId
1060+ property real sideStageWidth: units.gu(40)
1061+
1062 property bool surfaceDragging: triGestureArea.recognisedDrag
1063
1064 // In case the ApplicationManager already holds an app when starting up we're missing animations
1065@@ -688,9 +695,6 @@
1066
1067 readonly property bool wantsMainStage: model.stage == ApplicationInfoInterface.MainStage
1068
1069- readonly property string appId: model.appId
1070- readonly property bool isDash: model.appId == "unity8-dash"
1071-
1072 stage: model.stage
1073 fullscreen: {
1074 if (mainApp && stage === ApplicationInfoInterface.SideStage) {
1075@@ -947,6 +951,15 @@
1076 period: (spreadView.positionMarker2 - spreadView.positionMarker1) / 3
1077 progress: spreadTile.progress - spreadView.positionMarker1
1078 }
1079+
1080+ StagedFullscreenPolicy {
1081+ id: fullscreenPolicy
1082+ application: spreadTile.application
1083+ }
1084+ Connections {
1085+ target: root
1086+ onStageAboutToBeUnloaded: fullscreenPolicy.active = false
1087+ }
1088 }
1089 }
1090 }
1091
1092=== modified file 'qml/Stages/WindowResizeArea.qml'
1093--- qml/Stages/WindowResizeArea.qml 2016-03-10 22:43:31 +0000
1094+++ qml/Stages/WindowResizeArea.qml 2016-03-15 20:13:37 +0000
1095@@ -87,7 +87,7 @@
1096 priv.updateNormalGeometry();
1097 }
1098
1099- Component.onDestruction: {
1100+ function saveWindowState() {
1101 windowStateStorage.saveState(root.windowId, target.state == "maximized" ? WindowStateStorage.WindowStateMaximized : WindowStateStorage.WindowStateNormal)
1102 windowStateStorage.saveGeometry(root.windowId, Qt.rect(priv.normalX, priv.normalY, priv.normalWidth, priv.normalHeight))
1103 }
1104
1105=== added file 'qml/Stages/WindowedFullscreenPolicy.qml'
1106--- qml/Stages/WindowedFullscreenPolicy.qml 1970-01-01 00:00:00 +0000
1107+++ qml/Stages/WindowedFullscreenPolicy.qml 2016-03-15 20:13:37 +0000
1108@@ -0,0 +1,41 @@
1109+/*
1110+ * Copyright (C) 2016 Canonical, Ltd.
1111+ *
1112+ * This program is free software; you can redistribute it and/or modify
1113+ * it under the terms of the GNU General Public License as published by
1114+ * the Free Software Foundation; version 3.
1115+ *
1116+ * This program is distributed in the hope that it will be useful,
1117+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1118+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1119+ * GNU General Public License for more details.
1120+ *
1121+ * You should have received a copy of the GNU General Public License
1122+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1123+ */
1124+
1125+import QtQml 2.2
1126+import Unity.Application 0.1
1127+
1128+// This component will change the state of the surface when the stage is loaded.
1129+//
1130+// On first surface load; if the surface is set to low chrome & fullscreen, the
1131+// state of the window is returned to restored.
1132+QtObject {
1133+ property bool active: true
1134+ property QtObject application: null
1135+
1136+ readonly property var lastSurface: application && application.session ?
1137+ application.session.lastSurface : null
1138+ property bool _firstTimeSurface: true
1139+
1140+ onLastSurfaceChanged: {
1141+ if (!active || !lastSurface) return;
1142+ if (!_firstTimeSurface) return;
1143+ _firstTimeSurface = false;
1144+
1145+ if (lastSurface.state === Mir.FullscreenState && lastSurface.shellChrome === Mir.LowChrome) {
1146+ lastSurface.state = Mir.RestoredState;
1147+ }
1148+ }
1149+}
1150
1151=== removed file 'qml/Tutorial/Arrow.qml'
1152--- qml/Tutorial/Arrow.qml 2015-07-15 15:07:19 +0000
1153+++ qml/Tutorial/Arrow.qml 1970-01-01 00:00:00 +0000
1154@@ -1,56 +0,0 @@
1155-/*
1156- * Copyright (C) 2014 Canonical, Ltd.
1157- *
1158- * This program is free software; you can redistribute it and/or modify
1159- * it under the terms of the GNU General Public License as published by
1160- * the Free Software Foundation; version 3.
1161- *
1162- * This program is distributed in the hope that it will be useful,
1163- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1164- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1165- * GNU General Public License for more details.
1166- *
1167- * You should have received a copy of the GNU General Public License
1168- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1169- */
1170-
1171-import QtQuick 2.4
1172-import Ubuntu.Components 1.3
1173-
1174-Item {
1175- id: root
1176-
1177- property alias color: circle.color
1178-
1179- // Will make whole arrow darker
1180- property real darkenBy: 0
1181-
1182- property alias chevronOpacity: chevron.opacity
1183-
1184- ////
1185-
1186- Rectangle {
1187- id: circle
1188- anchors.fill: parent
1189- radius: width / 2
1190- }
1191-
1192- Image {
1193- id: chevron
1194- anchors.centerIn: parent
1195- source: Qt.resolvedUrl("graphics/chevron.png")
1196- fillMode: Image.PreserveAspectFit
1197- sourceSize.width: 152
1198- sourceSize.height: 152
1199- width: parent.width / 2
1200- height: parent.height / 2
1201- }
1202-
1203- Rectangle {
1204- id: darkCircle
1205- anchors.fill: parent
1206- radius: width / 2
1207- color: "black"
1208- opacity: root.darkenBy
1209- }
1210-}
1211
1212=== added file 'qml/Tutorial/InactivityTimer.qml'
1213--- qml/Tutorial/InactivityTimer.qml 1970-01-01 00:00:00 +0000
1214+++ qml/Tutorial/InactivityTimer.qml 2016-03-15 20:13:37 +0000
1215@@ -0,0 +1,62 @@
1216+/*
1217+ * Copyright (C) 2015 Canonical, Ltd.
1218+ *
1219+ * This program is free software; you can redistribute it and/or modify
1220+ * it under the terms of the GNU General Public License as published by
1221+ * the Free Software Foundation; version 3.
1222+ *
1223+ * This program is distributed in the hope that it will be useful,
1224+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1225+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1226+ * GNU General Public License for more details.
1227+ *
1228+ * You should have received a copy of the GNU General Public License
1229+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1230+ */
1231+
1232+import QtQuick 2.4
1233+import Ubuntu.Components 1.3
1234+
1235+Item {
1236+ readonly property alias running: internalTimer.running
1237+ property alias interval: internalTimer.interval
1238+ property var page
1239+ property int lastInputTimestamp
1240+
1241+ function start() {
1242+ internalTimer.start();
1243+ }
1244+
1245+ ////
1246+
1247+ onLastInputTimestampChanged: {
1248+ if (internalTimer.running) {
1249+ internalTimer.restart();
1250+ }
1251+ }
1252+
1253+ Connections {
1254+ target: page
1255+ onIsReadyChanged: {
1256+ if (page.isReady && internalTimer.running) {
1257+ internalTimer.restart();
1258+ }
1259+ }
1260+ }
1261+
1262+ Timer {
1263+ id: internalTimer
1264+
1265+ interval: 3000
1266+
1267+ onTriggered: {
1268+ if (page.isReady) {
1269+ if (!page.shown) {
1270+ page.show();
1271+ }
1272+ } else if (!page.skipped) {
1273+ restart();
1274+ }
1275+ }
1276+ }
1277+}
1278
1279=== removed file 'qml/Tutorial/Slider.qml'
1280--- qml/Tutorial/Slider.qml 2015-07-15 15:07:19 +0000
1281+++ qml/Tutorial/Slider.qml 1970-01-01 00:00:00 +0000
1282@@ -1,123 +0,0 @@
1283-/*
1284- * Copyright (C) 2014 Canonical, Ltd.
1285- *
1286- * This program is free software; you can redistribute it and/or modify
1287- * it under the terms of the GNU General Public License as published by
1288- * the Free Software Foundation; version 3.
1289- *
1290- * This program is distributed in the hope that it will be useful,
1291- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1292- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1293- * GNU General Public License for more details.
1294- *
1295- * You should have received a copy of the GNU General Public License
1296- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1297- */
1298-
1299-import QtQuick 2.4
1300-import Ubuntu.Components 1.3
1301-
1302-Item {
1303- id: root
1304-
1305- // Whether this slider is short or long
1306- property bool shortSwipe
1307-
1308- // How far the user has slid
1309- property real offset
1310-
1311- // Set to true when slider is being used
1312- property bool active
1313-
1314- // How far in percentage terms
1315- readonly property real percent: d.slideOffset / target.x
1316-
1317- QtObject {
1318- id: d
1319- readonly property color trayColor: "#424141"
1320- readonly property real margin: units.gu(0.5)
1321- readonly property real arrowSize: root.height - margin * 2
1322- readonly property real dotSize: units.dp(1)
1323- readonly property real slideOffset: MathUtils.clamp(root.offset - offscreenOffset, -offscreenOffset, target.x)
1324- readonly property real offscreenOffset: units.gu(2)
1325- }
1326-
1327- implicitWidth: shortSwipe ? units.gu(15) : units.gu(27.5)
1328- implicitHeight: units.gu(6.5)
1329-
1330- Rectangle {
1331- color: d.trayColor
1332- anchors.fill: parent
1333- anchors.rightMargin: clipBox.width - 1
1334- }
1335-
1336- // We want to have a circular border around the target. But we can't just
1337- // do a radius on two of a rectangle's corners. So we clip a full circle.
1338- Item {
1339- id: clipBox
1340-
1341- clip: true
1342- anchors.top: parent.top
1343- anchors.bottom: parent.bottom
1344- anchors.right: parent.right
1345- width: parent.height / 2
1346-
1347- Rectangle {
1348- color: d.trayColor
1349- anchors.top: parent.top
1350- anchors.bottom: parent.bottom
1351- anchors.right: parent.right
1352- width: parent.width * 2
1353- radius: parent.width
1354- }
1355- }
1356-
1357- Arrow {
1358- id: target
1359- width: d.arrowSize
1360- height: d.arrowSize
1361- color: "#73000000"
1362- chevronOpacity: 0.52
1363- anchors.right: parent.right
1364- anchors.rightMargin: d.margin
1365- anchors.verticalCenter: parent.verticalCenter
1366- }
1367-
1368- Row {
1369- anchors.left: handle.horizontalCenter
1370- anchors.right: target.horizontalCenter
1371- anchors.verticalCenter: parent.verticalCenter
1372-
1373- layoutDirection: Qt.RightToLeft
1374- spacing: d.dotSize * 2
1375-
1376- Repeater {
1377- model: parent.width / (parent.spacing + d.dotSize)
1378- Rectangle {
1379- anchors.verticalCenter: parent ? parent.verticalCenter : undefined
1380- height: d.dotSize
1381- width: height
1382- radius: width
1383- color: "white"
1384- opacity: 0.2
1385- }
1386- }
1387- }
1388-
1389- Arrow {
1390- id: handle
1391- width: d.arrowSize
1392- height: d.arrowSize
1393- color: UbuntuColors.orange
1394- darkenBy: root.active ? 0.5 : 0
1395- anchors.left: parent.left
1396- // We use a Translate transform rather than anchors.leftMargin because
1397- // the latter has weird performance problems on the TutorialRight page.
1398- transform: [
1399- Translate {
1400- x: d.slideOffset
1401- }
1402- ]
1403- anchors.verticalCenter: parent.verticalCenter
1404- }
1405-}
1406
1407=== removed file 'qml/Tutorial/Tick.qml'
1408--- qml/Tutorial/Tick.qml 2015-07-15 15:07:19 +0000
1409+++ qml/Tutorial/Tick.qml 1970-01-01 00:00:00 +0000
1410@@ -1,29 +0,0 @@
1411-/*
1412- * Copyright (C) 2015 Canonical, Ltd.
1413- *
1414- * This program is free software; you can redistribute it and/or modify
1415- * it under the terms of the GNU General Public License as published by
1416- * the Free Software Foundation; version 3.
1417- *
1418- * This program is distributed in the hope that it will be useful,
1419- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1420- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1421- * GNU General Public License for more details.
1422- *
1423- * You should have received a copy of the GNU General Public License
1424- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1425- */
1426-
1427-import QtQuick 2.4
1428-import Ubuntu.Components 1.3
1429-
1430-MouseArea {
1431- implicitHeight: tick.height
1432- implicitWidth: tick.width
1433- Image {
1434- id: tick
1435- source: Qt.resolvedUrl("graphics/tick.png")
1436- height: units.gu(6.5)
1437- width: units.gu(6.5)
1438- }
1439-}
1440
1441=== modified file 'qml/Tutorial/Tutorial.qml'
1442--- qml/Tutorial/Tutorial.qml 2015-08-25 07:25:26 +0000
1443+++ qml/Tutorial/Tutorial.qml 2016-03-15 20:13:37 +0000
1444@@ -16,21 +16,29 @@
1445
1446 import QtQuick 2.4
1447 import Ubuntu.Components 1.3
1448+import AccountsService 0.1
1449+
1450+/**
1451+ * This object is always present, so it should be lean and mean. It will
1452+ * use a Loader to create the heavier tutorial pages if needed.
1453+ */
1454
1455 Item {
1456 id: root
1457
1458 property alias active: loader.active
1459- property bool paused
1460- property real edgeSize
1461
1462 property Item launcher
1463 property Item panel
1464+ property Item stage
1465+ property string usageScenario
1466+ property bool paused
1467+ property bool keyboardVisible
1468+ property int lastInputTimestamp
1469
1470 readonly property bool launcherEnabled: loader.item ? loader.item.launcherEnabled : true
1471 readonly property bool spreadEnabled: loader.item ? loader.item.spreadEnabled : true
1472 readonly property bool panelEnabled: loader.item ? loader.item.panelEnabled : true
1473- readonly property bool panelContentEnabled: loader.item ? loader.item.panelContentEnabled : true
1474 readonly property bool running: loader.item ? loader.item.running : false
1475
1476 function finish() {
1477@@ -39,24 +47,11 @@
1478 }
1479 }
1480
1481- signal finished()
1482-
1483 Loader {
1484 id: loader
1485 anchors.fill: parent
1486 source: "TutorialContent.qml"
1487-
1488- Binding {
1489- target: loader.item
1490- property: "paused"
1491- value: root.paused
1492- }
1493-
1494- Binding {
1495- target: loader.item
1496- property: "edgeSize"
1497- value: root.edgeSize
1498- }
1499+ active: AccountsService.demoEdges
1500
1501 Binding {
1502 target: loader.item
1503@@ -70,9 +65,39 @@
1504 value: root.panel
1505 }
1506
1507+ Binding {
1508+ target: loader.item
1509+ property: "stage"
1510+ value: root.stage
1511+ }
1512+
1513+ Binding {
1514+ target: loader.item
1515+ property: "usageScenario"
1516+ value: root.usageScenario
1517+ }
1518+
1519+ Binding {
1520+ target: loader.item
1521+ property: "paused"
1522+ value: root.paused
1523+ }
1524+
1525+ Binding {
1526+ target: loader.item
1527+ property: "keyboardVisible"
1528+ value: root.keyboardVisible
1529+ }
1530+
1531+ Binding {
1532+ target: loader.item
1533+ property: "lastInputTimestamp"
1534+ value: root.lastInputTimestamp
1535+ }
1536+
1537 Connections {
1538 target: loader.item
1539- onFinished: root.finished()
1540+ onFinished: AccountsService.demoEdges = false
1541 }
1542 }
1543 }
1544
1545=== added file 'qml/Tutorial/TutorialBottom.qml'
1546--- qml/Tutorial/TutorialBottom.qml 1970-01-01 00:00:00 +0000
1547+++ qml/Tutorial/TutorialBottom.qml 2016-03-15 20:13:37 +0000
1548@@ -0,0 +1,126 @@
1549+/*
1550+ * Copyright (C) 2015 Canonical, Ltd.
1551+ *
1552+ * This program is free software; you can redistribute it and/or modify
1553+ * it under the terms of the GNU General Public License as published by
1554+ * the Free Software Foundation; version 3.
1555+ *
1556+ * This program is distributed in the hope that it will be useful,
1557+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1558+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1559+ * GNU General Public License for more details.
1560+ *
1561+ * You should have received a copy of the GNU General Public License
1562+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1563+ */
1564+
1565+import QtQuick 2.4
1566+import Ubuntu.Components 1.3
1567+import Ubuntu.Gestures 0.1
1568+import Unity.Application 0.1
1569+
1570+TutorialPage {
1571+ id: root
1572+
1573+ property string usageScenario
1574+ property var stage
1575+ property var application: null
1576+
1577+ // This page is a bit fragile. It relies on knowing how the app beneath
1578+ // the shell will react to a drag. What we do is put a monitor-only DDA
1579+ // at the bottom of the page (so that we know when the drag is finished)
1580+ // and pass the events on through to the app. Thus, it sees the drag and
1581+ // brings its bottom edge up.
1582+ //
1583+ // Unfortunately, each app is on its own when implementing the bottom edge
1584+ // drag. Most share copied-and-pasted code right now, but they will
1585+ // eventually consolidate on a version of DirectionalDragArea that will
1586+ // land in the SDK (making our guessing job easier). Though, also in the
1587+ // future, this whole bottom tutorial component will also land in the SDK,
1588+ // rendering our version here obsolete.
1589+ //
1590+ // Anyway, for the moment, we base our guesses on the copied-and-pasted
1591+ // code used in several of the core apps and only bring this component
1592+ // up if we are in those core apps.
1593+
1594+ readonly property real mainStageWidth: stage.width - sideStageWidth
1595+ readonly property real sideStageWidth: root.usageScenario === "tablet" && stage.sideStageVisible ?
1596+ stage.sideStageWidth : 0
1597+ readonly property bool isMainStageApp: usageScenario !== "tablet" ||
1598+ application.stage === ApplicationInfoInterface.MainStage
1599+ readonly property real dragAreaHeight: units.gu(3) // based on PageWithBottomEdge.qml
1600+ readonly property real targetDistance: height * 0.2 + dragAreaHeight // based on PageWithBottomEdge.qml
1601+
1602+ opacityOverride: dragArea.dragging ? 1 - (-dragArea.distance / targetDistance) : 1
1603+
1604+ mouseArea {
1605+ anchors.bottomMargin: root.dragAreaHeight
1606+ }
1607+
1608+ background {
1609+ sourceSize.height: 1916
1610+ sourceSize.width: 1080
1611+ source: Qt.resolvedUrl("graphics/background2.png")
1612+ rotation: 180
1613+ }
1614+
1615+ arrow {
1616+ anchors.bottom: root.bottom
1617+ anchors.bottomMargin: units.gu(3)
1618+ anchors.horizontalCenter: label.horizontalCenter
1619+ anchors.horizontalCenterOffset: -(label.width - label.contentWidth) / 2
1620+ rotation: 90
1621+ }
1622+
1623+ label {
1624+ text: !application ? "" :
1625+ application.appId === "address-book-app" ?
1626+ i18n.tr("Swipe up to add a contact") :
1627+ application.appId === "com.ubuntu.calculator_calculator" ?
1628+ i18n.tr("Swipe up for favorite calculations") :
1629+ application.appId === "com.ubuntu.clock_clock" ?
1630+ i18n.tr("Swipe up to manage alarms") :
1631+ application.appId === "dialer-app" ?
1632+ i18n.tr("Swipe up for recent calls") :
1633+ application.appId === "messaging-app" ?
1634+ i18n.tr("Swipe up to create a message") :
1635+ i18n.tr("Swipe up to manage the app") // shouldn't be used
1636+ anchors.bottom: arrow.top
1637+ anchors.bottomMargin: units.gu(3)
1638+ anchors.left: root.left
1639+ anchors.leftMargin: (label.width - label.contentWidth) / 2 + sideMargin +
1640+ (isMainStageApp ? 0 : mainStageWidth)
1641+ width: (isMainStageApp ? mainStageWidth : sideStageWidth) - sideMargin * 2
1642+
1643+ readonly property real sideMargin: units.gu(4)
1644+ }
1645+
1646+ // Watches drag events but does not intercept them, so that the app beneath
1647+ // will still drag the bottom edge up.
1648+ DirectionalDragArea {
1649+ id: dragArea
1650+ monitorOnly: true
1651+ direction: Direction.Upwards
1652+ anchors.left: parent.left
1653+ anchors.right: parent.right
1654+ anchors.bottom: parent.bottom
1655+ height: root.dragAreaHeight
1656+
1657+ // Apps currently don't use DDA. DDA will stop a gesture if
1658+ // horizontal motion is detected. But our apps won't. So turn off
1659+ // that gesture cleverness on our part, it will only get us out of sync.
1660+ immediateRecognition: true
1661+ }
1662+
1663+ MouseArea {
1664+ // A second mouse area because in tablet mode, we only want to let the
1665+ // user drag up on one of the stages, not both. So we want to cover
1666+ // the second bottom edge with an event eater.
1667+ enabled: root.usageScenario === "tablet"
1668+ height: root.dragAreaHeight
1669+ width: isMainStageApp ? sideStageWidth : mainStageWidth
1670+ anchors.bottom: parent.bottom
1671+ anchors.left: isMainStageApp ? undefined : parent.left
1672+ anchors.right: isMainStageApp ? parent.right : undefined
1673+ }
1674+}
1675
1676=== removed file 'qml/Tutorial/TutorialBottom.qml'
1677--- qml/Tutorial/TutorialBottom.qml 2015-07-15 15:07:19 +0000
1678+++ qml/Tutorial/TutorialBottom.qml 1970-01-01 00:00:00 +0000
1679@@ -1,104 +0,0 @@
1680-/*
1681- * Copyright (C) 2014 Canonical, Ltd.
1682- *
1683- * This program is free software; you can redistribute it and/or modify
1684- * it under the terms of the GNU General Public License as published by
1685- * the Free Software Foundation; version 3.
1686- *
1687- * This program is distributed in the hope that it will be useful,
1688- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1689- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1690- * GNU General Public License for more details.
1691- *
1692- * You should have received a copy of the GNU General Public License
1693- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1694- */
1695-
1696-import QtQuick 2.4
1697-import Ubuntu.Components 1.3
1698-import Ubuntu.Gestures 0.1
1699-import "../Components"
1700-import "." as LocalComponents
1701-
1702-TutorialPage {
1703- id: root
1704-
1705- property alias edgeSize: dragArea.height
1706-
1707- title: i18n.tr("Open special menus")
1708- text: i18n.tr("Swipe up from the bottom edge.")
1709- fullTextWidth: true
1710-
1711- SequentialAnimation {
1712- id: teaseAnimation
1713- paused: running && root.paused
1714- running: !dragArea.useTouchY && slider.dragOffset === 0
1715- loops: Animation.Infinite
1716-
1717- UbuntuNumberAnimation {
1718- target: slider
1719- property: "teaseOffset"
1720- to: units.gu(1)
1721- duration: UbuntuAnimation.SleepyDuration
1722- }
1723- UbuntuNumberAnimation {
1724- target: slider
1725- property: "teaseOffset"
1726- to: 0
1727- duration: UbuntuAnimation.SleepyDuration
1728- }
1729- }
1730-
1731- foreground {
1732- children: [
1733- LocalComponents.Slider {
1734- id: slider
1735- anchors {
1736- bottom: parent.bottom
1737- bottomMargin: width / 2 - height / 2
1738- horizontalCenter: parent.horizontalCenter
1739- }
1740- rotation: -90
1741- offset: teaseOffset + dragOffset
1742- active: dragArea.dragging
1743-
1744- property real teaseOffset
1745- property real dragOffset: dragArea.useTouchY ? -dragArea.touchY : 0
1746-
1747- Behavior on dragOffset {
1748- id: offsetAnimation
1749- UbuntuNumberAnimation {}
1750- }
1751- }
1752- ]
1753- }
1754-
1755- DirectionalDragArea {
1756- id: dragArea
1757- direction: Direction.Upwards
1758- anchors {
1759- bottom: parent.bottom
1760- left: parent.left
1761- right: parent.right
1762- }
1763-
1764- property bool useTouchY
1765-
1766- onDraggingChanged: {
1767- if (!dragging) {
1768- if (slider.percent >= 0.85) {
1769- root.hide();
1770- } else if (slider.percent >= 0.15) {
1771- root.showError();
1772- }
1773- }
1774-
1775- // We use a separate vars here rather than just directly looking at
1776- // 'dragging' because we want to preserve our 'slider.offset'
1777- // value during the above percent check. Now that we made it,
1778- // we can have 'slider.offset' go back to zero.
1779- offsetAnimation.enabled = !dragging;
1780- useTouchY = dragging;
1781- }
1782- }
1783-}
1784
1785=== removed file 'qml/Tutorial/TutorialBottomFinish.qml'
1786--- qml/Tutorial/TutorialBottomFinish.qml 2015-07-15 15:07:19 +0000
1787+++ qml/Tutorial/TutorialBottomFinish.qml 1970-01-01 00:00:00 +0000
1788@@ -1,41 +0,0 @@
1789-/*
1790- * Copyright (C) 2014 Canonical, Ltd.
1791- *
1792- * This program is free software; you can redistribute it and/or modify
1793- * it under the terms of the GNU General Public License as published by
1794- * the Free Software Foundation; version 3.
1795- *
1796- * This program is distributed in the hope that it will be useful,
1797- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1798- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1799- * GNU General Public License for more details.
1800- *
1801- * You should have received a copy of the GNU General Public License
1802- * along with this program. If not, see <http://www.gnu.org/licenses/>.
1803- */
1804-
1805-import QtQuick 2.4
1806-import Ubuntu.Components 1.3
1807-import "." as LocalComponents
1808-
1809-TutorialPage {
1810- id: root
1811-
1812- title: i18n.tr("This action does different things for different apps")
1813- text: i18n.tr("Tap here to finish.")
1814- fullTextWidth: true
1815-
1816- foreground {
1817- children: [
1818- LocalComponents.Tick {
1819- objectName: "tick"
1820- anchors {
1821- horizontalCenter: parent.horizontalCenter
1822- top: parent.top
1823- topMargin: root.textBottom + units.gu(3)
1824- }
1825- onClicked: root.hide()
1826- }
1827- ]
1828- }
1829-}
1830
1831=== modified file 'qml/Tutorial/TutorialContent.qml'
1832--- qml/Tutorial/TutorialContent.qml 2015-08-25 07:25:26 +0000
1833+++ qml/Tutorial/TutorialContent.qml 2016-03-15 20:13:37 +0000
1834@@ -16,103 +16,273 @@
1835
1836 import QtQuick 2.4
1837 import Ubuntu.Components 1.3
1838+import AccountsService 0.1
1839+import Unity.Application 0.1
1840
1841 Item {
1842 id: root
1843
1844 property Item launcher
1845 property Item panel
1846-
1847- readonly property bool launcherEnabled: !running ||
1848- (!paused && tutorialLeft.shown)
1849- readonly property bool spreadEnabled: !running
1850- readonly property bool panelEnabled: !running
1851- readonly property bool panelContentEnabled: !running
1852- readonly property alias running: d.running
1853-
1854- property bool paused: false
1855- property real edgeSize
1856+ property Item stage
1857+ property string usageScenario
1858+ property bool paused
1859+ property bool keyboardVisible
1860+ property var lastInputTimestamp
1861+
1862+ readonly property bool launcherEnabled: !running
1863+ || tutorialLeftLoader.shown
1864+ || tutorialLeftLongLoader.shown
1865+ readonly property bool spreadEnabled: !running || tutorialRightLoader.shown
1866+ readonly property bool panelEnabled: !running || tutorialTopLoader.shown
1867+ readonly property bool running: tutorialLeftLoader.shown
1868+ || tutorialTopLoader.shown
1869+ || tutorialRightLoader.shown
1870+ || tutorialBottomLoader.shown
1871
1872 signal finished()
1873
1874 function finish() {
1875- d.stop();
1876 finished();
1877 }
1878
1879 ////
1880
1881- Component.onCompleted: {
1882- d.start();
1883- }
1884-
1885 QtObject {
1886 id: d
1887
1888- property bool running
1889-
1890- function stop() {
1891- running = false;
1892- }
1893-
1894- function start() {
1895- running = true;
1896- tutorialLeft.show();
1897- }
1898- }
1899-
1900- TutorialLeft {
1901- id: tutorialLeft
1902- objectName: "tutorialLeft"
1903- anchors.fill: parent
1904- launcher: root.launcher
1905- paused: !shown || root.paused
1906-
1907- onFinished: tutorialLeftFinish.show()
1908- }
1909-
1910- TutorialLeftFinish {
1911- id: tutorialLeftFinish
1912- objectName: "tutorialLeftFinish"
1913- anchors.fill: parent
1914- textXOffset: root.launcher.panelWidth
1915- paused: !shown || root.paused
1916- text: i18n.tr("Tap here to continue.")
1917-
1918- onFinished: {
1919- root.launcher.hide();
1920- tutorialRight.show();
1921- }
1922- }
1923-
1924- TutorialRight {
1925- id: tutorialRight
1926- objectName: "tutorialRight"
1927- anchors.fill: parent
1928- edgeSize: root.edgeSize
1929- panel: root.panel
1930- paused: !shown || root.paused
1931-
1932- onFinished: tutorialBottom.show()
1933- }
1934-
1935- TutorialBottom {
1936- id: tutorialBottom
1937- objectName: "tutorialBottom"
1938- anchors.fill: parent
1939- edgeSize: root.edgeSize
1940- paused: !shown || root.paused
1941-
1942- onFinished: tutorialBottomFinish.show()
1943- }
1944-
1945- TutorialBottomFinish {
1946- id: tutorialBottomFinish
1947- objectName: "tutorialBottomFinish"
1948- anchors.fill: parent
1949- backgroundFadesOut: true
1950- paused: !shown || root.paused
1951-
1952- onFinished: root.finish()
1953+ // We allow "" because it is briefly empty on startup, and we don't
1954+ // want to improperly skip any mobile tutorials.
1955+ property bool mobileScenario: root.usageScenario === "" ||
1956+ root.usageScenario === "phone" ||
1957+ root.usageScenario === "tablet"
1958+
1959+ property var focusedApp: ApplicationManager.focusedApplicationId
1960+ ? ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
1961+ : null
1962+
1963+ function haveShown(tutorialId) {
1964+ return AccountsService.demoEdgesCompleted.indexOf(tutorialId) != -1;
1965+ }
1966+
1967+ property bool endPointsFinished: tutorialRightLoader.skipped &&
1968+ tutorialBottomLoader.skipped
1969+ onEndPointsFinishedChanged: if (endPointsFinished) root.finish()
1970+ }
1971+
1972+ Loader {
1973+ id: tutorialLeftLoader
1974+ objectName: "tutorialLeftLoader"
1975+ anchors.fill: parent
1976+
1977+ readonly property bool skipped: !d.mobileScenario || d.haveShown("left")
1978+ readonly property bool shown: item && item.shown
1979+ active: !skipped || (item && item.visible)
1980+ onSkippedChanged: if (skipped && shown) item.hide()
1981+
1982+ sourceComponent: TutorialLeft {
1983+ id: tutorialLeft
1984+ objectName: "tutorialLeft"
1985+ anchors.fill: parent
1986+ launcher: root.launcher
1987+ hides: [launcher, panel.indicators]
1988+ paused: root.paused
1989+
1990+ isReady: !tutorialLeftLoader.skipped && !paused && !keyboardVisible
1991+
1992+ // Use an idle timer here, because when constructed, all our isReady variables will be false.
1993+ // Qml needs a moment to copy their values from Tutorial.qml. So we idle it and recheck.
1994+ Timer {
1995+ id: tutorialLeftTimer
1996+ interval: 0
1997+ onTriggered: if (tutorialLeft.isReady && !tutorialLeft.shown) tutorialLeft.show()
1998+ }
1999+
2000+ onIsReadyChanged: if (isReady && !shown) tutorialLeftTimer.start()
2001+ onFinished: AccountsService.markDemoEdgeCompleted("left")
2002+ }
2003+ }
2004+
2005+ Loader {
2006+ id: tutorialLeftLongLoader
2007+ objectName: "tutorialLeftLongLoader"
2008+ anchors.fill: parent
2009+
2010+ readonly property bool skipped: !d.mobileScenario || d.haveShown("left-long")
2011+ readonly property bool shown: item && item.shown
2012+ active: !skipped || (item && item.visible)
2013+ onSkippedChanged: if (skipped && shown) item.hide()
2014+
2015+ sourceComponent: TutorialLeftLong {
2016+ id: tutorialLeftLong
2017+ objectName: "tutorialLeftLong"
2018+ anchors.fill: parent
2019+ launcher: root.launcher
2020+ hides: [launcher, panel.indicators]
2021+ paused: root.paused
2022+
2023+ skipped: tutorialLeftLongLoader.skipped
2024+ isReady: tutorialLeftLoader.skipped && !skipped && !paused && !keyboardVisible &&
2025+ !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow
2026+
2027+ Timer {
2028+ id: tutorialLeftLongTimer
2029+ objectName: "tutorialLeftLongTimer"
2030+ interval: 5000
2031+ onTriggered: {
2032+ if (parent.isReady) {
2033+ if (!parent.shown) {
2034+ parent.show();
2035+ }
2036+ } else if (!parent.skipped) {
2037+ restart();
2038+ }
2039+ }
2040+ }
2041+
2042+ onIsReadyChanged: if (isReady && !shown) tutorialLeftLongTimer.start()
2043+ onFinished: AccountsService.markDemoEdgeCompleted("left-long")
2044+ }
2045+ }
2046+
2047+ Loader {
2048+ id: tutorialTopLoader
2049+ objectName: "tutorialTopLoader"
2050+ anchors.fill: parent
2051+
2052+ readonly property bool skipped: !d.mobileScenario || d.haveShown("top")
2053+ readonly property bool shown: item && item.shown
2054+ active: !skipped || (item && item.visible)
2055+ onSkippedChanged: if (skipped && shown) item.hide()
2056+
2057+ sourceComponent: TutorialTop {
2058+ id: tutorialTop
2059+ objectName: "tutorialTop"
2060+ anchors.fill: parent
2061+ panel: root.panel
2062+ hides: [launcher, panel.indicators]
2063+ paused: root.paused
2064+
2065+ skipped: tutorialTopLoader.skipped
2066+ isReady: tutorialLeftLongLoader.skipped && !skipped && !paused && !keyboardVisible &&
2067+ !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow
2068+
2069+ // We fire 30s after left edge tutorial, with at least 3s of inactivity
2070+
2071+ InactivityTimer {
2072+ id: tutorialTopInactivityTimer
2073+ lastInputTimestamp: root.lastInputTimestamp
2074+ page: parent
2075+ }
2076+
2077+ Timer {
2078+ id: tutorialTopTimer
2079+ objectName: "tutorialTopTimer"
2080+ interval: 27000
2081+ onTriggered: tutorialTopInactivityTimer.start()
2082+ }
2083+
2084+ onIsReadyChanged: if (isReady && !shown) tutorialTopTimer.start()
2085+ onFinished: AccountsService.markDemoEdgeCompleted("top")
2086+ }
2087+ }
2088+
2089+ Loader {
2090+ id: tutorialRightLoader
2091+ objectName: "tutorialRightLoader"
2092+ anchors.fill: parent
2093+
2094+ readonly property bool skipped: d.haveShown("right")
2095+ readonly property bool shown: item && item.shown
2096+ active: !skipped || (item && item.visible)
2097+ onSkippedChanged: if (skipped && shown) item.hide()
2098+
2099+ sourceComponent: TutorialRight {
2100+ id: tutorialRight
2101+ objectName: "tutorialRight"
2102+ anchors.fill: parent
2103+ stage: root.stage
2104+ usageScenario: root.usageScenario
2105+ hides: [launcher, panel.indicators]
2106+ paused: root.paused
2107+
2108+ skipped: tutorialRightLoader.skipped
2109+ isReady: tutorialTopLoader.skipped && !skipped && !paused && !keyboardVisible &&
2110+ !tutorialBottomLoader.shown && !tutorialBottomLoader.mightShow &&
2111+ ApplicationManager.count >= 3
2112+
2113+ InactivityTimer {
2114+ id: tutorialRightInactivityTimer
2115+ objectName: "tutorialRightInactivityTimer"
2116+ lastInputTimestamp: root.lastInputTimestamp
2117+ page: parent
2118+ }
2119+
2120+ Connections {
2121+ target: d
2122+ onFocusedAppChanged: {
2123+ if (tutorialRight.isReady && !tutorialRight.shown && d.focusedApp
2124+ && d.focusedApp.state === ApplicationInfoInterface.Starting) {
2125+ tutorialRight.show();
2126+ }
2127+ }
2128+ }
2129+
2130+ onIsReadyChanged: if (isReady && !shown) tutorialRightInactivityTimer.start()
2131+ onFinished: AccountsService.markDemoEdgeCompleted("right")
2132+ }
2133+ }
2134+
2135+ Loader {
2136+ id: tutorialBottomLoader
2137+ objectName: "tutorialBottomLoader"
2138+ anchors.fill: parent
2139+
2140+ // See TutorialBottom.qml for an explanation of why we only support
2141+ // certain apps.
2142+ readonly property var supportedApps: ["address-book-app",
2143+ "com.ubuntu.calculator_calculator",
2144+ "dialer-app",
2145+ "messaging-app"]
2146+ readonly property bool skipped: {
2147+ if (!d.mobileScenario) {
2148+ return true;
2149+ }
2150+ for (var i = 0; i < supportedApps.length; i++) {
2151+ if (!d.haveShown("bottom-" + supportedApps[i])) {
2152+ return false;
2153+ }
2154+ }
2155+ return true;
2156+ }
2157+ readonly property bool shown: item && item.shown
2158+ readonly property bool haveShownFocusedApp: d.focusedApp &&
2159+ d.haveShown("bottom-" + d.focusedApp.appId)
2160+ readonly property bool mightShow: !skipped && d.focusedApp &&
2161+ supportedApps.indexOf(d.focusedApp.appId) !== -1 &&
2162+ !haveShownFocusedApp
2163+ active: !skipped || (item && item.visible)
2164+ onHaveShownFocusedAppChanged: if (haveShownFocusedApp && shown) hide()
2165+ onSkippedChanged: if (skipped && shown) item.hide()
2166+
2167+ sourceComponent: TutorialBottom {
2168+ id: tutorialBottom
2169+ objectName: "tutorialBottom"
2170+ anchors.fill: parent
2171+ hides: [launcher, panel.indicators]
2172+ paused: root.paused
2173+ usageScenario: root.usageScenario
2174+ stage: root.stage
2175+ application: d.focusedApp
2176+
2177+ skipped: tutorialBottomLoader.skipped
2178+ isReady: !tutorialBottomLoader.skipped && !paused && !keyboardVisible &&
2179+ !tutorialTopLoader.shown && !tutorialRightLoader.shown &&
2180+ tutorialBottomLoader.mightShow &&
2181+ d.focusedApp.state === ApplicationInfoInterface.Running
2182+
2183+ onIsReadyChanged: if (isReady && !shown) show()
2184+ onFinished: AccountsService.markDemoEdgeCompleted("bottom-" + d.focusedApp.appId)
2185+ }
2186 }
2187 }
2188
2189=== modified file 'qml/Tutorial/TutorialLeft.qml'
2190--- qml/Tutorial/TutorialLeft.qml 2015-07-21 14:38:35 +0000
2191+++ qml/Tutorial/TutorialLeft.qml 2016-03-15 20:13:37 +0000
2192@@ -1,5 +1,5 @@
2193 /*
2194- * Copyright (C) 2014,2015 Canonical, Ltd.
2195+ * Copyright (C) 2015 Canonical, Ltd.
2196 *
2197 * This program is free software; you can redistribute it and/or modify
2198 * it under the terms of the GNU General Public License as published by
2199@@ -23,79 +23,32 @@
2200
2201 property var launcher
2202
2203- title: i18n.tr("Open the launcher")
2204- text: i18n.tr("Short swipe from the left edge.")
2205-
2206- textXOffset: root.launcher.x + root.launcher.visibleWidth
2207-
2208- Connections {
2209- target: root.launcher
2210-
2211- onStateChanged: {
2212- if (root.launcher.state === "visible") {
2213- finishTimer.start();
2214- }
2215- }
2216-
2217- onDash: {
2218- finishTimer.stop();
2219- root.showError();
2220- root.launcher.hide();
2221- }
2222- }
2223-
2224- SequentialAnimation {
2225- id: teaseAnimation
2226- objectName: "teaseAnimation"
2227- paused: running && root.paused
2228- running: !slider.active && root.launcher.visibleWidth === 0 && root.shown
2229- loops: Animation.Infinite
2230- property real bounce: 0
2231- readonly property real maxBounce: units.gu(2)
2232-
2233- UbuntuNumberAnimation {
2234- target: teaseAnimation
2235- property: "bounce"
2236- to: teaseAnimation.maxBounce
2237- duration: UbuntuAnimation.SleepyDuration
2238- }
2239- UbuntuNumberAnimation {
2240- target: teaseAnimation
2241- property: "bounce"
2242- to: 0
2243- duration: UbuntuAnimation.SleepyDuration
2244- }
2245- }
2246-
2247- Binding {
2248- target: root.launcher
2249- when: root.shown
2250- property: "x"
2251- value: Math.min(root.launcher.panelWidth - root.launcher.visibleWidth, teaseAnimation.bounce)
2252- }
2253-
2254- Timer {
2255- id: finishTimer
2256- interval: 1
2257- onTriggered: {
2258- root.hide();
2259- root.launcher.x = 0; // make sure to reset launcher before we go
2260- }
2261- }
2262-
2263- foreground {
2264- children: [
2265- LocalComponents.Slider {
2266- id: slider
2267- anchors {
2268- left: parent.left
2269- top: parent.top
2270- topMargin: root.textBottom + units.gu(3)
2271- }
2272- offset: root.launcher.x + root.launcher.visibleWidth + root.launcher.progress
2273- active: root.launcher.dragging
2274- shortSwipe: true
2275- }
2276- ]
2277+ opacityOverride: 1 - launcher.visibleWidth / launcher.panelWidth
2278+
2279+ mouseArea {
2280+ anchors.leftMargin: launcher.dragAreaWidth
2281+ }
2282+
2283+ background {
2284+ sourceSize.height: 1916
2285+ sourceSize.width: 1080
2286+ source: Qt.resolvedUrl("graphics/background1.png")
2287+ mirror: true
2288+ }
2289+
2290+ arrow {
2291+ anchors.left: root.left
2292+ anchors.leftMargin: units.gu(2)
2293+ anchors.verticalCenter: root.verticalCenter
2294+ rotation: 180
2295+ }
2296+
2297+ label {
2298+ text: i18n.tr("Swipe from the left edge to open the launcher")
2299+ anchors.left: arrow.right
2300+ anchors.leftMargin: units.gu(3)
2301+ anchors.right: root.right
2302+ anchors.rightMargin: units.gu(4)
2303+ anchors.verticalCenter: arrow.verticalCenter
2304 }
2305 }
2306
2307=== removed file 'qml/Tutorial/TutorialLeftFinish.qml'
2308--- qml/Tutorial/TutorialLeftFinish.qml 2015-07-15 15:07:19 +0000
2309+++ qml/Tutorial/TutorialLeftFinish.qml 1970-01-01 00:00:00 +0000
2310@@ -1,41 +0,0 @@
2311-/*
2312- * Copyright (C) 2014 Canonical, Ltd.
2313- *
2314- * This program is free software; you can redistribute it and/or modify
2315- * it under the terms of the GNU General Public License as published by
2316- * the Free Software Foundation; version 3.
2317- *
2318- * This program is distributed in the hope that it will be useful,
2319- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2320- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2321- * GNU General Public License for more details.
2322- *
2323- * You should have received a copy of the GNU General Public License
2324- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2325- */
2326-
2327-import QtQuick 2.4
2328-import Ubuntu.Components 1.3
2329-import "." as LocalComponents
2330-
2331-TutorialPage {
2332- id: root
2333-
2334- title: i18n.tr("These are the shortcuts to favorite apps")
2335- text: i18n.tr("Tap here to continue.")
2336- fullTextWidth: true
2337-
2338- foreground {
2339- children: [
2340- LocalComponents.Tick {
2341- objectName: "tick"
2342- anchors {
2343- horizontalCenter: parent.horizontalCenter
2344- top: parent.top
2345- topMargin: root.textBottom + units.gu(3)
2346- }
2347- onClicked: root.hide()
2348- }
2349- ]
2350- }
2351-}
2352
2353=== added file 'qml/Tutorial/TutorialLeftLong.qml'
2354--- qml/Tutorial/TutorialLeftLong.qml 1970-01-01 00:00:00 +0000
2355+++ qml/Tutorial/TutorialLeftLong.qml 2016-03-15 20:13:37 +0000
2356@@ -0,0 +1,54 @@
2357+/*
2358+ * Copyright (C) 2016 Canonical, Ltd.
2359+ *
2360+ * This program is free software; you can redistribute it and/or modify
2361+ * it under the terms of the GNU General Public License as published by
2362+ * the Free Software Foundation; version 3.
2363+ *
2364+ * This program is distributed in the hope that it will be useful,
2365+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2366+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2367+ * GNU General Public License for more details.
2368+ *
2369+ * You should have received a copy of the GNU General Public License
2370+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2371+ */
2372+
2373+import QtQuick 2.4
2374+import Ubuntu.Components 1.3
2375+import "." as LocalComponents
2376+
2377+TutorialPage {
2378+ id: root
2379+
2380+ property var launcher
2381+
2382+ opacityOverride: 1 - launcher.dragDistance / launcher.minimizeDistance
2383+
2384+ mouseArea {
2385+ anchors.leftMargin: launcher.dragAreaWidth
2386+ }
2387+
2388+ background {
2389+ sourceSize.height: 1916
2390+ sourceSize.width: 1080
2391+ source: Qt.resolvedUrl("graphics/background1.png")
2392+ mirror: true
2393+ }
2394+
2395+ arrow {
2396+ anchors.left: root.left
2397+ anchors.leftMargin: units.gu(2)
2398+ anchors.verticalCenter: root.verticalCenter
2399+ rotation: 180
2400+ }
2401+
2402+ label {
2403+ text: i18n.tr("Long swipe from the left edge to open the Today scope")
2404+ anchors.left: arrow.right
2405+ anchors.leftMargin: units.gu(3)
2406+ anchors.right: root.right
2407+ anchors.rightMargin: units.gu(4)
2408+ anchors.verticalCenter: arrow.verticalCenter
2409+ }
2410+}
2411
2412=== modified file 'qml/Tutorial/TutorialPage.qml'
2413--- qml/Tutorial/TutorialPage.qml 2015-07-15 15:07:19 +0000
2414+++ qml/Tutorial/TutorialPage.qml 2016-03-15 20:13:37 +0000
2415@@ -21,225 +21,101 @@
2416 Showable {
2417 id: root
2418
2419- // This is the header displayed, like "Right edge"
2420- property alias title: titleLabel.text
2421-
2422- // This is the block of text displayed below the header
2423- property alias text: textLabel.text
2424-
2425- // Whether animations are paused
2426+ property alias arrow: arrow
2427+ property alias label: label
2428+ property alias background: background
2429+ property alias mouseArea: mouseArea
2430+ property real opacityOverride: 1
2431 property bool paused
2432-
2433- // Whether to give the text the full width that the title has
2434- property bool fullTextWidth
2435-
2436- // Whether whole page (background + foreground) or just the foreground fades in
2437- property bool backgroundFadesIn: false
2438-
2439- // Whether whole page (background + foreground) or just the foreground fades out
2440- property bool backgroundFadesOut: false
2441-
2442- // The foreground Item, add children to it that you want to fade in
2443- property alias foreground: foregroundExtra
2444-
2445- // The text label bottom, so you can position elements relative to it
2446- readonly property real textBottom: Math.max(textLabel.y + textLabel.height, errorTextLabel.y + errorTextLabel.height)
2447-
2448- // The MouseArea that eats events (so you can adjust size as you will)
2449- property alias mouseArea: mouseArea
2450-
2451- // X/Y offsets for text
2452- property real textXOffset: 0
2453- property real textYOffset: 0
2454-
2455- // Foreground text opacity
2456- property real textOpacity: 1
2457+ property bool skipped
2458+ property bool isReady
2459
2460 signal finished()
2461
2462- function showError() {
2463- errorTimer.start();
2464- }
2465-
2466 ////
2467
2468+ QtObject {
2469+ id: d
2470+ property bool showOnUnpause
2471+ }
2472+
2473 visible: false
2474 shown: false
2475
2476- property real _foregroundHideOpacity
2477+ opacity: Math.max(Math.min(_showOpacity, opacityOverride), 0)
2478+ onOpacityOverrideChanged: {
2479+ if (opacityOverride <= 0) {
2480+ d.showOnUnpause = false;
2481+ hide();
2482+ }
2483+ }
2484+ property real _showOpacity: 0
2485+
2486+ onPausedChanged: {
2487+ if (paused && shown) {
2488+ d.showOnUnpause = true;
2489+ hide();
2490+ } else if (!paused && d.showOnUnpause) {
2491+ if (isReady) {
2492+ show();
2493+ } else if (hideAnimation.running) {
2494+ hideAnimation.stop();
2495+ }
2496+ d.showOnUnpause = false;
2497+ }
2498+ }
2499
2500 showAnimation: StandardAnimation {
2501- property: root.backgroundFadesIn ? "opacity" : "_foregroundHideOpacity"
2502+ property: "_showOpacity"
2503 from: 0
2504 to: 1
2505- duration: root.backgroundFadesIn ? UbuntuAnimation.SleepyDuration : UbuntuAnimation.BriskDuration
2506+ duration: UbuntuAnimation.SleepyDuration
2507 onStarted: root.visible = true
2508 }
2509
2510 hideAnimation: StandardAnimation {
2511- property: root.backgroundFadesOut ? "opacity" : "_foregroundHideOpacity"
2512+ property: "_showOpacity"
2513 to: 0
2514 duration: UbuntuAnimation.BriskDuration
2515 onStopped: {
2516 root.visible = false;
2517- root.finished();
2518- }
2519- }
2520-
2521- QtObject {
2522- id: d
2523-
2524- readonly property real sideMargin: units.gu(5.5)
2525- readonly property real verticalOffset: -units.gu(9)
2526- readonly property real textXOffset: Math.max(0, root.textXOffset - sideMargin + units.gu(2))
2527-
2528- property real fadeInOffset: {
2529- if (showAnimation.running) {
2530- var opacity = root[root.showAnimation.property]
2531- return (1 - opacity) * units.gu(3);
2532- } else {
2533- return 0;
2534+ if (!d.showOnUnpause) {
2535+ root.finished();
2536 }
2537 }
2538 }
2539
2540- Timer {
2541- id: errorTimer
2542- interval: 3500
2543- }
2544-
2545 MouseArea { // eat any errant presses
2546 id: mouseArea
2547 anchors.fill: parent
2548 }
2549
2550- Rectangle {
2551- anchors.fill: parent
2552- color: "black"
2553- opacity: 0.82
2554- }
2555-
2556- Item {
2557- id: foreground
2558- anchors.fill: parent
2559- opacity: root._foregroundHideOpacity
2560-
2561- Item {
2562- anchors.fill: parent
2563- opacity: root.textOpacity
2564-
2565- Label {
2566- id: titleLabel
2567- anchors {
2568- top: parent.verticalCenter
2569- topMargin: d.verticalOffset + root.textYOffset
2570- left: parent.left
2571- leftMargin: d.sideMargin + d.textXOffset
2572- }
2573- width: parent.width - d.sideMargin * 2
2574- horizontalAlignment: Text.AlignLeft
2575- wrapMode: Text.Wrap
2576- font.weight: Font.Light
2577- font.pixelSize: units.gu(3.5)
2578- }
2579-
2580- Label {
2581- id: textLabel
2582- anchors {
2583- top: titleLabel.bottom
2584- topMargin: units.gu(2)
2585- left: parent.left
2586- leftMargin: d.sideMargin + d.textXOffset
2587- }
2588- width: (parent.width - d.sideMargin * 2) * (fullTextWidth ? 1 : 0.66)
2589- horizontalAlignment: Text.AlignLeft
2590- wrapMode: Text.Wrap
2591- font.weight: Font.Light
2592- font.pixelSize: units.gu(2.5)
2593- }
2594-
2595- // We use two separate labels like this rather than just changing
2596- // the text of the above labels because we want to know where to place
2597- // sliders (via root.textBottom) without having that place change
2598- // as the text changes length.
2599- Label {
2600- id: errorTitleLabel
2601- objectName: "errorTitleLabel"
2602- anchors {
2603- top: titleLabel.top
2604- left: titleLabel.left
2605- }
2606- width: titleLabel.width
2607- horizontalAlignment: titleLabel.horizontalAlignment
2608- wrapMode: titleLabel.wrapMode
2609- font.weight: titleLabel.font.weight
2610- font.pixelSize: titleLabel.font.pixelSize
2611- opacity: 0
2612- text: i18n.tr("You almost got it!")
2613- }
2614-
2615- Label {
2616- id: errorTextLabel
2617- objectName: "errorTextLabel"
2618- anchors {
2619- top: errorTitleLabel.bottom
2620- topMargin: textLabel.anchors.topMargin
2621- left: textLabel.left
2622- }
2623- width: textLabel.width
2624- horizontalAlignment: textLabel.horizontalAlignment
2625- wrapMode: textLabel.wrapMode
2626- font.weight: textLabel.font.weight
2627- font.pixelSize: textLabel.font.pixelSize
2628- opacity: 0
2629- text: i18n.tr("Try again.")
2630- }
2631- }
2632-
2633- // A place for subclasses to add extra widgets
2634- Item {
2635- id: foregroundExtra
2636- anchors.fill: parent
2637- }
2638- }
2639-
2640- states: State {
2641- name: "errorState"
2642- when: errorTimer.running
2643- PropertyChanges { target: titleLabel; opacity: 0 }
2644- PropertyChanges { target: textLabel; opacity: 0 }
2645- PropertyChanges { target: errorTitleLabel; opacity: 1 }
2646- PropertyChanges { target: errorTextLabel; opacity: 1 }
2647- }
2648-
2649- transitions: Transition {
2650- to: "errorState"
2651- reversible: true
2652- SequentialAnimation {
2653- ParallelAnimation {
2654- StandardAnimation {
2655- target: titleLabel
2656- property: "opacity"
2657- duration: UbuntuAnimation.BriskDuration
2658- }
2659- StandardAnimation {
2660- target: textLabel
2661- property: "opacity"
2662- duration: UbuntuAnimation.BriskDuration
2663- }
2664- }
2665- ParallelAnimation {
2666- StandardAnimation {
2667- target: errorTitleLabel
2668- property: "opacity"
2669- duration: UbuntuAnimation.BriskDuration
2670- }
2671- StandardAnimation {
2672- target: errorTextLabel
2673- property: "opacity"
2674- duration: UbuntuAnimation.BriskDuration
2675- }
2676- }
2677- }
2678+ Image {
2679+ id: background
2680+ // Use x/y/height/width instead of anchors so that we don't adjust
2681+ // the image if the OSK appears.
2682+ x: 0
2683+ y: 0
2684+ height: root.height
2685+ width: root.width
2686+ fillMode: Image.PreserveAspectCrop
2687+ }
2688+
2689+ Image {
2690+ id: arrow
2691+ width: units.gu(1.5)
2692+ source: Qt.resolvedUrl("graphics/arrow.svg")
2693+ fillMode: Image.PreserveAspectFit
2694+ mipmap: true
2695+ }
2696+
2697+ Label {
2698+ id: label
2699+ objectName: "tutorialLabel"
2700+ fontSize: "large"
2701+ font.weight: Font.Light
2702+ color: "#333333"
2703+ wrapMode: Text.Wrap
2704+ lineHeight: 1.2
2705 }
2706 }
2707
2708=== added file 'qml/Tutorial/TutorialRight.qml'
2709--- qml/Tutorial/TutorialRight.qml 1970-01-01 00:00:00 +0000
2710+++ qml/Tutorial/TutorialRight.qml 2016-03-15 20:13:37 +0000
2711@@ -0,0 +1,61 @@
2712+/*
2713+ * Copyright (C) 2015 Canonical, Ltd.
2714+ *
2715+ * This program is free software; you can redistribute it and/or modify
2716+ * it under the terms of the GNU General Public License as published by
2717+ * the Free Software Foundation; version 3.
2718+ *
2719+ * This program is distributed in the hope that it will be useful,
2720+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2721+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2722+ * GNU General Public License for more details.
2723+ *
2724+ * You should have received a copy of the GNU General Public License
2725+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2726+ */
2727+
2728+import QtQuick 2.4
2729+import Ubuntu.Components 1.3
2730+
2731+TutorialPage {
2732+ id: root
2733+
2734+ property var stage
2735+ property string usageScenario
2736+
2737+ // When on phone or tablet, fade out as the drag progresses
2738+ opacityOverride: usageScenario === "desktop" ? 1 : 1 - stage.dragProgress * 2
2739+
2740+ // Else on desktop, fade out when the spread is shown
2741+ Connections {
2742+ target: usageScenario === "desktop" ? stage : null
2743+ ignoreUnknownSignals: true
2744+ onSpreadShownChanged: if (stage.spreadShown && root.shown) root.hide()
2745+ }
2746+
2747+ mouseArea {
2748+ anchors.rightMargin: stage.dragAreaWidth
2749+ }
2750+
2751+ background {
2752+ sourceSize.height: 1916
2753+ sourceSize.width: 1080
2754+ source: Qt.resolvedUrl("graphics/background1.png")
2755+ }
2756+
2757+ arrow {
2758+ anchors.right: root.right
2759+ anchors.rightMargin: units.gu(2)
2760+ anchors.verticalCenter: root.verticalCenter
2761+ }
2762+
2763+ label {
2764+ text: root.usageScenario === "desktop" ?
2765+ i18n.tr("Hover your mouse on the right edge to view your open apps") :
2766+ i18n.tr("Short or long swipe from the right edge to view your open apps")
2767+ anchors.right: arrow.left
2768+ anchors.rightMargin: units.gu(2) - (label.width - label.contentWidth)
2769+ anchors.verticalCenter: arrow.verticalCenter
2770+ width: Math.min(units.gu(40), arrow.x - units.gu(4))
2771+ }
2772+}
2773
2774=== removed file 'qml/Tutorial/TutorialRight.qml'
2775--- qml/Tutorial/TutorialRight.qml 2015-07-15 15:07:19 +0000
2776+++ qml/Tutorial/TutorialRight.qml 1970-01-01 00:00:00 +0000
2777@@ -1,223 +0,0 @@
2778-/*
2779- * Copyright (C) 2014 Canonical, Ltd.
2780- *
2781- * This program is free software; you can redistribute it and/or modify
2782- * it under the terms of the GNU General Public License as published by
2783- * the Free Software Foundation; version 3.
2784- *
2785- * This program is distributed in the hope that it will be useful,
2786- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2787- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2788- * GNU General Public License for more details.
2789- *
2790- * You should have received a copy of the GNU General Public License
2791- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2792- */
2793-
2794-import QtQuick 2.4
2795-import Ubuntu.Components 1.3
2796-import Ubuntu.Gestures 0.1
2797-import Unity.Application 0.1
2798-import "../Components"
2799-import "../Stages"
2800-import "." as LocalComponents
2801-
2802-TutorialPage {
2803- id: root
2804-
2805- property var panel
2806- property alias edgeSize: stage.dragAreaWidth
2807-
2808- title: i18n.tr("To view open apps")
2809- text: i18n.tr("Long swipe from the right edge.")
2810-
2811- textOpacity: 1 - slider.percent
2812-
2813- SequentialAnimation {
2814- id: teaseAnimation
2815- paused: running && root.paused
2816- running: !stage.dragging && stage.dragProgress === 0
2817- loops: Animation.Infinite
2818-
2819- UbuntuNumberAnimation {
2820- target: stage
2821- property: "x"
2822- to: -units.gu(2)
2823- duration: UbuntuAnimation.SleepyDuration
2824- }
2825- UbuntuNumberAnimation {
2826- target: stage
2827- property: "x"
2828- to: 0
2829- duration: UbuntuAnimation.SleepyDuration
2830- }
2831- }
2832-
2833- foreground {
2834- children: [
2835- LocalComponents.Slider {
2836- id: slider
2837- anchors {
2838- right: parent.right
2839- top: parent.top
2840- topMargin: root.textBottom + units.gu(3)
2841- }
2842- rotation: 180
2843- offset: stage.dragProgress - stage.x
2844- active: stage.dragging
2845- },
2846-
2847- // Just assume PhoneStage for now. The tablet version of the right-edge
2848- // tutorial is still being spec'd by the design team.
2849- PhoneStage {
2850- id: stage
2851- objectName: "stage"
2852- anchors.top: parent.top
2853- width: parent.width
2854- height: parent.height
2855- applicationManager: fakeAppManager
2856- color: "transparent"
2857- interactive: false
2858- altTabEnabled: false
2859- focusFirstApp: false
2860- startScale: 0.8
2861- endScale: 0.6
2862- dragAreaOverlap: -x
2863-
2864- onOpened: {
2865- overlay.show();
2866- root.textOpacity = 0;
2867- slider.visible = false;
2868- }
2869-
2870- onDraggingChanged: {
2871- if (!dragging) {
2872- if (!overlay.shown) {
2873- root.showError();
2874- }
2875- teaseAnimation.complete();
2876- }
2877- }
2878- },
2879-
2880- Showable {
2881- id: overlay
2882- objectName: "overlay"
2883- anchors.fill: parent
2884-
2885- opacity: 0
2886- shown: false
2887- showAnimation: UbuntuNumberAnimation { property: "opacity"; to: 1 }
2888-
2889- Label {
2890- anchors.top: parent.top
2891- anchors.topMargin: root.panel.panelHeight + units.gu(2)
2892- anchors.left: parent.left
2893- anchors.leftMargin: units.gu(2)
2894- anchors.right: parent.right
2895- anchors.rightMargin: units.gu(2)
2896- wrapMode: Text.Wrap
2897- horizontalAlignment: Text.AlignHCenter
2898- fontSize: "large"
2899- text: i18n.tr("View all your running tasks.")
2900- }
2901-
2902- LocalComponents.Tick {
2903- objectName: "tick"
2904- anchors.bottom: bottomOverlayText.top
2905- anchors.bottomMargin: units.gu(1)
2906- anchors.horizontalCenter: bottomOverlayText.horizontalCenter
2907- onClicked: root.hide()
2908- }
2909-
2910- Label {
2911- id: bottomOverlayText
2912- anchors.bottom: parent.bottom
2913- anchors.bottomMargin: units.gu(2)
2914- anchors.left: parent.left
2915- anchors.leftMargin: units.gu(2)
2916- anchors.right: parent.right
2917- anchors.rightMargin: units.gu(2)
2918- wrapMode: Text.Wrap
2919- horizontalAlignment: Text.AlignHCenter
2920- fontSize: "small"
2921- text: i18n.tr("Tap here to continue.")
2922- }
2923- }
2924- ]
2925- }
2926-
2927- ListModel {
2928- id: fakeAppManager
2929-
2930- readonly property string focusedApplicationId: "facebook"
2931-
2932- function focusApplication(appId) {}
2933- function requestFocusApplication(appId) {}
2934- function findApplication(appId) {return null;}
2935-
2936- signal applicationAdded(string appId)
2937- signal applicationRemoved(string appId)
2938- signal focusRequested(string appId)
2939-
2940- ListElement {
2941- appId: "facebook"
2942- fullscreen: false
2943- name: ""
2944- icon: ""
2945- state: ApplicationInfoInterface.Stopped
2946- splashTitle: ""
2947- splashImage: ""
2948- splashShowHeader: false
2949- splashColor: "transparent"
2950- splashColorHeader: "transparent"
2951- splashColorFooter: "transparent"
2952- defaultScreenshot: "../Tutorial/graphics/facebook.png"
2953- }
2954-
2955- ListElement {
2956- appId: "camera"
2957- fullscreen: false
2958- name: ""
2959- icon: ""
2960- state: ApplicationInfoInterface.Stopped
2961- splashTitle: ""
2962- splashImage: ""
2963- splashShowHeader: false
2964- splashColor: "transparent"
2965- splashColorHeader: "transparent"
2966- splashColorFooter: "transparent"
2967- defaultScreenshot: "../Tutorial/graphics/camera.png"
2968- }
2969-
2970- ListElement {
2971- appId: "gallery"
2972- fullscreen: false
2973- name: ""
2974- icon: ""
2975- state: ApplicationInfoInterface.Stopped
2976- splashTitle: ""
2977- splashImage: ""
2978- splashShowHeader: false
2979- splashColor: "transparent"
2980- splashColorHeader: "transparent"
2981- splashColorFooter: "transparent"
2982- defaultScreenshot: "../Tutorial/graphics/gallery.png"
2983- }
2984-
2985- ListElement {
2986- appId: "dialer"
2987- fullscreen: false
2988- name: ""
2989- icon: ""
2990- state: ApplicationInfoInterface.Stopped
2991- splashTitle: ""
2992- splashImage: ""
2993- splashShowHeader: false
2994- splashColor: "transparent"
2995- splashColorHeader: "transparent"
2996- splashColorFooter: "transparent"
2997- defaultScreenshot: "../Tutorial/graphics/dialer.png"
2998- }
2999- }
3000-}
3001
3002=== added file 'qml/Tutorial/TutorialTop.qml'
3003--- qml/Tutorial/TutorialTop.qml 1970-01-01 00:00:00 +0000
3004+++ qml/Tutorial/TutorialTop.qml 2016-03-15 20:13:37 +0000
3005@@ -0,0 +1,61 @@
3006+/*
3007+ * Copyright (C) 2015 Canonical, Ltd.
3008+ *
3009+ * This program is free software; you can redistribute it and/or modify
3010+ * it under the terms of the GNU General Public License as published by
3011+ * the Free Software Foundation; version 3.
3012+ *
3013+ * This program is distributed in the hope that it will be useful,
3014+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3015+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3016+ * GNU General Public License for more details.
3017+ *
3018+ * You should have received a copy of the GNU General Public License
3019+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
3020+ */
3021+
3022+import QtQuick 2.4
3023+import Ubuntu.Components 1.3
3024+import "." as LocalComponents
3025+
3026+TutorialPage {
3027+ id: root
3028+
3029+ property var panel
3030+
3031+ opacityOverride: 1 - panel.indicators.unitProgress
3032+
3033+ QtObject {
3034+ id: d
3035+ readonly property bool landscape: root.width > units.gu(50)
3036+ readonly property real columnWidth: landscape ? panel.indicators.width : root.width
3037+ }
3038+
3039+ mouseArea {
3040+ anchors.topMargin: panel.indicators.minimizedPanelHeight
3041+ }
3042+
3043+ background {
3044+ sourceSize.height: 1916
3045+ sourceSize.width: 1080
3046+ source: Qt.resolvedUrl("graphics/background2.png")
3047+ }
3048+
3049+ arrow {
3050+ anchors.top: root.top
3051+ anchors.topMargin: units.gu(4)
3052+ anchors.horizontalCenter: root.right
3053+ anchors.horizontalCenterOffset: - d.columnWidth / 2
3054+ rotation: -90
3055+ }
3056+
3057+ label {
3058+ text: d.landscape ? i18n.tr("Swipe from the top right edge to open the notification bar")
3059+ : i18n.tr("Swipe from the top edge to open the notification bar")
3060+ anchors.top: arrow.bottom
3061+ anchors.topMargin: units.gu(3)
3062+ anchors.horizontalCenter: arrow.horizontalCenter
3063+ anchors.horizontalCenterOffset: (label.width - label.contentWidth) / 2
3064+ width: d.columnWidth - units.gu(8)
3065+ }
3066+}
3067
3068=== added file 'qml/Tutorial/graphics/arrow.svg'
3069--- qml/Tutorial/graphics/arrow.svg 1970-01-01 00:00:00 +0000
3070+++ qml/Tutorial/graphics/arrow.svg 2016-03-15 20:13:37 +0000
3071@@ -0,0 +1,19 @@
3072+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
3073+<svg width="35px" height="106px" viewBox="0 0 35 106" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3074+ <!-- Generator: Sketch 3.3.3 (12072) - http://www.bohemiancoding.com/sketch -->
3075+ <title>left swipe arrow</title>
3076+ <desc>Created with Sketch.</desc>
3077+ <defs></defs>
3078+ <g id="Final-design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
3079+ <g id="1.Left-swipe" sketch:type="MSArtboardGroup" transform="translate(-54.000000, -906.000000)">
3080+ <g id="left-swipe-arrow" sketch:type="MSLayerGroup" transform="translate(15.000000, 903.000000)">
3081+ <g id="layer1" transform="translate(0.857146, 0.494959)" sketch:type="MSShapeGroup">
3082+ <g id="g4216" transform="translate(0.952384, 0.831650)">
3083+ <path d="M38.0127338,5.94292186 C40.8696258,9.70328846 43.6961579,13.5492607 46.4521869,17.5776877 C50.0756129,22.8738077 53.4767719,28.2917937 56.6611719,33.8315937 C60.6031619,40.9214757 64.3797399,47.5658927 67.7217189,54.6714377 C64.3797399,61.7769828 60.6031619,68.4213998 56.6611719,75.5112818 C53.4767719,81.0510808 50.0756129,86.4690678 46.4521869,91.7651878 C43.6961579,95.7936138 40.8696258,99.6395938 38.0127338,103.399951 L38.0127338,107.669481 C42.0030779,102.508161 45.9748129,97.3405748 49.5537499,92.0679218 C54.5609019,84.6937758 59.0395839,77.5443828 62.9990629,70.6226098 C66.5019159,64.4983168 69.0866949,59.3452977 71.2158589,54.6733907 L69.4678129,54.6713907 L71.2158589,54.6693907 C69.0866949,49.9975777 66.5019159,44.8445587 62.9990629,38.7202657 C59.0395839,31.7984927 54.5609019,24.6490997 49.5537499,17.2749527 C45.9748129,12.0022997 42.0030779,6.83471186 38.0127338,1.67339065 L38.0127338,5.94292186 Z" id="left-swipe-arrow" fill="#6C0D52" transform="translate(54.614296, 54.671436) scale(-1, 1) translate(-54.614296, -54.671436) "></path>
3084+ <rect id="rect4782-01" transform="translate(54.190469, 54.673389) rotate(90.000000) translate(-54.190469, -54.673389) " x="0.190470662" y="0.67339065" width="107.999997" height="107.999997"></rect>
3085+ </g>
3086+ </g>
3087+ </g>
3088+ </g>
3089+ </g>
3090+</svg>
3091\ No newline at end of file
3092
3093=== added file 'qml/Tutorial/graphics/background1.png'
3094Binary files qml/Tutorial/graphics/background1.png 1970-01-01 00:00:00 +0000 and qml/Tutorial/graphics/background1.png 2016-03-15 20:13:37 +0000 differ
3095=== added file 'qml/Tutorial/graphics/background2.png'
3096Binary files qml/Tutorial/graphics/background2.png 1970-01-01 00:00:00 +0000 and qml/Tutorial/graphics/background2.png 2016-03-15 20:13:37 +0000 differ
3097=== removed file 'qml/Tutorial/graphics/camera.png'
3098Binary files qml/Tutorial/graphics/camera.png 2015-01-09 21:56:17 +0000 and qml/Tutorial/graphics/camera.png 1970-01-01 00:00:00 +0000 differ
3099=== removed file 'qml/Tutorial/graphics/chevron.png'
3100Binary files qml/Tutorial/graphics/chevron.png 2014-12-18 23:32:42 +0000 and qml/Tutorial/graphics/chevron.png 1970-01-01 00:00:00 +0000 differ
3101=== removed file 'qml/Tutorial/graphics/dialer.png'
3102Binary files qml/Tutorial/graphics/dialer.png 2015-01-09 21:56:17 +0000 and qml/Tutorial/graphics/dialer.png 1970-01-01 00:00:00 +0000 differ
3103=== removed file 'qml/Tutorial/graphics/facebook.png'
3104Binary files qml/Tutorial/graphics/facebook.png 2015-01-12 14:02:33 +0000 and qml/Tutorial/graphics/facebook.png 1970-01-01 00:00:00 +0000 differ
3105=== removed file 'qml/Tutorial/graphics/gallery.png'
3106Binary files qml/Tutorial/graphics/gallery.png 2015-01-09 21:56:17 +0000 and qml/Tutorial/graphics/gallery.png 1970-01-01 00:00:00 +0000 differ
3107=== removed file 'qml/Tutorial/graphics/tick.png'
3108Binary files qml/Tutorial/graphics/tick.png 2014-12-18 23:32:42 +0000 and qml/Tutorial/graphics/tick.png 1970-01-01 00:00:00 +0000 differ
3109=== modified file 'tests/autopilot/unity8/shell/emulators.py'
3110--- tests/autopilot/unity8/shell/emulators.py 2015-04-29 19:21:18 +0000
3111+++ tests/autopilot/unity8/shell/emulators.py 2016-03-15 20:13:37 +0000
3112@@ -36,7 +36,6 @@
3113 'greeter',
3114 'launcher',
3115 'main_window',
3116- 'tutorial',
3117 'UnityEmulatorException',
3118 ]
3119
3120@@ -46,7 +45,6 @@
3121 dash,
3122 launcher,
3123 shell as main_window,
3124- tutorial,
3125 UnityException as UnityEmulatorException
3126 )
3127 from unity8.shell import create_interactive_notification
3128
3129=== removed file 'tests/autopilot/unity8/shell/tests/test_tutorial.py'
3130--- tests/autopilot/unity8/shell/tests/test_tutorial.py 2015-04-29 19:21:18 +0000
3131+++ tests/autopilot/unity8/shell/tests/test_tutorial.py 1970-01-01 00:00:00 +0000
3132@@ -1,57 +0,0 @@
3133-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3134-#
3135-# Unity Autopilot Test Suite
3136-# Copyright (C) 2014, 2015 Canonical
3137-#
3138-# This program is free software: you can redistribute it and/or modify
3139-# it under the terms of the GNU General Public License as published by
3140-# the Free Software Foundation, either version 3 of the License, or
3141-# (at your option) any later version.
3142-#
3143-# This program is distributed in the hope that it will be useful,
3144-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3145-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3146-# GNU General Public License for more details.
3147-#
3148-# You should have received a copy of the GNU General Public License
3149-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3150-#
3151-
3152-from autopilot.matchers import Eventually
3153-from testtools.matchers import Equals
3154-
3155-from unity8.shell import (
3156- fixture_setup,
3157- tests
3158-)
3159-# unused import to load the tutorial helpers custom proxy objects.
3160-from unity8 import tutorial as tutorial_helpers # NOQA
3161-
3162-
3163-class TutorialTestCase(tests.UnityTestCase):
3164-
3165- def setUp(self):
3166- super().setUp()
3167- self._qml_mock_enabled = False
3168- self._data_dirs_mock_enabled = False
3169-
3170- self.useFixture(fixture_setup.Tutorial(True))
3171- self.unity = self.launch_unity()
3172-
3173- def test_complete_tutorial(self):
3174- greeter = self.main_window.get_greeter()
3175- tutorial = self.unity.select_single('Tutorial')
3176- self.assertThat(tutorial.running, Eventually(Equals(True)))
3177- greeter.swipe()
3178- page = self.unity.wait_select_single(objectName='tutorialLeft')
3179- page.short_swipe_right()
3180- page = self.unity.wait_select_single(objectName='tutorialLeftFinish')
3181- page.tap()
3182- page = self.unity.wait_select_single(objectName='tutorialRight')
3183- page.swipe_left()
3184- page.tap()
3185- page = self.unity.wait_select_single(objectName='tutorialBottom')
3186- page.swipe_up()
3187- page = self.unity.wait_select_single(objectName='tutorialBottomFinish')
3188- page.tap()
3189- self.assertThat(tutorial.running, Eventually(Equals(False)))
3190
3191=== removed file 'tests/autopilot/unity8/tutorial.py'
3192--- tests/autopilot/unity8/tutorial.py 2015-04-29 19:21:18 +0000
3193+++ tests/autopilot/unity8/tutorial.py 1970-01-01 00:00:00 +0000
3194@@ -1,73 +0,0 @@
3195-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
3196-#
3197-# Unity Autopilot Test Suite
3198-# Copyright (C) 2014 Canonical
3199-#
3200-# This program is free software: you can redistribute it and/or modify
3201-# it under the terms of the GNU General Public License as published by
3202-# the Free Software Foundation, either version 3 of the License, or
3203-# (at your option) any later version.
3204-#
3205-# This program is distributed in the hope that it will be useful,
3206-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3207-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3208-# GNU General Public License for more details.
3209-#
3210-# You should have received a copy of the GNU General Public License
3211-# along with this program. If not, see <http://www.gnu.org/licenses/>.
3212-#
3213-
3214-import logging
3215-
3216-import ubuntuuitoolkit
3217-
3218-import autopilot
3219-from autopilot import introspection
3220-
3221-
3222-logger = logging.getLogger(__name__)
3223-
3224-
3225-class TutorialPage(
3226- ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
3227-
3228- @classmethod
3229- def validate_dbus_object(cls, path, state):
3230- name = introspection.get_classname_from_path(path)
3231- return name in (b'TutorialPage', b'TutorialLeft',
3232- b'TutorialLeftFinish', b'TutorialRight',
3233- b'TutorialBottom', b'TutorialBottomFinish')
3234-
3235- @autopilot.logging.log_action(logger.info)
3236- def short_swipe_right(self):
3237- self.shown.wait_for(True)
3238- x, y, width, height = self.globalRect
3239- start_x = x
3240- stop_x = x + width // 3
3241- start_y = stop_y = y + height // 2
3242- self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
3243-
3244- @autopilot.logging.log_action(logger.info)
3245- def swipe_left(self):
3246- self.shown.wait_for(True)
3247- x, y, width, height = self.globalRect
3248- start_x = width
3249- stop_x = x
3250- start_y = stop_y = y + height // 2
3251- self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
3252-
3253- @autopilot.logging.log_action(logger.info)
3254- def swipe_up(self):
3255- self.shown.wait_for(True)
3256- x, y, width, height = self.globalRect
3257- start_y = height
3258- stop_y = y
3259- start_x = stop_x = x + width // 2
3260- self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
3261-
3262- @autopilot.logging.log_action(logger.info)
3263- def tap(self):
3264- """Tap the tick button to complete this step."""
3265- self.shown.wait_for(True)
3266- button = self.wait_select_single(objectName="tick")
3267- self.pointing_device.click_object(button)
3268
3269=== modified file 'tests/mocks/AccountsService/AccountsService.cpp'
3270--- tests/mocks/AccountsService/AccountsService.cpp 2016-03-15 20:13:36 +0000
3271+++ tests/mocks/AccountsService/AccountsService.cpp 2016-03-15 20:13:37 +0000
3272@@ -26,6 +26,7 @@
3273 m_statsWelcomeScreen(true),
3274 m_failedLogins(0),
3275 m_demoEdges(false),
3276+ m_demoEdgesCompleted(),
3277 m_hereEnabled(false),
3278 m_hereLicensePath("")
3279 {
3280@@ -54,6 +55,25 @@
3281 Q_EMIT demoEdgesChanged();
3282 }
3283
3284+QStringList AccountsService::demoEdgesCompleted() const
3285+{
3286+ return m_demoEdgesCompleted;
3287+}
3288+
3289+void AccountsService::markDemoEdgeCompleted(const QString &edge)
3290+{
3291+ if (!m_demoEdgesCompleted.contains(edge)) {
3292+ m_demoEdgesCompleted << edge;
3293+ Q_EMIT demoEdgesCompletedChanged();
3294+ }
3295+}
3296+
3297+void AccountsService::setDemoEdgesCompleted(const QStringList &demoEdgesCompleted)
3298+{
3299+ m_demoEdgesCompleted = demoEdgesCompleted;
3300+ Q_EMIT demoEdgesCompletedChanged();
3301+}
3302+
3303 bool AccountsService::enableLauncherWhileLocked() const
3304 {
3305 return m_enableLauncherWhileLocked;
3306
3307=== modified file 'tests/mocks/AccountsService/AccountsService.h'
3308--- tests/mocks/AccountsService/AccountsService.h 2016-03-15 20:13:36 +0000
3309+++ tests/mocks/AccountsService/AccountsService.h 2016-03-15 20:13:37 +0000
3310@@ -19,6 +19,7 @@
3311
3312 #include <QObject>
3313 #include <QString>
3314+#include <QStringList>
3315 #include <QVariant>
3316
3317 class AccountsService: public QObject
3318@@ -33,6 +34,10 @@
3319 READ demoEdges
3320 WRITE setDemoEdges
3321 NOTIFY demoEdgesChanged)
3322+ Q_PROPERTY (QStringList demoEdgesCompleted
3323+ READ demoEdgesCompleted
3324+ WRITE setDemoEdgesCompleted // only available in mock
3325+ NOTIFY demoEdgesCompletedChanged)
3326 Q_PROPERTY (bool enableLauncherWhileLocked
3327 READ enableLauncherWhileLocked
3328 WRITE setEnableLauncherWhileLocked // only available in mock
3329@@ -82,6 +87,9 @@
3330 void setUser(const QString &user);
3331 bool demoEdges() const;
3332 void setDemoEdges(bool demoEdges);
3333+ QStringList demoEdgesCompleted() const;
3334+ void setDemoEdgesCompleted(const QStringList &demoEdges);
3335+ Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
3336 bool enableLauncherWhileLocked() const;
3337 void setEnableLauncherWhileLocked(bool enableLauncherWhileLocked);
3338 bool enableIndicatorsWhileLocked() const;
3339@@ -106,6 +114,7 @@
3340 Q_SIGNALS:
3341 void userChanged();
3342 void demoEdgesChanged();
3343+ void demoEdgesCompletedChanged();
3344 void enableLauncherWhileLockedChanged();
3345 void enableIndicatorsWhileLockedChanged();
3346 void backgroundFileChanged();
3347@@ -125,6 +134,7 @@
3348 bool m_statsWelcomeScreen;
3349 uint m_failedLogins;
3350 bool m_demoEdges;
3351+ QStringList m_demoEdgesCompleted;
3352 bool m_hereEnabled;
3353 QString m_hereLicensePath;
3354 QString m_realName;
3355
3356=== modified file 'tests/mocks/AccountsService/AccountsService.qmltypes'
3357--- tests/mocks/AccountsService/AccountsService.qmltypes 2015-02-13 09:01:16 +0000
3358+++ tests/mocks/AccountsService/AccountsService.qmltypes 2016-03-15 20:13:37 +0000
3359@@ -23,6 +23,7 @@
3360 }
3361 Property { name: "user"; type: "string" }
3362 Property { name: "demoEdges"; type: "bool" }
3363+ Property { name: "demoEdgesCompleted"; type: "QStringList" }
3364 Property { name: "enableLauncherWhileLocked"; type: "bool" }
3365 Property { name: "enableIndicatorsWhileLocked"; type: "bool" }
3366 Property { name: "backgroundFile"; type: "string" }
3367@@ -32,5 +33,9 @@
3368 Property { name: "hereEnabled"; type: "bool" }
3369 Property { name: "hereLicensePath"; type: "string" }
3370 Property { name: "hereLicensePathValid"; type: "bool"; isReadonly: true }
3371+ Method {
3372+ name: "markDemoEdgeCompleted"
3373+ Parameter { name: "edge"; type: "string" }
3374+ }
3375 }
3376 }
3377
3378=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.cpp'
3379--- tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-01-22 19:44:56 +0000
3380+++ tests/mocks/Unity/Application/ApplicationInfo.cpp 2016-03-15 20:13:37 +0000
3381@@ -44,6 +44,7 @@
3382 , m_isTouchApp(true)
3383 , m_exemptFromLifecycle(false)
3384 , m_manualSurfaceCreation(false)
3385+ , m_shellChrome(Mir::NormalChrome)
3386 {
3387 }
3388
3389@@ -63,6 +64,7 @@
3390 , m_isTouchApp(true)
3391 , m_exemptFromLifecycle(false)
3392 , m_manualSurfaceCreation(false)
3393+ , m_shellChrome(Mir::NormalChrome)
3394 {
3395 }
3396
3397@@ -102,9 +104,11 @@
3398 if (m_session) {
3399 m_session->setApplication(this);
3400 m_session->setParent(this);
3401+ m_session->setFullscreen(m_fullscreen);
3402 SessionManager::singleton()->registerSession(m_session);
3403 connect(m_session, &Session::surfaceAdded,
3404 this, &ApplicationInfo::onSessionSurfaceAdded);
3405+ connect(m_session, &Session::fullscreenChanged, this, &ApplicationInfo::fullscreenChanged);
3406
3407 if (!m_manualSurfaceCreation) {
3408 QTimer::singleShot(500, m_session, &Session::createSurface);
3409@@ -191,12 +195,17 @@
3410
3411 void ApplicationInfo::setFullscreen(bool value)
3412 {
3413- if (value != m_fullscreen) {
3414- m_fullscreen = value;
3415- Q_EMIT fullscreenChanged(value);
3416+ m_fullscreen = value;
3417+ if (m_session) {
3418+ m_session->setFullscreen(value);
3419 }
3420 }
3421
3422+bool ApplicationInfo::fullscreen() const
3423+{
3424+ return m_session ? m_session->fullscreen() : false;
3425+}
3426+
3427 void ApplicationInfo::setManualSurfaceCreation(bool value)
3428 {
3429 if (value != m_manualSurfaceCreation) {
3430@@ -262,6 +271,7 @@
3431 } else {
3432 setState(Suspended);
3433 }
3434+ surface->setShellChrome(m_shellChrome);
3435 }
3436 }
3437
3438@@ -291,3 +301,11 @@
3439 Q_EMIT initialSurfaceSizeChanged(m_initialSurfaceSize);
3440 }
3441 }
3442+
3443+void ApplicationInfo::setShellChrome(Mir::ShellChrome shellChrome)
3444+{
3445+ m_shellChrome = shellChrome;
3446+ if (m_session && m_session->lastSurface()) {
3447+ m_session->lastSurface()->setShellChrome(shellChrome);
3448+ }
3449+}
3450
3451=== modified file 'tests/mocks/Unity/Application/ApplicationInfo.h'
3452--- tests/mocks/Unity/Application/ApplicationInfo.h 2016-01-19 21:41:34 +0000
3453+++ tests/mocks/Unity/Application/ApplicationInfo.h 2016-03-15 20:13:37 +0000
3454@@ -24,6 +24,7 @@
3455
3456 // unity-api
3457 #include <unity/shell/application/ApplicationInfoInterface.h>
3458+#include <unity/shell/application/Mir.h>
3459
3460 using namespace unity::shell::application;
3461
3462@@ -59,7 +60,7 @@
3463
3464 QUrl icon() const override { return m_icon; }
3465
3466- void setStage(Stage value);
3467+ Q_INVOKABLE void setStage(Stage value); // invokable only for mock
3468 Stage stage() const override { return m_stage; }
3469
3470 Q_INVOKABLE void setState(State value);
3471@@ -78,7 +79,7 @@
3472 QString screenshot() const { return m_screenshotFileName; }
3473
3474 void setFullscreen(bool value);
3475- bool fullscreen() const { return m_fullscreen; }
3476+ bool fullscreen() const;
3477
3478 Qt::ScreenOrientations supportedOrientations() const override;
3479 void setSupportedOrientations(Qt::ScreenOrientations orientations);
3480@@ -97,6 +98,8 @@
3481
3482 QSize initialSurfaceSize() const override;
3483 void setInitialSurfaceSize(const QSize &size) override;
3484+
3485+ Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome);
3486 public:
3487 void setSession(Session* session);
3488 Session* session() const { return m_session; }
3489@@ -134,6 +137,7 @@
3490 QSize m_initialSurfaceSize;
3491
3492 bool m_manualSurfaceCreation;
3493+ Mir::ShellChrome m_shellChrome;
3494 };
3495
3496 Q_DECLARE_METATYPE(ApplicationInfo*)
3497
3498=== modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp'
3499--- tests/mocks/Unity/Application/ApplicationManager.cpp 2016-03-15 20:13:36 +0000
3500+++ tests/mocks/Unity/Application/ApplicationManager.cpp 2016-03-15 20:13:37 +0000
3501@@ -328,6 +328,7 @@
3502 application->setName("Camera");
3503 application->setScreenshotId("camera");
3504 application->setIconId("camera");
3505+ application->setShellChrome(Mir::LowChrome);
3506 application->setFullscreen(true);
3507 application->setSupportedOrientations(Qt::PortraitOrientation
3508 | Qt::LandscapeOrientation
3509@@ -341,7 +342,8 @@
3510 application->setName("Gallery");
3511 application->setScreenshotId("gallery");
3512 application->setIconId("gallery");
3513- application->setFullscreen(true);
3514+ application->setShellChrome(Mir::LowChrome);
3515+ application->setStage(ApplicationInfo::MainStage);
3516 m_availableApplications.append(application);
3517
3518 application = new ApplicationInfo(this);
3519@@ -353,7 +355,7 @@
3520
3521 application = new ApplicationInfo(this);
3522 application->setAppId("webbrowser-app");
3523- application->setFullscreen(true);
3524+ application->setShellChrome(Mir::LowChrome);
3525 application->setName("Browser");
3526 application->setScreenshotId("browser");
3527 application->setIconId("browser");
3528@@ -378,7 +380,7 @@
3529 application->setName("GMail");
3530 application->setIconId("gmail");
3531 application->setScreenshotId("gmail-webapp.svg");
3532- application->setFullscreen(false);
3533+ application->setStage(ApplicationInfo::MainStage);
3534 application->setSupportedOrientations(Qt::PortraitOrientation
3535 | Qt::LandscapeOrientation
3536 | Qt::InvertedPortraitOrientation
3537@@ -390,7 +392,7 @@
3538 application->setName("Music");
3539 application->setIconId("soundcloud");
3540 application->setScreenshotId("music");
3541- application->setFullscreen(false);
3542+ application->setStage(ApplicationInfo::MainStage);
3543 application->setSupportedOrientations(Qt::PortraitOrientation
3544 | Qt::LandscapeOrientation
3545 | Qt::InvertedPortraitOrientation
3546
3547=== modified file 'tests/mocks/Unity/Application/MirSurface.cpp'
3548--- tests/mocks/Unity/Application/MirSurface.cpp 2016-03-10 22:39:10 +0000
3549+++ tests/mocks/Unity/Application/MirSurface.cpp 2016-03-15 20:13:37 +0000
3550@@ -38,6 +38,7 @@
3551 , m_width(-1)
3552 , m_height(-1)
3553 , m_slowToResize(false)
3554+ , m_shellChrome(Mir::NormalChrome)
3555 {
3556 // qDebug() << "MirSurface::MirSurface() " << name;
3557 QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
3558@@ -134,6 +135,21 @@
3559 }
3560
3561
3562+Mir::ShellChrome MirSurface::shellChrome() const
3563+{
3564+ return m_shellChrome;
3565+}
3566+
3567+void MirSurface::setShellChrome(Mir::ShellChrome shellChrome)
3568+{
3569+ if (shellChrome == m_shellChrome)
3570+ return;
3571+
3572+ m_shellChrome = shellChrome;
3573+ Q_EMIT shellChromeChanged(shellChrome);
3574+}
3575+
3576+
3577
3578 void MirSurface::registerView(qintptr viewId)
3579 {
3580
3581=== modified file 'tests/mocks/Unity/Application/MirSurface.h'
3582--- tests/mocks/Unity/Application/MirSurface.h 2016-03-01 12:56:35 +0000
3583+++ tests/mocks/Unity/Application/MirSurface.h 2016-03-15 20:13:37 +0000
3584@@ -74,10 +74,13 @@
3585 int widthIncrement() const override { return m_widthIncrement; }
3586 int heightIncrement() const override { return m_heightIncrement; }
3587
3588+ Mir::ShellChrome shellChrome() const override;
3589+
3590 ////
3591 // API for tests
3592
3593 Q_INVOKABLE void setLive(bool live);
3594+ Q_INVOKABLE void setShellChrome(Mir::ShellChrome shellChrome);
3595
3596 void registerView(qintptr viewId);
3597 void unregisterView(qintptr viewId);
3598@@ -109,9 +112,6 @@
3599 void setActiveFocus(bool);
3600
3601 Q_SIGNALS:
3602- void stateChanged(Mir::State);
3603- void liveChanged(bool live);
3604- void orientationAngleChanged(Mir::OrientationAngle angle);
3605 void widthChanged();
3606 void heightChanged();
3607 void slowToResizeChanged();
3608@@ -152,6 +152,8 @@
3609 QSize m_delayedResize;
3610 QSize m_pendingResize;
3611
3612+ Mir::ShellChrome m_shellChrome;
3613+
3614 struct View {
3615 bool visible;
3616 };
3617
3618=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.cpp'
3619--- tests/mocks/Unity/Application/MirSurfaceItem.cpp 2016-03-15 20:13:36 +0000
3620+++ tests/mocks/Unity/Application/MirSurfaceItem.cpp 2016-03-15 20:13:37 +0000
3621@@ -100,6 +100,15 @@
3622 }
3623 }
3624
3625+Mir::ShellChrome MirSurfaceItem::shellChrome() const
3626+{
3627+ if (m_qmlSurface) {
3628+ return m_qmlSurface->shellChrome();
3629+ } else {
3630+ return Mir::NormalChrome;
3631+ }
3632+}
3633+
3634 Mir::OrientationAngle MirSurfaceItem::orientationAngle() const
3635 {
3636 if (m_qmlSurface) {
3637
3638=== modified file 'tests/mocks/Unity/Application/MirSurfaceItem.h'
3639--- tests/mocks/Unity/Application/MirSurfaceItem.h 2016-03-15 20:13:36 +0000
3640+++ tests/mocks/Unity/Application/MirSurfaceItem.h 2016-03-15 20:13:37 +0000
3641@@ -47,6 +47,7 @@
3642 Mir::Type type() const override;
3643 QString name() const override;
3644 bool live() const override;
3645+ Mir::ShellChrome shellChrome() const override;
3646
3647 Mir::State surfaceState() const override;
3648 void setSurfaceState(Mir::State) override {}
3649
3650=== modified file 'tests/mocks/Unity/Application/Session.cpp'
3651--- tests/mocks/Unity/Application/Session.cpp 2015-12-01 12:17:24 +0000
3652+++ tests/mocks/Unity/Application/Session.cpp 2016-03-15 20:13:37 +0000
3653@@ -34,6 +34,7 @@
3654 , m_surface(nullptr)
3655 , m_parentSession(nullptr)
3656 , m_children(new SessionModel(this))
3657+ , m_fullscreen(false)
3658 {
3659 // qDebug() << "Session::Session() " << this->name();
3660
3661@@ -71,6 +72,25 @@
3662 deleteLater();
3663 }
3664
3665+void Session::updateFullscreenProperty()
3666+{
3667+ if (m_surfaces.rowCount() > 0) {
3668+ // TODO: Figure out something better
3669+ setFullscreen(lastSurface()->state() == Mir::FullscreenState);
3670+ } else {
3671+ // Keep the current value of the fullscreen property until we get a new
3672+ // surface
3673+ }
3674+}
3675+
3676+void Session::setFullscreen(bool fullscreen)
3677+{
3678+ if (m_fullscreen != fullscreen) {
3679+ m_fullscreen = fullscreen;
3680+ Q_EMIT fullscreenChanged(m_fullscreen);
3681+ }
3682+}
3683+
3684 void Session::setApplication(ApplicationInfo* application)
3685 {
3686 if (m_application == application)
3687@@ -82,15 +102,18 @@
3688
3689 void Session::appendSurface(MirSurface* surface)
3690 {
3691- // qDebug() << "Session::appendSurface - session=" << name() << "surface=" << surface;
3692+ qDebug() << "Session::appendSurface - session=" << name() << "surface=" << surface;
3693
3694 m_surfaces.insert(m_surfaces.rowCount(), surface);
3695
3696+ connect(surface, &MirSurfaceInterface::stateChanged, this, &Session::updateFullscreenProperty);
3697 connect(surface, &QObject::destroyed,
3698 this, [this, surface]() { this->removeSurface(surface); });
3699
3700 Q_EMIT lastSurfaceChanged(surface);
3701 Q_EMIT surfaceAdded(surface);
3702+
3703+ updateFullscreenProperty();
3704 }
3705
3706 void Session::removeSurface(MirSurface* surface)
3707@@ -99,6 +122,8 @@
3708 if (m_surfaces.contains(surface)) {
3709 m_surfaces.remove(surface);
3710 }
3711+
3712+ updateFullscreenProperty();
3713 }
3714
3715 void Session::setScreenshot(const QUrl& screenshot)
3716
3717=== modified file 'tests/mocks/Unity/Application/Session.h'
3718--- tests/mocks/Unity/Application/Session.h 2015-12-01 12:17:24 +0000
3719+++ tests/mocks/Unity/Application/Session.h 2016-03-15 20:13:37 +0000
3720@@ -47,6 +47,7 @@
3721 //getters
3722 QString name() const { return m_name; }
3723 bool live() const { return m_live; }
3724+ bool fullscreen() const { return m_fullscreen; }
3725 ApplicationInfo* application() const { return m_application; }
3726 MirSurface *lastSurface() const;
3727 ObjectListModel<MirSurface>* surfaces() const;
3728@@ -57,6 +58,7 @@
3729 void removeSurface(MirSurface* surface);
3730 void setScreenshot(const QUrl& m_screenshot);
3731 void setLive(bool live);
3732+ void setFullscreen(bool fullscreen);
3733
3734 Q_INVOKABLE void addChildSession(Session* session);
3735 void insertChildSession(uint index, Session* session);
3736@@ -68,6 +70,7 @@
3737 void liveChanged(bool live);
3738 void surfaceAdded(MirSurface *surface);
3739 void lastSurfaceChanged(MirSurface *surface);
3740+ void fullscreenChanged(bool fullscreen);
3741
3742 // internal mock use
3743 void deregister();
3744@@ -75,6 +78,9 @@
3745 public Q_SLOTS:
3746 Q_INVOKABLE void createSurface();
3747
3748+private Q_SLOTS:
3749+ void updateFullscreenProperty();
3750+
3751 private:
3752 SessionModel* childSessions() const;
3753 void setParentSession(Session* session);
3754@@ -87,6 +93,7 @@
3755 Session* m_parentSession;
3756 SessionModel* m_children;
3757 ObjectListModel<MirSurface> m_surfaces;
3758+ bool m_fullscreen;
3759
3760 friend class ApplicationTestInterface;
3761 };
3762
3763=== modified file 'tests/mocks/Utils/CMakeLists.txt'
3764--- tests/mocks/Utils/CMakeLists.txt 2016-03-15 20:13:36 +0000
3765+++ tests/mocks/Utils/CMakeLists.txt 2016-03-15 20:13:37 +0000
3766@@ -12,7 +12,7 @@
3767 ${CMAKE_SOURCE_DIR}/plugins/Utils/qlimitproxymodelqml.cpp
3768 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitysortfilterproxymodelqml.cpp
3769 ${CMAKE_SOURCE_DIR}/plugins/Utils/unitymenumodelpaths.cpp
3770- ${CMAKE_SOURCE_DIR}/plugins/Utils/windowkeysfilter.cpp
3771+ ${CMAKE_SOURCE_DIR}/plugins/Utils/windowinputfilter.cpp
3772 ${CMAKE_SOURCE_DIR}/plugins/Utils/windowscreenshotprovider.cpp
3773 ${CMAKE_SOURCE_DIR}/plugins/Utils/easingcurve.cpp
3774 ${CMAKE_SOURCE_DIR}/plugins/Utils/inputwatcher.cpp
3775
3776=== modified file 'tests/mocks/Utils/Utils.qmltypes'
3777--- tests/mocks/Utils/Utils.qmltypes 2015-07-15 11:37:23 +0000
3778+++ tests/mocks/Utils/Utils.qmltypes 2016-03-15 20:13:37 +0000
3779@@ -145,10 +145,10 @@
3780 }
3781 }
3782 Component {
3783- name: "WindowKeysFilter"
3784+ name: "WindowInputFilter"
3785 defaultProperty: "data"
3786 prototype: "QQuickItem"
3787- exports: ["Utils/WindowKeysFilter 0.1"]
3788+ exports: ["Utils/WindowInputFilter 0.1"]
3789 exportMetaObjectRevisions: [0]
3790 }
3791 Component {
3792
3793=== modified file 'tests/mocks/Utils/plugin.cpp'
3794--- tests/mocks/Utils/plugin.cpp 2016-03-15 20:13:36 +0000
3795+++ tests/mocks/Utils/plugin.cpp 2016-03-15 20:13:37 +0000
3796@@ -32,7 +32,7 @@
3797 #include <qlimitproxymodelqml.h>
3798 #include <unitysortfilterproxymodelqml.h>
3799 #include <unitymenumodelpaths.h>
3800-#include <windowkeysfilter.h>
3801+#include <windowinputfilter.h>
3802 #include <windowscreenshotprovider.h>
3803 #include <easingcurve.h>
3804 #include <timezoneFormatter.h>
3805@@ -69,7 +69,7 @@
3806 qmlRegisterType<QLimitProxyModelQML>(uri, 0, 1, "LimitProxyModel");
3807 qmlRegisterType<UnitySortFilterProxyModelQML>(uri, 0, 1, "UnitySortFilterProxyModel");
3808 qmlRegisterType<UnityMenuModelPaths>(uri, 0, 1, "UnityMenuModelPaths");
3809- qmlRegisterType<WindowKeysFilter>(uri, 0, 1, "WindowKeysFilter");
3810+ qmlRegisterType<WindowInputFilter>(uri, 0, 1, "WindowInputFilter");
3811 qmlRegisterType<EasingCurve>(uri, 0, 1, "EasingCurve");
3812 qmlRegisterSingletonType<WindowStateStorage>(uri, 0, 1, "WindowStateStorage", createWindowStateStorage);
3813 qmlRegisterType<InputWatcher>(uri, 0, 1, "InputWatcher");
3814
3815=== modified file 'tests/plugins/AccountsService/PropertiesServer.cpp'
3816--- tests/plugins/AccountsService/PropertiesServer.cpp 2016-03-10 22:42:54 +0000
3817+++ tests/plugins/AccountsService/PropertiesServer.cpp 2016-03-15 20:13:37 +0000
3818@@ -89,6 +89,7 @@
3819 void PropertiesServer::Reset()
3820 {
3821 m_properties["com.canonical.unity.AccountsService"]["demo-edges"] = false;
3822+ m_properties["com.canonical.unity.AccountsService"]["DemoEdgesCompleted"] = QStringList();
3823 m_properties["com.canonical.unity.AccountsService"]["LauncherItems"] = QVariant::fromValue(QList<QVariantMap>());
3824 m_properties["com.canonical.unity.AccountsService.Private"]["FailedLogins"] = 0;
3825 m_properties["com.ubuntu.touch.AccountsService.SecurityPrivacy"]["StatsWelcomeScreen"] = true;
3826
3827=== modified file 'tests/plugins/AccountsService/client.cpp'
3828--- tests/plugins/AccountsService/client.cpp 2016-02-25 10:57:17 +0000
3829+++ tests/plugins/AccountsService/client.cpp 2016-03-15 20:13:37 +0000
3830@@ -117,6 +117,43 @@
3831 QCOMPARE(session.hereEnabled(), true);
3832 }
3833
3834+ void testMarkDemoEdgeCompleted()
3835+ {
3836+ AccountsService session(this, QTest::currentTestFunction());
3837+ QSignalSpy changedSpy(&session, &AccountsService::demoEdgesCompletedChanged);
3838+
3839+ QCOMPARE(changedSpy.count(), 0);
3840+ QCOMPARE(session.demoEdgesCompleted(), QStringList());
3841+
3842+ session.markDemoEdgeCompleted("testedge");
3843+ QCOMPARE(changedSpy.count(), 1);
3844+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
3845+
3846+ session.markDemoEdgeCompleted("testedge");
3847+ QCOMPARE(changedSpy.count(), 1);
3848+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
3849+
3850+ session.markDemoEdgeCompleted("testedge2");
3851+ QCOMPARE(changedSpy.count(), 2);
3852+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge" << "testedge2");
3853+ }
3854+
3855+ void testAsynchronousChangeForDemoEdgesCompleted()
3856+ {
3857+ AccountsService session(this, QTest::currentTestFunction());
3858+ QSignalSpy changedSpy(&session, &AccountsService::demoEdgesCompletedChanged);
3859+
3860+ QCOMPARE(changedSpy.count(), 0);
3861+ QCOMPARE(session.demoEdgesCompleted(), QStringList());
3862+
3863+ ASSERT_DBUS_CALL(m_userInterface->call("Set",
3864+ "com.canonical.unity.AccountsService",
3865+ "DemoEdgesCompleted",
3866+ dbusVariant(QStringList() << "testedge")));
3867+ QTRY_COMPARE(changedSpy.count(), 1);
3868+ QCOMPARE(session.demoEdgesCompleted(), QStringList() << "testedge");
3869+ }
3870+
3871 void testAsynchronousChangeForDemoEdges()
3872 {
3873 AccountsService session(this, QTest::currentTestFunction());
3874
3875=== modified file 'tests/qmltests/Components/tst_PhysicalKeysMapper.qml'
3876--- tests/qmltests/Components/tst_PhysicalKeysMapper.qml 2016-01-15 10:21:18 +0000
3877+++ tests/qmltests/Components/tst_PhysicalKeysMapper.qml 2016-03-15 20:13:37 +0000
3878@@ -26,9 +26,9 @@
3879
3880 property var physicalKeysMapper: loader.item
3881
3882- WindowKeysFilter {
3883- Keys.onPressed: physicalKeysMapper.onKeyPressed(event, currentEventTimestamp);
3884- Keys.onReleased: physicalKeysMapper.onKeyReleased(event, currentEventTimestamp);
3885+ WindowInputFilter {
3886+ Keys.onPressed: physicalKeysMapper.onKeyPressed(event, lastInputTimestamp);
3887+ Keys.onReleased: physicalKeysMapper.onKeyReleased(event, lastInputTimestamp);
3888 }
3889
3890 Loader {
3891
3892=== modified file 'tests/qmltests/Greeter/tst_Greeter.qml'
3893--- tests/qmltests/Greeter/tst_Greeter.qml 2016-01-11 17:37:02 +0000
3894+++ tests/qmltests/Greeter/tst_Greeter.qml 2016-03-15 20:13:37 +0000
3895@@ -328,9 +328,15 @@
3896 LightDM.Greeter.active = true;
3897
3898 greeter.forcedUnlock = true;
3899- compare(view.locked, false);
3900+ compare(greeter.required, false);
3901 greeter.forcedUnlock = false;
3902
3903+ // Now recover from tearing down the view above
3904+ LightDM.Greeter.showGreeter();
3905+ tryCompare(greeter, "required", true);
3906+ tryCompare(greeter, "waiting", false);
3907+ view = findChild(greeter, "testView");
3908+
3909 selectUser("no-password");
3910 tryCompare(view, "locked", false);
3911 selectUser("has-password");
3912
3913=== modified file 'tests/qmltests/Tutorial/tst_Tutorial.qml'
3914--- tests/qmltests/Tutorial/tst_Tutorial.qml 2015-09-02 07:42:27 +0000
3915+++ tests/qmltests/Tutorial/tst_Tutorial.qml 2016-03-15 20:13:37 +0000
3916@@ -19,15 +19,19 @@
3917 import AccountsService 0.1
3918 import IntegratedLightDM 0.1 as LightDM
3919 import Ubuntu.Components 1.3
3920+import Ubuntu.Components.ListItems 1.3
3921+import Ubuntu.Telephony 0.1 as Telephony
3922 import Unity.Application 0.1
3923 import Unity.Test 0.1 as UT
3924
3925 import "../../../qml"
3926+import "../../../qml/Components"
3927
3928-Item {
3929+Rectangle {
3930 id: root
3931- width: shellLoader.width + buttons.width
3932- height: shellLoader.height
3933+ color: UbuntuColors.lightGrey
3934+ width: units.gu(100) + buttons.width
3935+ height: units.gu(71)
3936
3937 QtObject {
3938 id: applicationArguments
3939@@ -45,6 +49,11 @@
3940 }
3941 }
3942
3943+ Telephony.CallEntry {
3944+ id: phoneCall
3945+ phoneNumber: "+447812221111"
3946+ }
3947+
3948 Component.onCompleted: {
3949 // must set the mock mode before loading the Shell
3950 LightDM.Greeter.mockMode = "single-pin";
3951@@ -52,21 +61,63 @@
3952 shellLoader.active = true;
3953 }
3954
3955- Row {
3956- spacing: 0
3957- anchors.fill: parent
3958+ Item {
3959+ id: shellContainer
3960+ anchors.left: root.left
3961+ anchors.right: buttons.left
3962+ anchors.top: root.top
3963+ anchors.bottom: root.bottom
3964
3965 Loader {
3966 id: shellLoader
3967
3968 active: false
3969- width: units.gu(40)
3970- height: units.gu(71)
3971+ anchors.horizontalCenter: parent.horizontalCenter
3972+ anchors.top: parent.top
3973+ anchors.bottom: parent.bottom
3974+
3975+ property int shellOrientation: Qt.PortraitOrientation
3976+ property int nativeOrientation: Qt.PortraitOrientation
3977+ property int primaryOrientation: Qt.PortraitOrientation
3978+
3979+ state: modeSelector.model[modeSelector.selectedIndex]
3980+ states: [
3981+ State {
3982+ name: "phone"
3983+ PropertyChanges {
3984+ target: shellLoader
3985+ width: units.gu(40)
3986+ }
3987+ },
3988+ State {
3989+ name: "tablet"
3990+ PropertyChanges {
3991+ target: shellLoader
3992+ width: units.gu(100)
3993+ shellOrientation: Qt.LandscapeOrientation
3994+ nativeOrientation: Qt.LandscapeOrientation
3995+ primaryOrientation: Qt.LandscapeOrientation
3996+ }
3997+ },
3998+ State {
3999+ name: "desktop"
4000+ PropertyChanges {
4001+ target: shellLoader
4002+ width: units.gu(100)
4003+ }
4004+ }
4005+ ]
4006
4007 property bool itemDestroyed: false
4008 sourceComponent: Component {
4009 Shell {
4010+ usageScenario: shellLoader.state
4011 property string indicatorProfile: "phone"
4012+ orientation: shellLoader.shellOrientation
4013+ orientations: Orientations {
4014+ native_: shellLoader.nativeOrientation
4015+ primary: shellLoader.primaryOrientation
4016+ }
4017
4018 Component.onDestruction: {
4019 shellLoader.itemDestroyed = true;
4020@@ -74,29 +125,92 @@
4021 }
4022 }
4023 }
4024-
4025- Rectangle {
4026- id: buttons
4027- color: "white"
4028- width: units.gu(30)
4029- height: shellLoader.height
4030-
4031- Column {
4032- anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
4033- spacing: units.gu(1)
4034- Row {
4035- anchors { left: parent.left; right: parent.right }
4036- Button {
4037- text: "Restart Tutorial"
4038- onClicked: {
4039- if (shellLoader.status !== Loader.Ready)
4040- return;
4041-
4042- AccountsService.demoEdges = false;
4043- AccountsService.demoEdges = true;
4044- }
4045- }
4046- }
4047+ }
4048+
4049+ Rectangle {
4050+ id: buttons
4051+ color: UbuntuColors.darkGrey
4052+ width: units.gu(30)
4053+ anchors.top: root.top
4054+ anchors.bottom: root.bottom
4055+ anchors.right: root.right
4056+
4057+ Column {
4058+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
4059+ spacing: units.gu(1)
4060+ Row {
4061+ anchors { left: parent.left; right: parent.right }
4062+ Button {
4063+ text: "Hide Greeter"
4064+ onClicked: {
4065+ if (shellLoader.status !== Loader.Ready)
4066+ return;
4067+
4068+ var greeter = testCase.findChild(shellLoader.item, "greeter");
4069+ if (greeter.shown) {
4070+ greeter.hide();
4071+ }
4072+ }
4073+ }
4074+ }
4075+
4076+ Row {
4077+ anchors { left: parent.left; right: parent.right }
4078+ Button {
4079+ text: "Restart Tutorial"
4080+ onClicked: {
4081+ if (shellLoader.status !== Loader.Ready)
4082+ return;
4083+
4084+ AccountsService.demoEdges = false;
4085+ AccountsService.demoEdgesCompleted = [];
4086+ AccountsService.demoEdges = true;
4087+ }
4088+ }
4089+ }
4090+
4091+ Row {
4092+ anchors { left: parent.left; right: parent.right }
4093+ CheckBox {
4094+ onCheckedChanged: {
4095+ if (checked) {
4096+ callManager.foregroundCall = phoneCall;
4097+ } else {
4098+ callManager.foregroundCall = null;
4099+ }
4100+ }
4101+ }
4102+ Label {
4103+ text: "Active Call"
4104+ anchors.verticalCenter: parent.verticalCenter
4105+ }
4106+ }
4107+
4108+ Row {
4109+ anchors { left: parent.left; right: parent.right }
4110+ CheckBox {
4111+ activeFocusOnPress: false
4112+ onCheckedChanged: {
4113+ var surface = SurfaceManager.inputMethodSurface;
4114+ if (checked) {
4115+ surface.setState(Mir.RestoredState);
4116+ } else {
4117+ surface.setState(Mir.MinimizedState);
4118+ }
4119+ }
4120+ }
4121+ Label {
4122+ text: "Input Method"
4123+ anchors.verticalCenter: parent.verticalCenter
4124+ }
4125+ }
4126+
4127+ ItemSelector {
4128+ id: modeSelector
4129+ anchors { left: parent.left; right: parent.right }
4130+ activeFocusOnPress: false
4131+ text: "Mode"
4132+ model: ["phone", "tablet", "desktop"]
4133 }
4134 }
4135 }
4136@@ -111,17 +225,21 @@
4137 property real halfHeight: shell ? shell.height / 2 : 0
4138
4139 function init() {
4140- tryCompare(shell, "enabled", true); // enabled by greeter when ready
4141+ prepareShell();
4142
4143- AccountsService.demoEdges = false;
4144- AccountsService.demoEdges = true;
4145- swipeAwayGreeter();
4146+ var tutorialLeft = findChild(shell, "tutorialLeft");
4147+ tryCompare(tutorialLeft, "opacity", 1);
4148 }
4149
4150 function cleanup() {
4151+ resetLoader("phone");
4152+ }
4153+
4154+ function resetLoader(state) {
4155 shellLoader.itemDestroyed = false;
4156
4157 shellLoader.active = false;
4158+ shellLoader.state = state;
4159
4160 tryCompare(shellLoader, "status", Loader.Null);
4161 tryCompare(shellLoader, "item", null);
4162@@ -133,6 +251,11 @@
4163 // Shell instance gets destroyed.
4164 tryCompare(shellLoader, "itemDestroyed", true);
4165
4166+ // Reset any futzing our tests may have done with persistent objects
4167+ var app = ApplicationManager.findApplication("dialer-app");
4168+ if (app) {
4169+ app.setStage(ApplicationInfoInterface.SideStage);
4170+ }
4171 // kill all (fake) running apps
4172 killApps();
4173
4174@@ -143,6 +266,22 @@
4175 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
4176 }
4177
4178+ function prepareShell() {
4179+ tryCompare(shell, "enabled", true); // enabled by greeter when ready
4180+
4181+ callManager.foregroundCall = null;
4182+ AccountsService.demoEdges = false;
4183+ AccountsService.demoEdgesCompleted = [];
4184+ AccountsService.demoEdges = true;
4185+
4186+ LightDM.Greeter.hideGreeter();
4187+ }
4188+
4189+ function loadShell(state) {
4190+ resetLoader(state);
4191+ prepareShell();
4192+ }
4193+
4194 function killApps() {
4195 while (ApplicationManager.count > 1) {
4196 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
4197@@ -163,234 +302,486 @@
4198 waitForRendering(greeter);
4199 }
4200
4201- function waitForPage(name) {
4202- waitForRendering(findChild(shell, name));
4203- var page = findChild(shell, name);
4204- tryCompare(page, "shown", true);
4205- tryCompare(page.showAnimation, "running", false);
4206- return page;
4207- }
4208-
4209- function checkTopEdge() {
4210- touchFlick(shell, halfWidth, 0, halfWidth, halfHeight);
4211-
4212+ function openTutorialTop() {
4213+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4214+ var tutorialTop = findChild(shell, "tutorialTop");
4215+ var tutorialTopTimer = findInvisibleChild(tutorialTop, "tutorialTopTimer");
4216+
4217+ tutorialTopTimer.interval = 1;
4218+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
4219+
4220+ tryCompare(tutorialLeftLoader, "active", false);
4221+ tryCompare(tutorialTop, "shown", true);
4222+ tryCompare(tutorialTop, "opacity", 1);
4223+ }
4224+
4225+ function openTutorialRight() {
4226+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4227+ var tutorialRight = findChild(shell, "tutorialRight");
4228+
4229+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
4230+ ApplicationManager.startApplication("gallery-app");
4231+ ApplicationManager.startApplication("facebook-webapp");
4232+
4233+ tryCompare(tutorialLeftLoader, "active", false);
4234+ tryCompare(tutorialRight, "shown", true);
4235+ tryCompare(tutorialRight, "opacity", 1);
4236+ }
4237+
4238+ function openTutorialBottom() {
4239+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4240+ var tutorialBottom = findChild(shell, "tutorialBottom");
4241+
4242+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right"];
4243+ ApplicationManager.startApplication("dialer-app");
4244+
4245+ tryCompare(tutorialLeftLoader, "active", false);
4246+ tryCompare(tutorialBottom, "shown", true);
4247+ tryCompare(tutorialBottom, "opacity", 1);
4248+ }
4249+
4250+ function test_tutorialLeftEdges() {
4251+ var tutorial = findChild(shell, "tutorial");
4252+ var tutorialLeft = findChild(tutorial, "tutorialLeft");
4253+ var launcher = findChild(shell, "launcher");
4254+ var stage = findChild(shell, "stage");
4255 var panel = findChild(shell, "panel");
4256- tryCompare(panel.indicators, "fullyClosed", true);
4257- }
4258-
4259- function checkLeftEdge() {
4260- touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
4261-
4262- var launcher = findChild(shell, "launcher");
4263- tryCompare(launcher, "state", "");
4264- }
4265-
4266- function checkRightEdge() {
4267- if (shell.usageScenario === "phone") {
4268- touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
4269-
4270- var stage = findChild(shell, "stage");
4271- var spreadView = findChild(stage, "spreadView");
4272- tryCompare(spreadView, "phase", 0);
4273- }
4274- }
4275-
4276- function checkBottomEdge() {
4277- // Can't actually check effect of swipe, since dash isn't really loaded
4278- var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader");
4279- tryCompare(applicationsDisplayLoader, "interactive", false);
4280- }
4281-
4282- function checkFinished() {
4283- tryCompare(AccountsService, "demoEdges", false);
4284-
4285- var tutorial = findChild(shell, "tutorial");
4286- tryCompare(tutorial, "running", false);
4287-
4288- var launcher = findChild(shell, "launcher");
4289- tryCompare(launcher, "shown", false);
4290- }
4291-
4292- function goToPage(name) {
4293- var page = waitForPage("tutorialLeft");
4294- checkTopEdge();
4295- checkRightEdge();
4296- checkBottomEdge();
4297- if (name === "tutorialLeft") return page;
4298- touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
4299-
4300- page = waitForPage("tutorialLeftFinish");
4301- if (name === "tutorialLeftFinish") return page;
4302- var tick = findChild(page, "tick");
4303- tap(tick);
4304-
4305- page = waitForPage("tutorialRight");
4306- checkTopEdge();
4307- checkLeftEdge();
4308- checkBottomEdge();
4309- if (name === "tutorialRight") return page;
4310- touchFlick(shell,
4311- shell.width, halfHeight,
4312- halfWidth, halfHeight,
4313- true /* beginTouch */, true /* endTouch */,
4314- 20 /* speed */, 50 /* iterations */);
4315- var overlay = findChild(page, "overlay");
4316- tryCompare(overlay, "shown", true);
4317- var tick = findChild(page, "tick");
4318- tap(tick);
4319-
4320- var page = waitForPage("tutorialBottom");
4321- checkTopEdge();
4322- checkLeftEdge();
4323- checkRightEdge();
4324- if (name === "tutorialBottom") return page;
4325- touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
4326-
4327- var page = waitForPage("tutorialBottomFinish");
4328- checkTopEdge();
4329- checkLeftEdge();
4330- checkRightEdge();
4331- checkBottomEdge();
4332- if (name === "tutorialBottomFinish") return page;
4333- var tick = findChild(page, "tick");
4334- tap(tick);
4335-
4336- checkFinished();
4337- return null;
4338- }
4339-
4340- function test_walkthrough() {
4341- goToPage(null);
4342- }
4343-
4344- function test_skipOnDesktop() {
4345- var tutorial = findChild(shell, "tutorial");
4346- tryCompare(tutorial, "active", true);
4347- tryCompare(tutorial, "running", true);
4348-
4349- shell.usageScenario = "desktop";
4350- tryCompare(tutorial, "active", false);
4351- tryCompare(tutorial, "running", false);
4352- }
4353-
4354- function test_launcherShortDrag() {
4355- // goToPage does a normal launcher pull. But here we want to test
4356- // just barely pulling the launcher out and letting go (i.e. not
4357- // triggering the "progress" property of Launcher).
4358-
4359- var left = goToPage("tutorialLeft");
4360+
4361+ verify(tutorial.running);
4362+ verify(tutorial.launcherEnabled);
4363+ verify(!tutorial.spreadEnabled);
4364+ verify(!tutorial.panelEnabled);
4365+ verify(tutorialLeft.shown);
4366+ verify(launcher.available);
4367+ verify(!stage.spreadEnabled);
4368+ verify(!panel.indicators.available);
4369+ }
4370+
4371+ function test_tutorialLeftFinish() {
4372+ var tutorial = findChild(shell, "tutorial");
4373+ var tutorialLeft = findChild(tutorial, "tutorialLeft");
4374+ var launcher = findChild(shell, "launcher");
4375+
4376+ touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
4377+
4378+ tryCompare(tutorialLeft, "shown", false);
4379+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
4380+ tryCompare(launcher, "state", "visible");
4381+ }
4382+
4383+ function test_tutorialLeftShortDrag() {
4384+ // Here we want to test just barely pulling the launcher out and
4385+ // letting go (i.e. not triggering the "progress" property of
4386+ // Launcher).
4387+ var tutorialLeft = findChild(shell, "tutorialLeft");
4388+ var launcher = findChild(shell, "launcher");
4389+
4390+ // Confirm fade during drag
4391+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, true, false);
4392+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
4393+ // always match the drag perfectly (takes a moment for drag to kick in)
4394+ tryCompareFunction(function() {
4395+ return tutorialLeft.opacity >= 0.6 && tutorialLeft.opacity < 0.7;
4396+ }, true);
4397+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, false, true);
4398+
4399
4400 // Make sure we don't do anything if we don't pull the launcher
4401 // out much.
4402- var launcher = findChild(shell, "launcher");
4403 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
4404 tryCompare(launcher, "state", ""); // should remain hidden
4405- tryCompare(left, "shown", true); // and we should still be on left
4406+ tryCompare(tutorialLeft, "shown", true); // and we should still be on left
4407+
4408
4409 // Now drag out but not past launcher itself
4410 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
4411
4412- waitForPage("tutorialLeftFinish");
4413+ tryCompare(tutorialLeft, "shown", false);
4414+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
4415+ tryCompare(launcher, "state", "visible");
4416 }
4417
4418- function test_launcherLongDrag() {
4419- // goToPage does a normal launcher pull. But here we want to test
4420- // a full pull across the page.
4421+ function test_tutorialLeftLongDrag() {
4422+ // Just confirm that a long drag ("dash" drag) doesn't confuse us
4423
4424- var left = goToPage("tutorialLeft");
4425+ // So that we actually switch to dash and launcher hides
4426+ ApplicationManager.startApplication("gallery-app");
4427
4428 var launcher = findChild(shell, "launcher");
4429+ var tutorialLeft = findChild(shell, "tutorialLeft");
4430 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
4431
4432- var errorTextLabel = findChild(left, "errorTextLabel");
4433- var errorTitleLabel = findChild(left, "errorTitleLabel");
4434- tryCompare(launcher, "state", ""); // launcher goes away
4435- tryCompare(left, "shown", true); // still on left page
4436- tryCompare(errorTextLabel, "opacity", 1); // show error
4437- tryCompare(errorTitleLabel, "opacity", 1); // show error
4438- }
4439-
4440- function test_launcherDragBack() {
4441- // goToPage does a full launcher pull. But here we test pulling
4442- // all the way out, then dragging back into place.
4443-
4444- var left = goToPage("tutorialLeft");
4445- touchFlick(shell, 0, halfHeight, halfWidth, halfHeight, true, false);
4446- touchFlick(shell, halfWidth, halfHeight, 0, halfHeight, false, true);
4447-
4448- tryCompare(left, "shown", true); // and we should still be on left
4449- }
4450-
4451- function test_launcherNoDragGap() {
4452- // See bug 1454882, where if you dragged the launcher while it was
4453- // visible, you could pull it further than the edge of the screen.
4454-
4455- var left = goToPage("tutorialLeft");
4456- var launcher = findChild(shell, "launcher");
4457- var teaseAnimation = findInvisibleChild(left, "teaseAnimation");
4458-
4459- // Wait for launcher to be really out there
4460- tryCompareFunction(function() {return launcher.x > teaseAnimation.maxBounce/2}, true);
4461- verify(teaseAnimation.running);
4462-
4463- // Start a drag, make sure animation stops
4464- touchFlick(shell, 0, halfHeight, units.gu(4), halfHeight, true, false);
4465- verify(!teaseAnimation.running);
4466- verify(launcher.visibleWidth > 0);
4467- verify(launcher.x > 0);
4468- compare(launcher.x, teaseAnimation.bounce);
4469-
4470- // Continue drag, make sure we don't create a gap on the left hand side
4471- touchFlick(shell, units.gu(4), halfHeight, shell.width, halfHeight, false, false);
4472- verify(!teaseAnimation.running);
4473- compare(launcher.visibleWidth, launcher.panelWidth);
4474- compare(launcher.x, 0);
4475-
4476- // Finish and make sure we continue animation
4477- touchFlick(shell, shell.width, halfHeight, shell.width, halfHeight, false, true);
4478- tryCompare(teaseAnimation, "running", true);
4479- }
4480-
4481- function test_spread() {
4482- // Unfortunately, most of what we want to test of the spread is
4483- // "did it render correctly?" but that's hard to test. So instead,
4484- // just poke and prod it a little bit to see if some of the values
4485- // we'd expect to be correct, are so.
4486-
4487- var right = goToPage("tutorialRight");
4488- var stage = findChild(right, "stage");
4489- var delegate0 = findChild(right, "appDelegate0");
4490-
4491- tryCompare(stage, "dragProgress", 0);
4492+ tryCompare(tutorialLeft, "shown", false);
4493+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
4494+ }
4495+
4496+ function test_tutorialLeftAutoSkipped() {
4497+ // Test that we skip the tutorial if user uses left edge themselves
4498+
4499+ var tutorialLeft = findChild(shell, "tutorialLeft");
4500+ LightDM.Greeter.showGreeter();
4501+ tryCompare(tutorialLeft, "visible", false);
4502+ compare(AccountsService.demoEdgesCompleted, []);
4503+
4504+ touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
4505+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
4506+ }
4507+
4508+ function test_tutorialTopEdges() {
4509+ var tutorial = findChild(shell, "tutorial");
4510+ var tutorialTop = findChild(tutorial, "tutorialTop");
4511+ var launcher = findChild(shell, "launcher");
4512+ var stage = findChild(shell, "stage");
4513+ var panel = findChild(shell, "panel");
4514+
4515+ openTutorialTop();
4516+
4517+ tryCompare(tutorial, "running", true);
4518+ verify(!tutorial.launcherEnabled);
4519+ verify(!tutorial.spreadEnabled);
4520+ verify(tutorial.panelEnabled);
4521+ verify(tutorialTop.shown);
4522+ verify(!launcher.available);
4523+ verify(!stage.spreadEnabled);
4524+ verify(panel.indicators.available);
4525+ }
4526+
4527+ function test_tutorialTopFinish() {
4528+ var tutorial = findChild(shell, "tutorial");
4529+ var tutorialTop = findChild(tutorial, "tutorialTop");
4530+ var panel = findChild(shell, "panel");
4531+
4532+ openTutorialTop();
4533+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
4534+
4535+ tryCompare(tutorialTop, "shown", false);
4536+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
4537+ tryCompare(panel.indicators, "fullyOpened", true);
4538+ }
4539+
4540+ function test_tutorialTopShortDrag() {
4541+ var tutorial = findChild(shell, "tutorial");
4542+ var tutorialTop = findChild(tutorial, "tutorialTop");
4543+ var panel = findChild(shell, "panel");
4544+
4545+ openTutorialTop();
4546+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, true, false);
4547+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
4548+ // always match the drag perfectly (takes a moment for drag to kick in)
4549+ tryCompareFunction(function() {
4550+ return tutorialTop.opacity >= 0.6 && tutorialTop.opacity < 0.7;
4551+ }, true);
4552+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, false, true);
4553+
4554+ compare(tutorialTop.shown, true);
4555+ }
4556+
4557+ function test_tutorialTopAutoSkipped() {
4558+ // Test that we skip the tutorial if user uses top edge themselves
4559+
4560+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4561+ var tutorialTop = findChild(shell, "tutorialTop");
4562+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
4563+ tryCompare(tutorialLeftLoader, "active", false);
4564+ verify(!tutorialTop.shown);
4565+
4566+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
4567+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
4568+ }
4569+
4570+ function test_tutorialRightEdges() {
4571+ var tutorial = findChild(shell, "tutorial");
4572+ var tutorialRight = findChild(tutorial, "tutorialRight");
4573+ var launcher = findChild(shell, "launcher");
4574+ var stage = findChild(shell, "stage");
4575+ var panel = findChild(shell, "panel");
4576+
4577+ openTutorialRight();
4578+
4579+ tryCompare(tutorial, "running", true);
4580+ verify(!tutorial.launcherEnabled);
4581+ verify(tutorial.spreadEnabled);
4582+ verify(!tutorial.panelEnabled);
4583+ verify(tutorialRight.shown);
4584+ verify(!launcher.available);
4585+ verify(stage.spreadEnabled);
4586+ verify(!panel.indicators.available);
4587+ }
4588+
4589+ function test_tutorialRightFinish() {
4590+ var tutorial = findChild(shell, "tutorial");
4591+ var tutorialRight = findChild(tutorial, "tutorialRight");
4592+ var stage = findChild(shell, "stage");
4593+
4594+ openTutorialRight();
4595+ touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
4596+
4597+ tryCompare(tutorialRight, "shown", false);
4598+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right"]);
4599+ }
4600+
4601+ function test_tutorialRightShortDrag() {
4602+ var tutorial = findChild(shell, "tutorial");
4603+ var tutorialRight = findChild(tutorial, "tutorialRight");
4604+ var stage = findChild(shell, "stage");
4605+
4606+ openTutorialRight();
4607 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
4608- verify(stage.dragProgress > 0);
4609- compare(stage.dragProgress, -delegate0.xTranslate);
4610- touchFlick(shell, shell.width * 0.8, halfHeight, shell.width, halfHeight, false, true);
4611- tryCompare(stage, "dragProgress", 0);
4612-
4613- tryCompare(delegate0, "x", shell.width);
4614-
4615- var screenshotImage = findChild(right, "screenshotImage");
4616- tryCompare(screenshotImage, "source", Qt.resolvedUrl("../../../qml/Tutorial/graphics/facebook.png"));
4617- tryCompare(screenshotImage, "visible", true);
4618- }
4619-
4620- function test_bottomShortDrag() {
4621- var bottom = goToPage("tutorialBottom");
4622-
4623- touchFlick(shell, halfWidth, shell.height, halfWidth, shell.height * 0.8);
4624-
4625- var errorTextLabel = findChild(bottom, "errorTextLabel");
4626- var errorTitleLabel = findChild(bottom, "errorTitleLabel");
4627- tryCompare(bottom, "shown", true); // still on bottom page
4628- tryCompare(errorTextLabel, "opacity", 1); // show error
4629- tryCompare(errorTitleLabel, "opacity", 1); // show error
4630- }
4631-
4632- function test_interrupted() {
4633- goToPage("tutorialLeft");
4634- ApplicationManager.startApplication("dialer-app");
4635- checkFinished();
4636+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
4637+ // always match the drag perfectly (takes a moment for drag to kick in)
4638+ tryCompareFunction(function() {
4639+ return tutorialRight.opacity >= 0.6 && tutorialRight.opacity < 0.8;
4640+ }, true);
4641+ touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, false, true);
4642+
4643+ compare(tutorialRight.shown, true);
4644+ }
4645+
4646+ function test_tutorialRightDelay() {
4647+ // Test that if we exit the top tutorial, we don't immediately
4648+ // jump into right tutorial.
4649+ var tutorialRight = findChild(shell, "tutorialRight");
4650+ var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightInactivityTimer");
4651+
4652+ tutorialRightTimer.interval = 1;
4653+ openTutorialTop();
4654+ ApplicationManager.startApplication("gallery-app");
4655+ ApplicationManager.startApplication("facebook-webapp");
4656+ tryCompare(ApplicationManager, "count", 3);
4657+
4658+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
4659+ verify(tutorialRightTimer.running, true);
4660+ verify(!tutorialRight.shown);
4661+ tryCompare(tutorialRight, "shown", true);
4662+ }
4663+
4664+ function test_tutorialRightAutoSkipped() {
4665+ // Test that we skip the tutorial if user uses right edge themselves
4666+
4667+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4668+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
4669+ tryCompare(tutorialLeftLoader, "active", false);
4670+
4671+ touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
4672+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "right"]);
4673+ }
4674+
4675+ function test_tutorialBottomEdges() {
4676+ var tutorial = findChild(shell, "tutorial");
4677+ var tutorialBottom = findChild(tutorial, "tutorialBottom");
4678+ var tutorialLabel = findChild(tutorialBottom, "tutorialLabel");
4679+ var launcher = findChild(shell, "launcher");
4680+ var stage = findChild(shell, "stage");
4681+ var panel = findChild(shell, "panel");
4682+
4683+ openTutorialBottom();
4684+
4685+ tryCompare(tutorial, "running", true);
4686+ verify(!tutorial.launcherEnabled);
4687+ verify(!tutorial.spreadEnabled);
4688+ verify(!tutorial.panelEnabled);
4689+ verify(tutorialBottom.shown);
4690+ verify(!launcher.available);
4691+ verify(!stage.spreadEnabled);
4692+ verify(!panel.indicators.available);
4693+ compare(tutorialLabel.text, "Swipe up for recent calls");
4694+ }
4695+
4696+ function test_tutorialBottomFinish() {
4697+ var tutorial = findChild(shell, "tutorial");
4698+ var tutorialBottom = findChild(tutorial, "tutorialBottom");
4699+
4700+ openTutorialBottom();
4701+ touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
4702+
4703+ tryCompare(tutorialBottom, "shown", false);
4704+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right", "bottom-dialer-app"]);
4705+
4706+ // OK, we did one, just confirm that when all are done, we mark whole tutorial as done.
4707+ verify(AccountsService.demoEdges);
4708+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right",
4709+ "bottom-address-book-app",
4710+ "bottom-com.ubuntu.calculator_calculator",
4711+ "bottom-dialer-app",
4712+ "bottom-messaging-app"];
4713+ verify(!AccountsService.demoEdges);
4714+ }
4715+
4716+ function test_tutorialBottomAppearsBeforeRight() {
4717+ // Confirm that if bottom edge and right edge would appear on the
4718+ // the same app open, bottom edge appears first. (this is a lightly
4719+ // edited version of openTutorialRight)
4720+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4721+ var tutorialRight = findChild(shell, "tutorialRight");
4722+ var tutorialBottom = findChild(shell, "tutorialBottom");
4723+
4724+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
4725+ ApplicationManager.startApplication("gallery-app");
4726+ ApplicationManager.startApplication("dialer-app");
4727+
4728+ tryCompare(tutorialLeftLoader, "active", false);
4729+ tryCompare(tutorialBottom, "shown", true);
4730+ tryCompare(tutorialBottom, "opacity", 1);
4731+ tryCompare(tutorialRight, "visible", false);
4732+ }
4733+
4734+ function test_tutorialBottomOnlyCoversSideStageOnTablet() {
4735+ loadShell("tablet");
4736+
4737+ var tutorialBottom = findChild(shell, "tutorialBottom");
4738+ var targetHeight = shell.height - units.gu(4);
4739+ var mainStageX = units.gu(20);
4740+ var sideStageX = shell.width - units.gu(20);
4741+
4742+ openTutorialBottom();
4743+
4744+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
4745+ compare(tutorialBottom.opacity, 1);
4746+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
4747+
4748+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
4749+ verify(tutorialBottom.opacity < 1);
4750+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
4751+ }
4752+
4753+ function test_tutorialBottomOnlyCoversMainStageOnTablet() {
4754+ loadShell("tablet");
4755+
4756+ var tutorialBottom = findChild(shell, "tutorialBottom");
4757+ var targetHeight = shell.height - units.gu(4);
4758+ var mainStageX = units.gu(20);
4759+ var sideStageX = shell.width - units.gu(20);
4760+
4761+ openTutorialBottom();
4762+ var app = ApplicationManager.findApplication("dialer-app");
4763+ app.setStage(ApplicationInfoInterface.MainStage);
4764+
4765+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
4766+ compare(tutorialBottom.opacity, 1);
4767+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
4768+
4769+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
4770+ verify(tutorialBottom.opacity < 1);
4771+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
4772+ }
4773+
4774+ function test_activeCallInterruptsTutorial() {
4775+ var tutorialLeft = findChild(shell, "tutorialLeft");
4776+ verify(tutorialLeft.shown);
4777+ verify(!tutorialLeft.paused);
4778+
4779+ callManager.foregroundCall = phoneCall;
4780+ verify(!tutorialLeft.shown);
4781+ verify(tutorialLeft.paused);
4782+ tryCompare(tutorialLeft, "visible", false);
4783+
4784+ callManager.foregroundCall = null;
4785+ tryCompare(tutorialLeft, "shown", true);
4786+ verify(!tutorialLeft.paused);
4787+ }
4788+
4789+ function test_greeterInterruptsTutorial() {
4790+ var tutorialLeft = findChild(shell, "tutorialLeft");
4791+ verify(tutorialLeft.shown);
4792+ verify(!tutorialLeft.paused);
4793+
4794+ LightDM.Greeter.showGreeter();
4795+ verify(!tutorialLeft.shown);
4796+ verify(tutorialLeft.paused);
4797+ tryCompare(tutorialLeft, "visible", false);
4798+
4799+ LightDM.Greeter.hideGreeter();
4800+ tryCompare(tutorialLeft, "shown", true);
4801+ verify(!tutorialLeft.paused);
4802+ }
4803+
4804+ function test_interruptionChecksReadyStateWhenDone() {
4805+ // If we're done with an interruption (like active call), make sure
4806+ // that we don't blindly resume the tutorial -- our trigger
4807+ // conditions still need to be met. For example, there need to be
4808+ // enough apps open for the right edge tutorial.
4809+
4810+ openTutorialRight();
4811+
4812+ var tutorialRight = findChild(shell, "tutorialRight");
4813+ verify(tutorialRight.isReady);
4814+ verify(tutorialRight.shown);
4815+ verify(!tutorialRight.paused);
4816+
4817+ callManager.foregroundCall = phoneCall;
4818+ killApps();
4819+ callManager.foregroundCall = null;
4820+
4821+ verify(!tutorialRight.isReady);
4822+ verify(!tutorialRight.shown);
4823+ verify(!tutorialRight.paused);
4824+ compare(AccountsService.demoEdgesCompleted, ["left", "left-long", "top"]);
4825+ }
4826+
4827+ function test_desktopOnlyShowsTutorialRight() {
4828+ loadShell("desktop");
4829+
4830+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
4831+ var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
4832+ var tutorialRightLoader = findChild(shell, "tutorialRightLoader");
4833+ var tutorialBottomLoader = findChild(shell, "tutorialBottomLoader");
4834+ verify(!tutorialLeftLoader.active);
4835+ verify(!tutorialTopLoader.active);
4836+ verify(tutorialRightLoader.active);
4837+ verify(!tutorialBottomLoader.active);
4838+ compare(AccountsService.demoEdgesCompleted, []);
4839+
4840+ ApplicationManager.startApplication("dialer-app");
4841+ ApplicationManager.startApplication("camera-app");
4842+ tryCompare(tutorialRightLoader.item, "isReady", true);
4843+ tryCompare(tutorialRightLoader, "shown", true);
4844+ }
4845+
4846+ function test_oskDoesNotHideTutorial() {
4847+ var tutorialLeft = findChild(shell, "tutorialLeft");
4848+ verify(tutorialLeft.shown);
4849+
4850+ var surface = SurfaceManager.inputMethodSurface;
4851+ surface.setState(Mir.RestoredState);
4852+
4853+ var inputMethod = findInvisibleChild(shell, "inputMethod");
4854+ tryCompare(inputMethod, "state", "shown");
4855+
4856+ verify(tutorialLeft.shown);
4857+ }
4858+
4859+ function test_oskPreventsTutorial() {
4860+ var surface = SurfaceManager.inputMethodSurface;
4861+ var inputMethod = findInvisibleChild(shell, "inputMethod");
4862+
4863+ AccountsService.demoEdges = false;
4864+ surface.setState(Mir.RestoredState);
4865+ tryCompare(inputMethod, "state", "shown");
4866+
4867+ var tutorial = findChild(shell, "tutorial");
4868+ tryCompare(tutorial, "keyboardVisible", true);
4869+
4870+ AccountsService.demoEdges = true;
4871+ var tutorialLeft = findChild(shell, "tutorialLeft");
4872+ verify(!tutorialLeft.shown);
4873+
4874+ surface.setState(Mir.MinimizedState);
4875+ tryCompare(inputMethod, "state", "hidden");
4876+ tryCompare(tutorialLeft, "shown", false);
4877+ }
4878+
4879+ function test_accountsServiceSettings() {
4880+ var tutorialLeft = findChild(shell, "tutorialLeft");
4881+ verify(tutorialLeft != null);
4882+ verify(tutorialLeft.shown);
4883+
4884+ AccountsService.demoEdges = false;
4885+ verify(findChild(shell, "tutorialLeft") == null);
4886+
4887+ AccountsService.demoEdges = true;
4888+ tutorialLeft = findChild(shell, "tutorialLeft");
4889+ verify(tutorialLeft != null);
4890+ tryCompare(tutorialLeft, "shown", true);
4891 }
4892 }
4893 }
4894
4895=== modified file 'tests/qmltests/tst_Shell.qml'
4896--- tests/qmltests/tst_Shell.qml 2016-03-10 22:43:31 +0000
4897+++ tests/qmltests/tst_Shell.qml 2016-03-15 20:13:37 +0000
4898@@ -131,6 +131,9 @@
4899 anchors.right: root.right
4900 width: units.gu(30)
4901
4902+ property var focusedApp: ApplicationManager.findApplication(ApplicationManager.focusedApplicationId)
4903+ property var focusedSurface: focusedApp && focusedApp.session ? focusedApp.session.lastSurface : null
4904+
4905 Rectangle {
4906 id: controlRect
4907 anchors { left: parent.left; right: parent.right }
4908@@ -251,6 +254,65 @@
4909 appId: modelData
4910 }
4911 }
4912+
4913+ Label { text: "Focused Application"; font.bold: true }
4914+
4915+ Row {
4916+ CheckBox {
4917+ id: fullscreeAppCheck
4918+
4919+ onTriggered: {
4920+ if (!controls.focusedSurface) return;
4921+ if (controls.focusedSurface.state == Mir.FullscreenState) {
4922+ controls.focusedSurface.state = Mir.RestoredState;
4923+ } else {
4924+ controls.focusedSurface.state = Mir.FullscreenState;
4925+ }
4926+ }
4927+
4928+ Binding {
4929+ target: fullscreeAppCheck
4930+ when: controls.focusedSurface
4931+ property: "checked"
4932+ value: {
4933+ if (!controls.focusedSurface) return false;
4934+ return controls.focusedSurface.state === Mir.FullscreenState
4935+ }
4936+ }
4937+ }
4938+ Label {
4939+ text: "Fullscreen"
4940+ }
4941+ }
4942+
4943+ Row {
4944+ CheckBox {
4945+ id: chromeAppCheck
4946+
4947+ onTriggered: {
4948+ if (!controls.focusedSurface) return;
4949+ if (controls.focusedSurface.shellChrome == Mir.LowChrome) {
4950+ controls.focusedSurface.setShellChrome(Mir.NormalChrome);
4951+ } else {
4952+ controls.focusedSurface.setShellChrome(Mir.LowChrome);
4953+ }
4954+ }
4955+
4956+ Binding {
4957+ target: chromeAppCheck
4958+ when: controls.focusedSurface !== null
4959+ property: "checked"
4960+ value: {
4961+ if (!controls.focusedSurface) return false;
4962+ controls.focusedSurface.shellChrome === Mir.LowChrome
4963+ }
4964+ }
4965+ }
4966+ Label {
4967+ text: "Low Chrome"
4968+ }
4969+ }
4970+
4971 }
4972 }
4973 }
4974@@ -425,6 +487,7 @@
4975 setLightDMMockMode("single"); // back to the default value
4976
4977 AccountsService.demoEdges = false;
4978+ AccountsService.demoEdgesCompleted = [];
4979 Wizard.System.wizardEnabled = false;
4980
4981 // kill all (fake) running apps
4982@@ -576,9 +639,8 @@
4983
4984 function test_tabletLeftEdgeDrag_data() {
4985 return [
4986- {tag: "without password", user: "no-password", loggedIn: true, demo: false},
4987- {tag: "with password", user: "has-password", loggedIn: false, demo: false},
4988- {tag: "with demo", user: "has-password", loggedIn: true, demo: true},
4989+ {tag: "without password", user: "no-password", loggedIn: true},
4990+ {tag: "with password", user: "has-password", loggedIn: false},
4991 ]
4992 }
4993
4994@@ -588,10 +650,6 @@
4995
4996 selectUser(data.user)
4997
4998- AccountsService.demoEdges = data.demo
4999- var tutorial = findChild(shell, "tutorial");
5000- tryCompare(tutorial, "running", data.demo);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches