on xenial help sign in
a first cut on implementing the new design requirements in the Launcher
bd9f0c1Michael Zanetti
qml/Components/PhysicalKeysMapper.qml+21
@@ -41,12 +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
45
45 property int powerKeyLongPressTime: 2000
46 property int powerKeyLongPressTime: 2000
46
47
47 // 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
48 // running desktop, set this to true to use Ctrl+Tab instead.
49 // running desktop, set this to true to use Ctrl+Tab instead.
49 property bool controlInsteadOfAlt: false
50 property bool controlInsteadOfAlt: false
51+ property bool controlInsteadOfMeta: false
50
52
51 QtObject {
53 QtObject {
52 id: d
54 id: d
@@ -58,10 +60,14 @@ Item {
58 property bool altPressed: false
60 property bool altPressed: false
59 property bool altTabPressed: false
61 property bool altTabPressed: false
60
62
63+ property bool metaPressed: false
64+ property bool metaTabPressed: false
65+
61 property var powerButtonPressStart: 0
66 property var powerButtonPressStart: 0
62 }
67 }
63
68
64 function onKeyPressed(event, currentEventTimestamp) {
69 function onKeyPressed(event, currentEventTimestamp) {
70+ print("key pressed", event.key, Qt.Key_Tab)
65 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
71 if (event.key == Qt.Key_PowerDown || event.key == Qt.Key_PowerOff) {
66 if (event.isAutoRepeat) {
72 if (event.isAutoRepeat) {
67 if (d.powerButtonPressStart > 0
73 if (d.powerButtonPressStart > 0
@@ -98,11 +104,20 @@ Item {
98 }
104 }
99 } 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)) {
100 d.altPressed = true;
106 d.altPressed = true;
107+ } else if (event.key == Qt.Key_Meta || (root.controlInsteadOfMeta && event.key == Qt.Key_Control)) {
108+ print("meta pressed")
109+ d.metaPressed = true;
101 } else if (event.key == Qt.Key_Tab) {
110 } else if (event.key == Qt.Key_Tab) {
102 if (d.altPressed && !d.altTabPressed) {
111 if (d.altPressed && !d.altTabPressed) {
103 d.altTabPressed = true;
112 d.altTabPressed = true;
104 event.accepted = true;
113 event.accepted = true;
105 }
114 }
115+ print("huh", d.metaPressed)
116+ if (d.metaPressed && !d.metaTabPressed) {
117+ print("metaTab pressed")
118+ d.metaTabPressed = true;
119+ event.accepted = true;
120+ }
106 }
121 }
107 }
122 }
108
123
@@ -124,6 +139,12 @@ Item {
124 d.altTabPressed = false;
139 d.altTabPressed = false;
125 event.accepted = true;
140 event.accepted = true;
126 }
141 }
142+ } else if (event.key == Qt.Key_Meta || (root.controlInsteadOfMeta && event.key == Qt.Key_Control)) {
143+ d.metaPressed = false;
144+ if (d.metaTabPressed) {
145+ d.metaTabPressed = false;
146+ event.accepted = true;
147+ }
127 }
148 }
128 }
149 }
129}
150}
qml/Launcher/Launcher.qml+83−1
@@ -19,8 +19,9 @@ import "../Components"
19import Ubuntu.Components 1.3
19import Ubuntu.Components 1.3
20import Ubuntu.Gestures 0.1
20import Ubuntu.Gestures 0.1
21import Unity.Launcher 0.1
21import Unity.Launcher 0.1
22+import GlobalShortcut 1.0
22
23
23−Item {
24+FocusScope {
24 id: root
25 id: root
25
26
26 property bool autohideEnabled: false
27 property bool autohideEnabled: false
@@ -34,6 +35,8 @@ Item {
34 property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
35 property real progress: dragArea.dragging && dragArea.touchX > panelWidth ?
35 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
36 (width * (dragArea.touchX-panelWidth) / (width - panelWidth)) : 0
36
37
38+ property bool metaTabPressed: false
39+
37 readonly property bool dragging: dragArea.dragging
40 readonly property bool dragging: dragArea.dragging
38 readonly property real dragDistance: dragArea.dragging ? dragArea.touchX : 0
41 readonly property real dragDistance: dragArea.dragging ? dragArea.touchX : 0
39 readonly property real visibleWidth: panel.width + panel.x
42 readonly property real visibleWidth: panel.width + panel.x
@@ -57,6 +60,25 @@ Item {
57 }
60 }
58 }
61 }
59
62
63+ onMetaTabPressedChanged: {
64+ if (metaTabPressed) {
65+ print("meta tab pressed")
66+ switchToNextState("visible")
67+ panel.highlightIndex = -1;
68+ root.focus = true;
69+ } else {
70+ print("meta tab released")
71+ if (panel.highlightIndex == -1) {
72+ showDashHome();
73+ } else if (panel.highlightIndex >= 0){
74+ launcherApplicationSelected(LauncherModel.get(panel.highlightIndex).appId);
75+ }
76+ panel.highlightIndex = -2;
77+ switchToNextState("");
78+ root.focus = false;
79+ }
80+ }
81+
60 function hide() {
82 function hide() {
61 switchToNextState("")
83 switchToNextState("")
62 }
84 }
@@ -84,6 +106,66 @@ Item {
84 }
106 }
85 }
107 }
86
108
109+ Keys.onPressed: {
110+ print("blubb")
111+ switch (event.key) {
112+ case Qt.Key_Backtab:
113+ panel.highlightPrevious();
114+ event.accepted = true;
115+ break;
116+ case Qt.Key_Up:
117+ if (root.inverted) {
118+ panel.highlightNext()
119+ } else {
120+ panel.highlightPrevious();
121+ }
122+ event.accepted = true;
123+ break;
124+ case Qt.Key_Tab:
125+ panel.highlightNext();
126+ event.accepted = true;
127+ break;
128+ case Qt.Key_Down:
129+ if (root.inverted) {
130+ panel.highlightPrevious();
131+ } else {
132+ panel.highlightNext();
133+ }
134+ event.accepted = true;
135+ break;
136+ case Qt.Key_Right:
137+ panel.openQuicklist(panel.highlightIndex)
138+ event.accepted = true;
139+ break;
140+ case Qt.Key_Escape:
141+ panel.highlightIndex = -2
142+ // Falling through intentionally
143+ case Qt.Key_Enter:
144+ case Qt.Key_Return:
145+ case Qt.Key_Space:
146+ if (panel.highlightIndex == -1) {
147+ showDashHome();
148+ } else if (panel.highlightIndex >= 0) {
149+ launcherApplicationSelected(LauncherModel.get(panel.highlightIndex).appId);
150+ }
151+ root.state = ""
152+ event.accepted = true;
153+ root.focus = false;
154+ }
155+ }
156+
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+
87 Timer {
169 Timer {
88 id: teaseTimer
170 id: teaseTimer
89 interval: mode == "teasing" ? 200 : 300
171 interval: mode == "teasing" ? 200 : 300
qml/Launcher/LauncherDelegate.qml+25−9
@@ -29,7 +29,7 @@ Item {
29 property real maxAngle: 0
29 property real maxAngle: 0
30 property bool inverted: false
30 property bool inverted: false
31 property bool alerting: false
31 property bool alerting: false
32− readonly property alias wiggling: wiggleAnim.running
32+ property bool highlighted: false
33
33
34 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
34 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
35 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
35 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
@@ -125,6 +125,15 @@ 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 {
129+ anchors.fill: parent
130+ anchors.margins: units.gu(.5)
131+ backgroundColor: "#1986ee"
132+ aspect: UbuntuShape.Flat
133+ radius: "medium"
134+ visible: root.highlighted
135+ }
136+
128 UbuntuShape {
137 UbuntuShape {
129 id: iconShape
138 id: iconShape
130 anchors.fill: parent
139 anchors.fill: parent
@@ -216,25 +225,32 @@ Item {
216 }
225 }
217 }
226 }
218
227
219− Image {
228+ Column {
220− objectName: "runningHighlight"
221 anchors {
229 anchors {
222 left: parent.left
230 left: parent.left
223 verticalCenter: parent.verticalCenter
231 verticalCenter: parent.verticalCenter
224 }
232 }
233+ spacing: units.gu(.5)
234+ Repeater {
235+ model: 1
236+ Rectangle {
237+ width: units.gu(0.25)
238+ height: units.gu(.5)
239+ color: "white"
225− visible: root.itemRunning
240+ visible: root.itemRunning
226− rotation: 180
241+ }
227− source: "graphics/focused_app_arrow.png"
242+ }
228 }
243 }
229
244
230− Image {
245+ Rectangle {
231− objectName: "focusedHighlight"
232 anchors {
246 anchors {
233 right: parent.right
247 right: parent.right
234 verticalCenter: parent.verticalCenter
248 verticalCenter: parent.verticalCenter
235 }
249 }
250+ width: units.gu(0.25)
251+ height: units.gu(.5)
252+ color: "white"
236 visible: root.itemFocused
253 visible: root.itemFocused
237− source: "graphics/focused_app_arrow.png"
238 }
254 }
239 }
255 }
240
256
qml/Launcher/LauncherPanel.qml+80−18
@@ -19,6 +19,7 @@ import Ubuntu.Components 1.3
19import Ubuntu.Components.ListItems 1.3 as ListItems
19import Ubuntu.Components.ListItems 1.3 as ListItems
20import Unity.Launcher 0.1
20import Unity.Launcher 0.1
21import Ubuntu.Components.Popups 1.3
21import Ubuntu.Components.Popups 1.3
22+import GlobalShortcut 1.0
22import "../Components/ListItems"
23import "../Components/ListItems"
23import "../Components/"
24import "../Components/"
24
25
@@ -33,7 +34,7 @@ Rectangle {
33 property bool dragging: false
34 property bool dragging: false
34 property bool moving: launcherListView.moving || launcherListView.flicking
35 property bool moving: launcherListView.moving || launcherListView.flicking
35 property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
36 property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
36− property int highlightIndex: -1
37+ property int highlightIndex: -2
37
38
38 signal applicationSelected(string appId)
39 signal applicationSelected(string appId)
39 signal showDashHome()
40 signal showDashHome()
@@ -44,6 +45,26 @@ Rectangle {
44 }
45 }
45 }
46 }
46
47
48+ function highlightNext() {
49+ highlightIndex++;
50+ if (highlightIndex >= launcherListView.count) {
51+ highlightIndex = -1;
52+ }
53+ moveAnimation.moveToIndex(Math.max(highlightIndex, 0));
54+ }
55+ function highlightPrevious() {
56+ highlightIndex--;
57+ if (highlightIndex <= -2) {
58+ highlightIndex = launcherListView.count - 1;
59+ }
60+ moveAnimation.moveToIndex(Math.max(highlightIndex, 0));
61+ }
62+ function openQuicklist(index) {
63+ quickList.open(index);
64+ quickList.selectedIndex = 0;
65+ quickList.focus = true;
66+ }
67+
47 Column {
68 Column {
48 id: mainColumn
69 id: mainColumn
49 anchors {
70 anchors {
@@ -172,6 +193,16 @@ Rectangle {
172 to = contentY;
193 to = contentY;
173 start();
194 start();
174 }
195 }
196+ function moveToIndex(index) {
197+ var itemPosition = index * launcherListView.itemHeight;
198+ var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin
199+ var distanceToEnd = index == 0 || index == launcherListView.count - 1 ? 0 : launcherListView.itemHeight
200+ if (itemPosition + launcherListView.itemHeight + distanceToEnd > launcherListView.contentY + launcherListView.topMargin + height) {
201+ moveAnimation.moveTo(itemPosition + launcherListView.itemHeight - launcherListView.topMargin - height + distanceToEnd);
202+ } else if (itemPosition - distanceToEnd < launcherListView.contentY + launcherListView.topMargin) {
203+ moveAnimation.moveTo(itemPosition - distanceToEnd - launcherListView.topMargin);
204+ }
205+ }
175 }
206 }
176
207
177 displaced: Transition {
208 displaced: Transition {
@@ -197,6 +228,7 @@ Rectangle {
197 itemFocused: model.focused
228 itemFocused: model.focused
198 inverted: root.inverted
229 inverted: root.inverted
199 alerting: model.alerting
230 alerting: model.alerting
231+ highlighted: root.highlightIndex == index
200 z: -Math.abs(offset)
232 z: -Math.abs(offset)
201 maxAngle: 55
233 maxAngle: 55
202 property bool dragging: false
234 property bool dragging: false
@@ -234,14 +266,7 @@ Rectangle {
234 onAlertingChanged: {
266 onAlertingChanged: {
235 if(alerting) {
267 if(alerting) {
236 if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) {
268 if (!dragging && (launcherListView.peekingIndex === -1 || launcher.visibleWidth > 0)) {
237− var itemPosition = index * launcherListView.itemHeight;
269+ moveAnimation.moveToIndex(index)
238− var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin
239− var distanceToEnd = index == 0 || index == launcherListView.count - 1 ? 0 : launcherListView.itemHeight
240− if (itemPosition + launcherListView.itemHeight + distanceToEnd > launcherListView.contentY + launcherListView.topMargin + height) {
241− moveAnimation.moveTo(itemPosition + launcherListView.itemHeight - launcherListView.topMargin - height + distanceToEnd);
242− } else if (itemPosition - distanceToEnd < launcherListView.contentY + launcherListView.topMargin) {
243− moveAnimation.moveTo(itemPosition - distanceToEnd - launcherListView.topMargin);
244− }
245 if (!dragging && launcher.state !== "visible") {
270 if (!dragging && launcher.state !== "visible") {
246 peekingAnimation.start()
271 peekingAnimation.start()
247 }
272 }
@@ -392,10 +417,7 @@ Rectangle {
392
417
393 if (mouse.button & Qt.RightButton) { // context menu
418 if (mouse.button & Qt.RightButton) { // context menu
394 // Opening QuickList
419 // Opening QuickList
395− quickList.item = clickedItem;
420+ quickList.open(index);
396− quickList.model = launcherListView.model.get(index).quickList;
397− quickList.appId = launcherListView.model.get(index).appId;
398− quickList.state = "open";
399 return
421 return
400 }
422 }
401
423
@@ -465,11 +487,7 @@ Rectangle {
465
487
466 draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
488 draggedIndex = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
467
489
468− // Opening QuickList
469− quickList.item = selectedItem;
470− quickList.model = launcherListView.model.get(draggedIndex).quickList;
471− quickList.appId = launcherListView.model.get(draggedIndex).appId;
472− quickList.state = "open";
490+ quickList.open(draggedIndex)
473
491
474 launcherListView.interactive = false
492 launcherListView.interactive = false
475
493
@@ -647,12 +665,55 @@ Rectangle {
647 property var model
665 property var model
648 property string appId
666 property string appId
649 property var item
667 property var item
668+ property int selectedIndex: -1
669+
670+ Keys.onPressed: {
671+ switch (event.key) {
672+ case Qt.Key_Down:
673+ selectedIndex++;
674+ if (selectedIndex >= popoverRepeater.count) {
675+ selectedIndex = 0;
676+ }
677+ event.accepted = true;
678+ break;
679+ case Qt.Key_Up:
680+ selectedIndex--;
681+ if (selectedIndex < 0) {
682+ selectedIndex = popoverRepeater.count - 1;
683+ }
684+ event.accepted = true;
685+ break;
686+ case Qt.Key_Left:
687+ case Qt.Key_Escape:
688+ quickList.selectedIndex = -1;
689+ // Falling through intentionally
690+ case Qt.Key_Enter:
691+ case Qt.Key_Return:
692+ case Qt.Key_Space:
693+ if (quickList.selectedIndex >= 0) {
694+ LauncherModel.quickListActionInvoked(quickList.appId, quickList.selectedIndex)
695+ }
696+ quickList.focus = false;
697+ quickList.state = ""
698+ // Don't consume the event. We want to close the Launcher too, not just the quicklist.
699+ break;
700+ }
701+ }
650
702
651 // internal
703 // internal
652 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
704 property int itemCenter: item ? root.mapFromItem(quickList.item).y + (item.height / 2) : units.gu(1)
653 property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
705 property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
654 itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
706 itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
655
707
708+ function open(index) {
709+ var itemPosition = index * launcherListView.itemHeight;
710+ var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin
711+ item = launcherListView.itemAt(launcherListView.width / 2, itemPosition + launcherListView.itemHeight / 2);
712+ quickList.model = launcherListView.model.get(index).quickList;
713+ quickList.appId = launcherListView.model.get(index).appId;
714+ quickList.state = "open";
715+ }
716+
656 Column {
717 Column {
657 id: quickListColumn
718 id: quickListColumn
658 width: parent.width
719 width: parent.width
@@ -666,6 +727,7 @@ Rectangle {
666 objectName: "quickListEntry" + index
727 objectName: "quickListEntry" + index
667 text: (model.clickable ? "" : "<b>") + model.label + (model.clickable ? "" : "</b>")
728 text: (model.clickable ? "" : "<b>") + model.label + (model.clickable ? "" : "</b>")
668 highlightWhenPressed: model.clickable
729 highlightWhenPressed: model.clickable
730+ selected: index === quickList.selectedIndex
669
731
670 // FIXME: This is a workaround for the theme not being context sensitive. I.e. the
732 // FIXME: This is a workaround for the theme not being context sensitive. I.e. the
671 // ListItems don't know that they are sitting in a themed Popover where the color
733 // ListItems don't know that they are sitting in a themed Popover where the color
qml/Shell.qml+6
@@ -550,6 +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
554
554 onShowDashHome: showHome()
555 onShowDashHome: showHome()
555 onDash: showDash()
556 onDash: showDash()
@@ -569,6 +570,11 @@ Item {
569 panel.indicators.hide()
570 panel.indicators.hide()
570 }
571 }
571 }
572 }
573+ onFocusChanged: {
574+ if (!focus) {
575+ applicationsDisplayLoader.focus = true;
576+ }
577+ }
572 }
578 }
573
579
574 Wizard {
580 Wizard {
tests/mocks/Unity/Launcher/MockLauncherModel.cpp+2
@@ -25,6 +25,7 @@ MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(pa
25 MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this);
25 MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this);
26 item->setProgress(0);
26 item->setProgress(0);
27 item->setPinned(true);
27 item->setPinned(true);
28+ item->setRunning(true);
28 item->setFocused(true);
29 item->setFocused(true);
29 m_list.append(item);
30 m_list.append(item);
30 item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this);
31 item = new MockLauncherItem("camera-app", "/usr/share/applications/camera-app.desktop", "Camera", "camera", this);
@@ -34,6 +35,7 @@ MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(pa
34 item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
35 item = new MockLauncherItem("gallery-app", "/usr/share/applications/gallery-app.desktop", "Gallery", "gallery", this);
35 item->setProgress(50);
36 item->setProgress(50);
36 item->setCountVisible(true);
37 item->setCountVisible(true);
38+ item->setRunning(true);
37 item->setAlerting(false);
39 item->setAlerting(false);
38 m_list.append(item);
40 m_list.append(item);
39 item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);
41 item = new MockLauncherItem("music-app", "/usr/share/applications/music-app.desktop", "Music", "soundcloud", this);
tests/qmltests/Launcher/tst_Launcher.qml+2
@@ -30,9 +30,11 @@ Item {
30 width: units.gu(50)
30 width: units.gu(50)
31 height: units.gu(55)
31 height: units.gu(55)
32
32
33+ Keys.onPressed: print("waaah")
33 Loader {
34 Loader {
34 id: launcherLoader
35 id: launcherLoader
35 anchors.fill: parent
36 anchors.fill: parent
37+ focus: true
36 property bool itemDestroyed: false
38 property bool itemDestroyed: false
37 sourceComponent: Component {
39 sourceComponent: Component {
38 Launcher {
40 Launcher {
tests/qmltests/tst_Shell.qml+12−4
@@ -116,10 +116,6 @@ Rectangle {
116 Component.onDestruction: {
116 Component.onDestruction: {
117 shellLoader.itemDestroyed = true;
117 shellLoader.itemDestroyed = true;
118 }
118 }
119− Component.onCompleted: {
120− var keyMapper = testCase.findChild(__shell, "physicalKeysMapper");
121− keyMapper.controlInsteadOfAlt = true;
122− }
123 }
119 }
124 }
120 }
125 }
121 }
@@ -208,6 +204,18 @@ Rectangle {
208 checked: true
204 checked: true
209 color: "white"
205 color: "white"
210 }
206 }
207+ ListItem.ItemSelector {
208+ id: ctrlModifier
209+ anchors { left: parent.left; right: parent.right }
210+ activeFocusOnPress: false
211+ text: "Ctrl key as"
212+ model: ["Ctrl", "Alt", "Meta"]
213+ onSelectedIndexChanged: {
214+ var keyMapper = testCase.findChild(shellContainer, "physicalKeysMapper");
215+ keyMapper.controlInsteadOfAlt = selectedIndex == 1;
216+ keyMapper.controlInsteadOfMeta = selectedIndex == 2;
217+ }
218+ }
211
219
212 Label { text: "Applications"; font.bold: true }
220 Label { text: "Applications"; font.bold: true }
213
221