Merge lp:~mzanetti/unity8/staged-spread-with-kbd into lp:unity8

Proposed by Michael Zanetti
Status: Merged
Approved by: Albert Astals Cid
Approved revision: 2210
Merged at revision: 2236
Proposed branch: lp:~mzanetti/unity8/staged-spread-with-kbd
Merge into: lp:unity8
Prerequisite: lp:~mzanetti/unity8/mouse-activated-staged-spreads
Diff against target: 322 lines (+139/-24)
5 files modified
qml/Stages/PhoneStage.qml (+47/-6)
qml/Stages/SpreadDelegate.qml (+20/-0)
qml/Stages/TabletStage.qml (+53/-6)
tests/qmltests/Stages/tst_SpreadDelegate.qml (+7/-0)
tests/qmltests/tst_Shell.qml (+12/-12)
To merge this branch: bzr merge lp:~mzanetti/unity8/staged-spread-with-kbd
Reviewer Review Type Date Requested Status
Albert Astals Cid (community) Approve
Unity8 CI Bot continuous-integration Needs Fixing
Review via email: mp+288281@code.launchpad.net

Commit message

Allow alt+tabbing in staged mode too

Description of the change

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

see prereq

 * 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?

n/a

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

vesa is testing it

To post a comment you must log in.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

A checkbox in tst_SpreadDelegate.qml to control highlightShown would be nice.

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

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

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

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

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

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

review: Needs Fixing (continuous-integration)
2208. By Michael Zanetti

merge trunk

2209. By Michael Zanetti

allow navigating the staged spreads with keyboard too

2210. By Michael Zanetti

merge prereq

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

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

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

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

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Stages/PhoneStage.qml'
2--- qml/Stages/PhoneStage.qml 2016-03-10 12:03:17 +0000
3+++ qml/Stages/PhoneStage.qml 2016-03-10 12:03:17 +0000
4@@ -44,6 +44,33 @@
5 }
6 }
7
8+ onAltTabPressedChanged: {
9+ if (!spreadEnabled || !altTabEnabled) {
10+ return;
11+ }
12+ if (altTabPressed) {
13+ spreadView.snapToSpread();
14+ priv.highlightIndex = Math.min(spreadRepeater.count - 1, 1);
15+ } else {
16+ spreadView.snapTo(priv.highlightIndex)
17+ }
18+ }
19+
20+ FocusScope {
21+ focus: root.altTabPressed
22+
23+ Keys.onPressed: {
24+ switch (event.key) {
25+ case Qt.Key_Tab:
26+ priv.highlightIndex = (priv.highlightIndex + 1) % spreadRepeater.count
27+ break;
28+ case Qt.Key_Backtab:
29+ priv.highlightIndex = (priv.highlightIndex + spreadRepeater.count - 1) % spreadRepeater.count
30+ break;
31+ }
32+ }
33+ }
34+
35 // Functions to be called from outside
36 function updateFocusedAppOrientation() {
37 if (spreadRepeater.count > 0) {
38@@ -186,6 +213,7 @@
39
40 property real oldInverseProgress: 0
41 property bool animateX: false
42+ property int highlightIndex: 0
43
44 onFocusedAppDelegateChanged: {
45 if (focusedAppDelegate) {
46@@ -220,6 +248,10 @@
47 spreadView.phase = 0;
48 spreadView.contentX = -spreadView.shift;
49 }
50+
51+ onHighlightIndexChanged: {
52+ spreadView.contentX = highlightIndex * spreadView.contentWidth / (spreadRepeater.count + 2)
53+ }
54 }
55 Timer {
56 id: fullyShowingFocusedAppUpdateTimer
57@@ -287,6 +319,11 @@
58 }
59 }
60
61+ Behavior on contentX {
62+ enabled: root.altTabPressed
63+ UbuntuNumberAnimation {}
64+ }
65+
66 onShiftedContentXChanged: {
67 if (root.beingResized) {
68 // Flickabe.contentX wiggles during resizes. Don't react to it.
69@@ -325,12 +362,17 @@
70 } else if (shiftedContentX < positionMarker3 * width) {
71 snapTo(1);
72 } else if (phase < 2){
73- // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
74- snapAnimation.targetContentX = width * positionMarker4 + 1 - shift;
75- snapAnimation.start();
76+ snapToSpread();
77 root.opened();
78 }
79 }
80+
81+ function snapToSpread() {
82+ // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
83+ snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
84+ snapAnimation.start();
85+ }
86+
87 function snapTo(index) {
88 if (!root.altTabEnabled) {
89 // Reset to start instead
90@@ -433,6 +475,7 @@
91 maximizedAppTopMargin: root.maximizedAppTopMargin
92 dropShadow: spreadView.active || priv.focusedAppDelegateIsDislocated
93 focusFirstApp: root.focusFirstApp
94+ highlightShown: root.altTabPressed && index === priv.highlightIndex
95
96 readonly property bool isDash: model.appId == "unity8-dash"
97
98@@ -665,9 +708,7 @@
99 edge: Qt.RightEdge
100
101 onPassed: {
102- // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
103- snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
104- snapAnimation.start();
105+ spreadView.snapToSpread();
106 }
107 material: Component {
108 Item {
109
110=== modified file 'qml/Stages/SpreadDelegate.qml'
111--- qml/Stages/SpreadDelegate.qml 2015-11-04 14:57:45 +0000
112+++ qml/Stages/SpreadDelegate.qml 2016-03-10 12:03:17 +0000
113@@ -43,6 +43,7 @@
114 property int shellOrientationAngle
115 property int shellOrientation
116 property QtObject orientations
117+ property bool highlightShown: false
118
119 function matchShellOrientation() {
120 if (!root.application)
121@@ -261,6 +262,25 @@
122 Behavior on opacity { UbuntuNumberAnimation {} }
123 }
124
125+ Rectangle {
126+ id: selectionHighlight
127+ objectName: "selectionHighlight"
128+ anchors.fill: appWindow
129+ anchors.margins: -units.gu(1)
130+ color: "white"
131+ opacity: root.highlightShown ? 0.15 : 0
132+ antialiasing: true
133+ visible: opacity > 0
134+ }
135+
136+ Rectangle {
137+ anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; }
138+ height: units.dp(2)
139+ color: UbuntuColors.orange
140+ visible: root.highlightShown
141+ antialiasing: true
142+ }
143+
144 ApplicationWindow {
145 id: appWindow
146 objectName: application ? "appWindow_" + application.appId : "appWindow_null"
147
148=== modified file 'qml/Stages/TabletStage.qml'
149--- qml/Stages/TabletStage.qml 2016-03-10 12:03:17 +0000
150+++ qml/Stages/TabletStage.qml 2016-03-10 12:03:17 +0000
151@@ -108,6 +108,38 @@
152 priv.oldInverseProgress = inverseProgress;
153 }
154
155+ onAltTabPressedChanged: {
156+ if (!spreadEnabled) {
157+ return;
158+ }
159+ if (altTabPressed) {
160+ priv.highlightIndex = Math.min(spreadRepeater.count - 1, 1);
161+ spreadView.snapToSpread();
162+ } else {
163+ for (var i = 0; i < spreadRepeater.count; i++) {
164+ if (spreadRepeater.itemAt(i).zIndex === priv.highlightIndex) {
165+ spreadView.snapTo(i);
166+ return;
167+ }
168+ }
169+ }
170+ }
171+
172+ FocusScope {
173+ focus: root.altTabPressed
174+
175+ Keys.onPressed: {
176+ switch (event.key) {
177+ case Qt.Key_Tab:
178+ priv.highlightIndex = (priv.highlightIndex + 1) % spreadRepeater.count
179+ break;
180+ case Qt.Key_Backtab:
181+ priv.highlightIndex = (priv.highlightIndex + spreadRepeater.count - 1) % spreadRepeater.count
182+ break;
183+ }
184+ }
185+ }
186+
187 QtObject {
188 id: priv
189 objectName: "stagesPriv"
190@@ -136,6 +168,8 @@
191
192 property int oldInverseProgress: 0
193
194+ property int highlightIndex: 0
195+
196 onFocusedAppIdChanged: {
197 if (priv.focusedAppId.length > 0) {
198 var focusedApp = ApplicationManager.findApplication(focusedAppId);
199@@ -191,6 +225,10 @@
200 }
201 return oneWayFlick;
202 }
203+
204+ onHighlightIndexChanged: {
205+ spreadView.contentX = highlightIndex * spreadView.contentWidth / (spreadRepeater.count + 2)
206+ }
207 }
208
209 Connections {
210@@ -397,11 +435,16 @@
211 } else if (shiftedContentX < phase1Width) {
212 snapTo(1);
213 } else {
214- // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
215- snapAnimation.targetContentX = spreadView.width * spreadView.positionMarker4 + 1 - shift;
216- snapAnimation.start();
217+ snapToSpread();
218 }
219 }
220+
221+ function snapToSpread() {
222+ // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
223+ snapAnimation.targetContentX = (spreadView.width * spreadView.positionMarker4) + 1 - shift;
224+ snapAnimation.start();
225+ }
226+
227 function snapTo(index) {
228 spreadView.selectedIndex = index;
229 snapAnimation.targetContentX = -shift;
230@@ -487,6 +530,11 @@
231 }
232 }
233
234+ Behavior on contentX {
235+ enabled: root.altTabPressed
236+ UbuntuNumberAnimation {}
237+ }
238+
239 MouseArea {
240 id: spreadRow
241 x: spreadView.contentX
242@@ -617,6 +665,7 @@
243 dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 && spreadView.phase === 0 ? root.inverseProgress : 0
244 application: ApplicationManager.get(index)
245 closeable: !isDash
246+ highlightShown: root.altTabPressed && priv.highlightIndex == zIndex
247
248 readonly property bool wantsMainStage: model.stage == ApplicationInfoInterface.MainStage
249
250@@ -819,9 +868,7 @@
251 edge: Qt.RightEdge
252
253 onPassed: {
254- // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
255- snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
256- snapAnimation.start();
257+ spreadView.snapToSpread();
258 }
259 material: Component {
260 Item {
261
262=== modified file 'tests/qmltests/Stages/tst_SpreadDelegate.qml'
263--- tests/qmltests/Stages/tst_SpreadDelegate.qml 2015-11-04 14:57:45 +0000
264+++ tests/qmltests/Stages/tst_SpreadDelegate.qml 2016-03-10 12:03:17 +0000
265@@ -308,5 +308,12 @@
266 tryCompare(closeAnimation, "running", false);
267 }
268
269+ function test_showHighLight() {
270+ loadWithGalleryApp.clicked();
271+ var highlightRect = findChild(spreadDelegateLoader.item, "selectionHighlight")
272+ tryCompare(highlightRect, "visible", false)
273+ spreadDelegateLoader.item.highlightShown = true;
274+ tryCompare(highlightRect, "visible", true)
275+ }
276 }
277 }
278
279=== modified file 'tests/qmltests/tst_Shell.qml'
280--- tests/qmltests/tst_Shell.qml 2016-03-10 12:03:17 +0000
281+++ tests/qmltests/tst_Shell.qml 2016-03-10 12:03:17 +0000
282@@ -1447,9 +1447,17 @@
283 tryCompare(galleryApp, "requestedState", ApplicationInfoInterface.RequestedRunning);
284 }
285
286- function test_altTabSwitchesFocus() {
287- loadShell("desktop");
288- shell.usageScenario = "desktop"
289+ function test_altTabSwitchesFocus_data() {
290+ return [
291+ { tag: "windowed", shellType: "desktop" },
292+ { tag: "staged", shellType: "phone" },
293+ { tag: "sidestaged", shellType: "tablet" }
294+ ];
295+ }
296+
297+ function test_altTabSwitchesFocus(data) {
298+ loadShell(data.shellType);
299+ shell.usageScenario = data.shellType;
300 waitForRendering(root)
301
302 var desktopStage = findChild(shell, "stage");
303@@ -1467,18 +1475,10 @@
304 keyClick(Qt.Key_Tab, Qt.AltModifier)
305 tryCompare(app2.session.lastSurface, "activeFocus", true)
306
307- var desktopSpread = findChild(shell, "spread")
308-
309- tryCompare(desktopSpread, "state", "")
310-
311- // Just press Alt, make sure the spread comes up
312+ // Press Alt+Tab
313 keyPress(Qt.Key_Alt);
314 keyClick(Qt.Key_Tab);
315- tryCompare(desktopSpread, "state", "altTab")
316-
317- // Release control, check if spread disappears
318 keyRelease(Qt.Key_Alt)
319- tryCompare(desktopSpread, "state", "")
320
321 // Focus should have switched back now
322 tryCompare(app3.session.lastSurface, "activeFocus", true)

Subscribers

People subscribed via source and target branches