on xenial help sign in
add new focus highlight, add some tests
1942930Michael Zanetti
qml/Components/PhysicalKeysMapper.qml+15−15
@@ -41,14 +41,14 @@ Item {
41 signal screenshotTriggered;
41 signal screenshotTriggered;
42
42
43 readonly property bool altTabPressed: d.altTabPressed
43 readonly property bool altTabPressed: d.altTabPressed
44− readonly property bool metaTabPressed: d.metaTabPressed
44+ readonly property bool superTabPressed: d.superTabPressed
45
45
46 property int powerKeyLongPressTime: 2000
46 property int powerKeyLongPressTime: 2000
47
47
48 // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the
48 // For testing. If running windowed (e.g. tryShell), Alt+Tab is taken by the
49 // running desktop, set this to true to use Ctrl+Tab instead.
49 // running desktop, set this to true to use Ctrl+Tab instead.
50 property bool controlInsteadOfAlt: false
50 property bool controlInsteadOfAlt: false
51− property bool controlInsteadOfMeta: false
51+ property bool controlInsteadOfSuper: false
52
52
53 QtObject {
53 QtObject {
54 id: d
54 id: d
@@ -60,14 +60,14 @@ Item {
60 property bool altPressed: false
60 property bool altPressed: false
61 property bool altTabPressed: false
61 property bool altTabPressed: false
62
62
63− property bool metaPressed: false
63+ property bool superPressed: false
64− property bool metaTabPressed: false
64+ property bool superTabPressed: false
65
65
66 property var powerButtonPressStart: 0
66 property var powerButtonPressStart: 0
67 }
67 }
68
68
69 function onKeyPressed(event, currentEventTimestamp) {
69 function onKeyPressed(event, currentEventTimestamp) {
70− print("key pressed", event.key, Qt.Key_Tab)
70+ print("key pressed", event.key, "Tab is", Qt.Key_Tab, "Meta is", Qt.Key_Meta)
71 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
71 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
72 if (event.isAutoRepeat) {
72 if (event.isAutoRepeat) {
73 if (d.powerButtonPressStart > 0
73 if (d.powerButtonPressStart > 0
@@ -104,18 +104,18 @@ Item {
104 }
104 }
105 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
105 } else if (event.key == Qt.Key_Alt || (root.controlInsteadOfAlt && event.key == Qt.Key_Control)) {
106 d.altPressed = true;
106 d.altPressed = true;
107− } else if (event.key == Qt.Key_Meta || (root.controlInsteadOfMeta && event.key == Qt.Key_Control)) {
107+ } else if (event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)) {
108 print("meta pressed")
108 print("meta pressed")
109− d.metaPressed = true;
109+ d.superPressed = true;
110 } else if (event.key == Qt.Key_Tab) {
110 } else if (event.key == Qt.Key_Tab) {
111 if (d.altPressed && !d.altTabPressed) {
111 if (d.altPressed && !d.altTabPressed) {
112 d.altTabPressed = true;
112 d.altTabPressed = true;
113 event.accepted = true;
113 event.accepted = true;
114 }
114 }
115− print("huh", d.metaPressed)
115+ print("huh", d.superPressed, d.superTabPressed)
116− if (d.metaPressed && !d.metaTabPressed) {
116+ if (d.superPressed && !d.superTabPressed) {
117− print("metaTab pressed")
117+ print("superTab pressed")
118− d.metaTabPressed = true;
118+ d.superTabPressed = true;
119 event.accepted = true;
119 event.accepted = true;
120 }
120 }
121 }
121 }
@@ -139,10 +139,10 @@ Item {
139 d.altTabPressed = false;
139 d.altTabPressed = false;
140 event.accepted = true;
140 event.accepted = true;
141 }
141 }
142− } else if (event.key == Qt.Key_Meta || (root.controlInsteadOfMeta && event.key == Qt.Key_Control)) {
142+ } else if (event.key == Qt.Key_Super_L || event.key == Qt.Key_Super_R || (root.controlInsteadOfSuper && event.key == Qt.Key_Control)) {
143− d.metaPressed = false;
143+ d.superPressed = false;
144− if (d.metaTabPressed) {
144+ if (d.superTabPressed) {
145− d.metaTabPressed = false;
145+ d.superTabPressed = false;
146 event.accepted = true;
146 event.accepted = true;
147 }
147 }
148 }
148 }
qml/Launcher/Launcher.qml+17−17
@@ -35,7 +35,7 @@ FocusScope {
35 property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
35 property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
36 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
36 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
37
37
38− property bool metaTabPressed: false
38+ property bool superTabPressed: false
39
39
40 readonly property bool dragging: dragArea.dragging
40 readonly property bool dragging: dragArea.dragging
41 readonly property real dragDistance: dragArea.dragging ? dragArea.touchX : 0
41 readonly property real dragDistance: dragArea.dragging ? dragArea.touchX : 0
@@ -60,14 +60,14 @@ FocusScope {
60 }
60 }
61 }
61 }
62
62
63− onMetaTabPressedChanged: {
63+ onSuperTabPressedChanged: {
64− if (metaTabPressed) {
64+ if (superTabPressed) {
65− print("meta tab pressed")
65+ print("super tab pressed")
66 switchToNextState("visible")
66 switchToNextState("visible")
67 panel.highlightIndex = -1;
67 panel.highlightIndex = -1;
68 root.focus = true;
68 root.focus = true;
69 } else {
69 } else {
70− print("meta tab released")
70+ print("super tab released")
71 if (panel.highlightIndex == -1) {
71 if (panel.highlightIndex == -1) {
72 showDashHome();
72 showDashHome();
73 } else if (panel.highlightIndex >= 0){
73 } else if (panel.highlightIndex >= 0){
@@ -106,6 +106,18 @@ FocusScope {
106 }
106 }
107 }
107 }
108
108
109+ GlobalShortcut {
110+// shortcut: Qt.AltModifier|Qt.Key_F1
111+ shortcut: Qt.Key_F1
112+ onTriggered: {
113+ panel.highlightIndex = -1; // The BFB
114+ root.focus = true;
115+ switchToNextState("visible")
116+ root.focus = true;
117+ print("root has focus", root.focus, root.activeFocus)
118+ }
119+ }
120+
109 Keys.onPressed: {
121 Keys.onPressed: {
110 print("blubb")
122 print("blubb")
111 switch (event.key) {
123 switch (event.key) {
@@ -154,18 +166,6 @@ FocusScope {
154 }
166 }
155 }
167 }
156
168
157− GlobalShortcut {
158−// shortcut: Qt.AltModifier|Qt.Key_F1
159− shortcut: Qt.Key_F1
160− onTriggered: {
161− panel.highlightIndex = -1; // The BFB
162− root.focus = true;
163− switchToNextState("visible")
164− root.focus = true;
165− print("root has focus", root.focus, root.activeFocus)
166− }
167− }
168−
169 Timer {
169 Timer {
170 id: teaseTimer
170 id: teaseTimer
171 interval: mode == "teasing" ? 200 : 300
171 interval: mode == "teasing" ? 200 : 300
qml/Launcher/LauncherDelegate.qml+3−4
@@ -125,12 +125,11 @@ Item {
125 height: parent.itemHeight + units.gu(1)
125 height: parent.itemHeight + units.gu(1)
126 anchors.centerIn: parent
126 anchors.centerIn: parent
127
127
128− UbuntuShape {
128+ Image {
129+ objectName: "focusRing"
129 anchors.fill: parent
130 anchors.fill: parent
130 anchors.margins: units.gu(.5)
131 anchors.margins: units.gu(.5)
131− backgroundColor: "#1986ee"
132+ source: "graphics/launcher-app-focus-ring.svg"
132− aspect: UbuntuShape.Flat
133− radius: "medium"
134 visible: root.highlighted
133 visible: root.highlighted
135 }
134 }
136
135
qml/Launcher/LauncherPanel.qml+1
@@ -76,6 +76,7 @@ Rectangle {
76 width: parent.width
76 width: parent.width
77 height: units.gu(7)
77 height: units.gu(7)
78 clip: true
78 clip: true
79+ property bool highlighted: root.highlightIndex == -1;
79
80
80 UbuntuShape {
81 UbuntuShape {
81 anchors {
82 anchors {
qml/Launcher/graphics/launcher-app-focus-ring.svgnew file+12
@@ -0,0 +1,12 @@
1+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+<svg width="187px" height="176px" viewBox="0 0 187 176" 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">
3+ <!-- Generator: Sketch 3.4.2 (15855) - http://www.bohemiancoding.com/sketch -->
4+ <title>launcher-app-focus-ring</title>
5+ <desc>Created with Sketch.</desc>
6+ <defs></defs>
7+ <g id="•-Launcher" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8+ <g id="40gu" sketch:type="MSArtboardGroup" transform="translate(-15.000000, -250.000000)" fill="#E95420">
9+ <path d="M79.1353463,254 L79.1353463,254 C50.2199442,254 38.1947414,256.685493 29.9431226,264.926849 C21.6897424,273.169965 19,285.18356 19,314.067129 L19,361.932871 C19,390.816338 21.6897456,402.829937 29.9431169,411.07307 C38.1947484,419.314466 50.2200476,422 79.1353463,422 L137.864654,422 C166.77995,422 178.805249,419.314466 187.056881,411.07307 C195.310253,402.829936 198,390.816335 198,361.932871 L198,314.067129 C198,285.183562 195.310257,273.169965 187.056875,264.926849 C178.805256,256.685493 166.780053,254 137.864654,254 L79.1353463,254 Z M79.1353463,250 L137.864654,250 C166.696254,250 180.342914,252.567901 189.883542,262.096662 C199.427539,271.628789 202,285.265604 202,314.067129 L202,361.932871 C202,390.734293 199.427535,404.371109 189.883552,413.903252 C180.342916,423.432054 166.696166,426 137.864654,426 L79.1353463,426 C50.3038315,426 36.6570818,423.432054 27.1164457,413.903252 C17.5724634,404.371109 15,390.734295 15,361.932871 L15,314.067129 C15,285.265602 17.57246,271.628789 27.116456,262.096663 C36.6570831,252.567901 50.3037433,250 79.1353463,250 L79.1353463,250 Z" id="launcher-app-focus-ring" sketch:type="MSShapeGroup"></path>
10+ </g>
11+ </g>
12+</svg>
qml/Shell.qml+1−1
@@ -550,7 +550,7 @@ Item {
550 && !greeter.hasLockedApp
550 && !greeter.hasLockedApp
551 inverted: shell.usageScenario !== "desktop"
551 inverted: shell.usageScenario !== "desktop"
552 shadeBackground: !tutorial.running
552 shadeBackground: !tutorial.running
553− metaTabPressed: physicalKeysMapper.metaTabPressed
553+ superTabPressed: physicalKeysMapper.superTabPressed
554
554
555 onShowDashHome: showHome()
555 onShowDashHome: showHome()
556 onDash: showDash()
556 onDash: showDash()
tests/qmltests/Launcher/tst_Launcher.qml+35
@@ -883,5 +883,40 @@ Item {
883 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 0)
883 LauncherModel.setCountVisible(LauncherModel.get(1).appId, 0)
884 LauncherModel.setCount(LauncherModel.get(1).appId, oldCount)
884 LauncherModel.setCount(LauncherModel.get(1).appId, oldCount)
885 }
885 }
886+
887+ function test_focusRingFollowsHighlightIndex() {
888+ var bfb = findChild(launcher, "buttonShowDashHome");
889+ var focusRing0 = findChild(findChild(launcher, "launcherDelegate0"), "focusRing");
890+ var focusRing1 = findChild(findChild(launcher, "launcherDelegate1"), "focusRing");
891+ var focusRing2 = findChild(findChild(launcher, "launcherDelegate2"), "focusRing");
892+
893+ compare(bfb.highlighted, false);
894+ compare(focusRing0.visible, false);
895+ compare(focusRing1.visible, false);
896+ compare(focusRing2.visible, false);
897+
898+ launcher.superTabPressed = true;
899+ tryCompare(bfb, "highlighted", true);
900+ keyClick(Qt.Key_Tab);
901+ tryCompare(bfb, "highlighted", false);
902+ tryCompare(focusRing0, "visible", true);
903+ keyClick(Qt.Key_Tab);
904+ tryCompare(focusRing0, "visible", false);
905+ tryCompare(focusRing1, "visible", true);
906+ keyClick(Qt.Key_Tab);
907+ tryCompare(focusRing1, "visible", false);
908+ tryCompare(focusRing2, "visible", true);
909+
910+ keyClick(Qt.Key_Backtab);
911+ tryCompare(focusRing2, "visible", false);
912+ tryCompare(focusRing1, "visible", true);
913+ keyClick(Qt.Key_Backtab);
914+ tryCompare(focusRing1, "visible", false);
915+ tryCompare(focusRing0, "visible", true);
916+ keyClick(Qt.Key_Backtab);
917+ tryCompare(focusRing1, "visible", false);
918+ tryCompare(focusRing1, "visible", true);
919+ tryCompare(bfb, "highlighted", true);
920+ }
886 }
921 }
887}
922}
tests/qmltests/tst_Shell.qml+40−2
@@ -26,6 +26,7 @@ import Unity.Application 0.1
26import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
27import Unity.Indicators 0.1
27import Unity.Indicators 0.1
28import Unity.Notifications 1.0
28import Unity.Notifications 1.0
29+import Unity.Launcher 0.1
29import Unity.Test 0.1
30import Unity.Test 0.1
30import Powerd 0.1
31import Powerd 0.1
31import Wizard 0.1 as Wizard
32import Wizard 0.1 as Wizard
@@ -209,11 +210,11 @@ Rectangle {
209 anchors { left: parent.left; right: parent.right }
210 anchors { left: parent.left; right: parent.right }
210 activeFocusOnPress: false
211 activeFocusOnPress: false
211 text: "Ctrl key as"
212 text: "Ctrl key as"
212− model: ["Ctrl", "Alt", "Meta"]
213+ model: ["Ctrl", "Alt", "Super"]
213 onSelectedIndexChanged: {
214 onSelectedIndexChanged: {
214 var keyMapper = testCase.findChild(shellContainer, "physicalKeysMapper");
215 var keyMapper = testCase.findChild(shellContainer, "physicalKeysMapper");
215 keyMapper.controlInsteadOfAlt = selectedIndex == 1;
216 keyMapper.controlInsteadOfAlt = selectedIndex == 1;
216− keyMapper.controlInsteadOfMeta = selectedIndex == 2;
217+ keyMapper.controlInsteadOfSuper = selectedIndex == 2;
217 }
218 }
218 }
219 }
219
220
@@ -1861,5 +1862,42 @@ Rectangle {
1861 compare(app1.session.surface.activeFocus, false);
1862 compare(app1.session.surface.activeFocus, false);
1862 compare(app1.requestedState, ApplicationInfoInterface.RequestedRunning);
1863 compare(app1.requestedState, ApplicationInfoInterface.RequestedRunning);
1863 }
1864 }
1865+
1866+ function test_superTabToCycleLauncher() {
1867+ loadShell("desktop");
1868+ shell.usageScenario = "desktop";
1869+
1870+ var launcher = findChild(shell, "launcher");
1871+ var launcherPanel = findChild(launcher, "launcherPanel");
1872+ var firstAppInLauncher = LauncherModel.get(0).appId;
1873+
1874+ compare(launcher.state, "");
1875+ compare(launcherPanel.highlightIndex, -2);
1876+ compare(ApplicationManager.focusedApplicationId, "unity8-dash");
1877+
1878+ // Use Super + Tab Tab to cycle to the first entry in the launcher
1879+ keyPress(Qt.Key_Super_L);
1880+ keyClick(Qt.Key_Tab);
1881+ tryCompare(launcher, "state", "visible");
1882+ tryCompare(launcherPanel, "highlightIndex", -1);
1883+ keyClick(Qt.Key_Tab);
1884+ tryCompare(launcherPanel, "highlightIndex", 0);
1885+ keyRelease(Qt.Key_Super_L);
1886+ tryCompare(launcher, "state", "");
1887+ tryCompare(launcherPanel, "highlightIndex", -2);
1888+ tryCompare(ApplicationManager, "focusedApplicationId", firstAppInLauncher);
1889+
1890+ // No go back to the dash
1891+ keyPress(Qt.Key_Super_L);
1892+ keyClick(Qt.Key_Tab);
1893+ tryCompare(launcher, "state", "visible");
1894+ tryCompare(launcherPanel, "highlightIndex", -1);
1895+ keyRelease(Qt.Key_Super_L);
1896+ tryCompare(launcher, "state", "");
1897+ tryCompare(launcherPanel, "highlightIndex", -2);
1898+ tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
1899+
1900+
1901+ }
1864 }
1902 }
1865}
1903}