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
=== modified file 'qml/Stages/PhoneStage.qml'
--- qml/Stages/PhoneStage.qml 2016-03-10 12:03:17 +0000
+++ qml/Stages/PhoneStage.qml 2016-03-10 12:03:17 +0000
@@ -44,6 +44,33 @@
44 }44 }
45 }45 }
4646
47 onAltTabPressedChanged: {
48 if (!spreadEnabled || !altTabEnabled) {
49 return;
50 }
51 if (altTabPressed) {
52 spreadView.snapToSpread();
53 priv.highlightIndex = Math.min(spreadRepeater.count - 1, 1);
54 } else {
55 spreadView.snapTo(priv.highlightIndex)
56 }
57 }
58
59 FocusScope {
60 focus: root.altTabPressed
61
62 Keys.onPressed: {
63 switch (event.key) {
64 case Qt.Key_Tab:
65 priv.highlightIndex = (priv.highlightIndex + 1) % spreadRepeater.count
66 break;
67 case Qt.Key_Backtab:
68 priv.highlightIndex = (priv.highlightIndex + spreadRepeater.count - 1) % spreadRepeater.count
69 break;
70 }
71 }
72 }
73
47 // Functions to be called from outside74 // Functions to be called from outside
48 function updateFocusedAppOrientation() {75 function updateFocusedAppOrientation() {
49 if (spreadRepeater.count > 0) {76 if (spreadRepeater.count > 0) {
@@ -186,6 +213,7 @@
186213
187 property real oldInverseProgress: 0214 property real oldInverseProgress: 0
188 property bool animateX: false215 property bool animateX: false
216 property int highlightIndex: 0
189217
190 onFocusedAppDelegateChanged: {218 onFocusedAppDelegateChanged: {
191 if (focusedAppDelegate) {219 if (focusedAppDelegate) {
@@ -220,6 +248,10 @@
220 spreadView.phase = 0;248 spreadView.phase = 0;
221 spreadView.contentX = -spreadView.shift;249 spreadView.contentX = -spreadView.shift;
222 }250 }
251
252 onHighlightIndexChanged: {
253 spreadView.contentX = highlightIndex * spreadView.contentWidth / (spreadRepeater.count + 2)
254 }
223 }255 }
224 Timer {256 Timer {
225 id: fullyShowingFocusedAppUpdateTimer257 id: fullyShowingFocusedAppUpdateTimer
@@ -287,6 +319,11 @@
287 }319 }
288 }320 }
289321
322 Behavior on contentX {
323 enabled: root.altTabPressed
324 UbuntuNumberAnimation {}
325 }
326
290 onShiftedContentXChanged: {327 onShiftedContentXChanged: {
291 if (root.beingResized) {328 if (root.beingResized) {
292 // Flickabe.contentX wiggles during resizes. Don't react to it.329 // Flickabe.contentX wiggles during resizes. Don't react to it.
@@ -325,12 +362,17 @@
325 } else if (shiftedContentX < positionMarker3 * width) {362 } else if (shiftedContentX < positionMarker3 * width) {
326 snapTo(1);363 snapTo(1);
327 } else if (phase < 2){364 } else if (phase < 2){
328 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.365 snapToSpread();
329 snapAnimation.targetContentX = width * positionMarker4 + 1 - shift;
330 snapAnimation.start();
331 root.opened();366 root.opened();
332 }367 }
333 }368 }
369
370 function snapToSpread() {
371 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
372 snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
373 snapAnimation.start();
374 }
375
334 function snapTo(index) {376 function snapTo(index) {
335 if (!root.altTabEnabled) {377 if (!root.altTabEnabled) {
336 // Reset to start instead378 // Reset to start instead
@@ -433,6 +475,7 @@
433 maximizedAppTopMargin: root.maximizedAppTopMargin475 maximizedAppTopMargin: root.maximizedAppTopMargin
434 dropShadow: spreadView.active || priv.focusedAppDelegateIsDislocated476 dropShadow: spreadView.active || priv.focusedAppDelegateIsDislocated
435 focusFirstApp: root.focusFirstApp477 focusFirstApp: root.focusFirstApp
478 highlightShown: root.altTabPressed && index === priv.highlightIndex
436479
437 readonly property bool isDash: model.appId == "unity8-dash"480 readonly property bool isDash: model.appId == "unity8-dash"
438481
@@ -665,9 +708,7 @@
665 edge: Qt.RightEdge708 edge: Qt.RightEdge
666709
667 onPassed: {710 onPassed: {
668 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.711 spreadView.snapToSpread();
669 snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
670 snapAnimation.start();
671 }712 }
672 material: Component {713 material: Component {
673 Item {714 Item {
674715
=== modified file 'qml/Stages/SpreadDelegate.qml'
--- qml/Stages/SpreadDelegate.qml 2015-11-04 14:57:45 +0000
+++ qml/Stages/SpreadDelegate.qml 2016-03-10 12:03:17 +0000
@@ -43,6 +43,7 @@
43 property int shellOrientationAngle43 property int shellOrientationAngle
44 property int shellOrientation44 property int shellOrientation
45 property QtObject orientations45 property QtObject orientations
46 property bool highlightShown: false
4647
47 function matchShellOrientation() {48 function matchShellOrientation() {
48 if (!root.application)49 if (!root.application)
@@ -261,6 +262,25 @@
261 Behavior on opacity { UbuntuNumberAnimation {} }262 Behavior on opacity { UbuntuNumberAnimation {} }
262 }263 }
263264
265 Rectangle {
266 id: selectionHighlight
267 objectName: "selectionHighlight"
268 anchors.fill: appWindow
269 anchors.margins: -units.gu(1)
270 color: "white"
271 opacity: root.highlightShown ? 0.15 : 0
272 antialiasing: true
273 visible: opacity > 0
274 }
275
276 Rectangle {
277 anchors { left: selectionHighlight.left; right: selectionHighlight.right; bottom: selectionHighlight.bottom; }
278 height: units.dp(2)
279 color: UbuntuColors.orange
280 visible: root.highlightShown
281 antialiasing: true
282 }
283
264 ApplicationWindow {284 ApplicationWindow {
265 id: appWindow285 id: appWindow
266 objectName: application ? "appWindow_" + application.appId : "appWindow_null"286 objectName: application ? "appWindow_" + application.appId : "appWindow_null"
267287
=== modified file 'qml/Stages/TabletStage.qml'
--- qml/Stages/TabletStage.qml 2016-03-10 12:03:17 +0000
+++ qml/Stages/TabletStage.qml 2016-03-10 12:03:17 +0000
@@ -108,6 +108,38 @@
108 priv.oldInverseProgress = inverseProgress;108 priv.oldInverseProgress = inverseProgress;
109 }109 }
110110
111 onAltTabPressedChanged: {
112 if (!spreadEnabled) {
113 return;
114 }
115 if (altTabPressed) {
116 priv.highlightIndex = Math.min(spreadRepeater.count - 1, 1);
117 spreadView.snapToSpread();
118 } else {
119 for (var i = 0; i < spreadRepeater.count; i++) {
120 if (spreadRepeater.itemAt(i).zIndex === priv.highlightIndex) {
121 spreadView.snapTo(i);
122 return;
123 }
124 }
125 }
126 }
127
128 FocusScope {
129 focus: root.altTabPressed
130
131 Keys.onPressed: {
132 switch (event.key) {
133 case Qt.Key_Tab:
134 priv.highlightIndex = (priv.highlightIndex + 1) % spreadRepeater.count
135 break;
136 case Qt.Key_Backtab:
137 priv.highlightIndex = (priv.highlightIndex + spreadRepeater.count - 1) % spreadRepeater.count
138 break;
139 }
140 }
141 }
142
111 QtObject {143 QtObject {
112 id: priv144 id: priv
113 objectName: "stagesPriv"145 objectName: "stagesPriv"
@@ -136,6 +168,8 @@
136168
137 property int oldInverseProgress: 0169 property int oldInverseProgress: 0
138170
171 property int highlightIndex: 0
172
139 onFocusedAppIdChanged: {173 onFocusedAppIdChanged: {
140 if (priv.focusedAppId.length > 0) {174 if (priv.focusedAppId.length > 0) {
141 var focusedApp = ApplicationManager.findApplication(focusedAppId);175 var focusedApp = ApplicationManager.findApplication(focusedAppId);
@@ -191,6 +225,10 @@
191 }225 }
192 return oneWayFlick;226 return oneWayFlick;
193 }227 }
228
229 onHighlightIndexChanged: {
230 spreadView.contentX = highlightIndex * spreadView.contentWidth / (spreadRepeater.count + 2)
231 }
194 }232 }
195233
196 Connections {234 Connections {
@@ -397,11 +435,16 @@
397 } else if (shiftedContentX < phase1Width) {435 } else if (shiftedContentX < phase1Width) {
398 snapTo(1);436 snapTo(1);
399 } else {437 } else {
400 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.438 snapToSpread();
401 snapAnimation.targetContentX = spreadView.width * spreadView.positionMarker4 + 1 - shift;
402 snapAnimation.start();
403 }439 }
404 }440 }
441
442 function snapToSpread() {
443 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.
444 snapAnimation.targetContentX = (spreadView.width * spreadView.positionMarker4) + 1 - shift;
445 snapAnimation.start();
446 }
447
405 function snapTo(index) {448 function snapTo(index) {
406 spreadView.selectedIndex = index;449 spreadView.selectedIndex = index;
407 snapAnimation.targetContentX = -shift;450 snapAnimation.targetContentX = -shift;
@@ -487,6 +530,11 @@
487 }530 }
488 }531 }
489532
533 Behavior on contentX {
534 enabled: root.altTabPressed
535 UbuntuNumberAnimation {}
536 }
537
490 MouseArea {538 MouseArea {
491 id: spreadRow539 id: spreadRow
492 x: spreadView.contentX540 x: spreadView.contentX
@@ -617,6 +665,7 @@
617 dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 && spreadView.phase === 0 ? root.inverseProgress : 0665 dragOffset: !isDash && model.appId == priv.mainStageAppId && root.inverseProgress > 0 && spreadView.phase === 0 ? root.inverseProgress : 0
618 application: ApplicationManager.get(index)666 application: ApplicationManager.get(index)
619 closeable: !isDash667 closeable: !isDash
668 highlightShown: root.altTabPressed && priv.highlightIndex == zIndex
620669
621 readonly property bool wantsMainStage: model.stage == ApplicationInfoInterface.MainStage670 readonly property bool wantsMainStage: model.stage == ApplicationInfoInterface.MainStage
622671
@@ -819,9 +868,7 @@
819 edge: Qt.RightEdge868 edge: Qt.RightEdge
820869
821 onPassed: {870 onPassed: {
822 // Add 1 pixel to make sure we definitely hit positionMarker4 even with rounding errors of the animation.871 spreadView.snapToSpread();
823 snapAnimation.targetContentX = (root.width * spreadView.positionMarker4) + 1 - spreadView.shift;
824 snapAnimation.start();
825 }872 }
826 material: Component {873 material: Component {
827 Item {874 Item {
828875
=== modified file 'tests/qmltests/Stages/tst_SpreadDelegate.qml'
--- tests/qmltests/Stages/tst_SpreadDelegate.qml 2015-11-04 14:57:45 +0000
+++ tests/qmltests/Stages/tst_SpreadDelegate.qml 2016-03-10 12:03:17 +0000
@@ -308,5 +308,12 @@
308 tryCompare(closeAnimation, "running", false);308 tryCompare(closeAnimation, "running", false);
309 }309 }
310310
311 function test_showHighLight() {
312 loadWithGalleryApp.clicked();
313 var highlightRect = findChild(spreadDelegateLoader.item, "selectionHighlight")
314 tryCompare(highlightRect, "visible", false)
315 spreadDelegateLoader.item.highlightShown = true;
316 tryCompare(highlightRect, "visible", true)
317 }
311 }318 }
312}319}
313320
=== modified file 'tests/qmltests/tst_Shell.qml'
--- tests/qmltests/tst_Shell.qml 2016-03-10 12:03:17 +0000
+++ tests/qmltests/tst_Shell.qml 2016-03-10 12:03:17 +0000
@@ -1447,9 +1447,17 @@
1447 tryCompare(galleryApp, "requestedState", ApplicationInfoInterface.RequestedRunning);1447 tryCompare(galleryApp, "requestedState", ApplicationInfoInterface.RequestedRunning);
1448 }1448 }
14491449
1450 function test_altTabSwitchesFocus() {1450 function test_altTabSwitchesFocus_data() {
1451 loadShell("desktop");1451 return [
1452 shell.usageScenario = "desktop"1452 { tag: "windowed", shellType: "desktop" },
1453 { tag: "staged", shellType: "phone" },
1454 { tag: "sidestaged", shellType: "tablet" }
1455 ];
1456 }
1457
1458 function test_altTabSwitchesFocus(data) {
1459 loadShell(data.shellType);
1460 shell.usageScenario = data.shellType;
1453 waitForRendering(root)1461 waitForRendering(root)
14541462
1455 var desktopStage = findChild(shell, "stage");1463 var desktopStage = findChild(shell, "stage");
@@ -1467,18 +1475,10 @@
1467 keyClick(Qt.Key_Tab, Qt.AltModifier)1475 keyClick(Qt.Key_Tab, Qt.AltModifier)
1468 tryCompare(app2.session.lastSurface, "activeFocus", true)1476 tryCompare(app2.session.lastSurface, "activeFocus", true)
14691477
1470 var desktopSpread = findChild(shell, "spread")1478 // Press Alt+Tab
1471
1472 tryCompare(desktopSpread, "state", "")
1473
1474 // Just press Alt, make sure the spread comes up
1475 keyPress(Qt.Key_Alt);1479 keyPress(Qt.Key_Alt);
1476 keyClick(Qt.Key_Tab);1480 keyClick(Qt.Key_Tab);
1477 tryCompare(desktopSpread, "state", "altTab")
1478
1479 // Release control, check if spread disappears
1480 keyRelease(Qt.Key_Alt)1481 keyRelease(Qt.Key_Alt)
1481 tryCompare(desktopSpread, "state", "")
14821482
1483 // Focus should have switched back now1483 // Focus should have switched back now
1484 tryCompare(app3.session.lastSurface, "activeFocus", true)1484 tryCompare(app3.session.lastSurface, "activeFocus", true)

Subscribers

People subscribed via source and target branches