@@ -20,6 +20,7 @@ import Unity.Launcher 0.1
2020import Utils 0.1
2121import "../Components"
2222import Qt.labs.settings 1.0
23+import GSettings 1.0
2324
2425FocusScope {
2526 id: root
@@ -43,6 +44,12 @@ FocusScope {
4344 searchField.focus = true;
4445 }
4546
47+ Keys.onPressed: {
48+ // Catch all presses here in case the navigation lets something through
49+ // We never want to end up in the launcher with focus
50+ event.accepted = true;
51+ }
52+
4653 Settings {
4754 property alias selectedTab: sections.selectedIndex
4855 }
@@ -79,6 +86,9 @@ FocusScope {
7986 anchors { left: parent.left; top: parent.top; right: parent.right; margins: units.gu(1) }
8087 placeholderText: i18n.tr("Search…")
8188 focus: true
89+
90+ KeyNavigation.down: sections
91+
8292 onAccepted: {
8393 if (searchField.displayText != "" && listLoader.item && listLoader.item.currentItem) {
8494 root.applicationSelected(listLoader.item.getFirstAppId());
@@ -96,13 +106,19 @@ FocusScope {
96106 Sections {
97107 id: sections
98108 width: parent.width
109+
110+ KeyNavigation.up: searchField
111+ KeyNavigation.down: headerFocusScope
112+ KeyNavigation.backtab: searchField
113+ KeyNavigation.tab: headerFocusScope
114+
99115 actions: [
100116 Action {
101117 text: i18n.ctr("Apps sorted alphabetically", "A-Z")
102118 // TODO: Disabling this for now as we don't get the right input from u-a-l yet.
103−// },
104−// Action {
105−// text: i18n.ctr("Most used apps", "Most used")
119+ },
120+ Action {
121+ text: i18n.ctr("Most used apps", "Most used")
106122 }
107123 ]
108124
@@ -115,9 +131,42 @@ FocusScope {
115131 }
116132 }
117133
134+ FocusScope {
135+ id: headerFocusScope
136+ KeyNavigation.up: sections
137+ KeyNavigation.down: listLoader.item
138+ KeyNavigation.backtab: sections
139+ KeyNavigation.tab: listLoader.item
140+
141+ GSettings {
142+ id: settings
143+ schema.id: "com.canonical.Unity8"
144+ }
145+
146+ Keys.onPressed: {
147+ switch (event.key) {
148+ case Qt.Key_Return:
149+ case Qt.Key_Enter:
150+ case Qt.Key_Space:
151+ trigger();
152+ event.accepted = true;
153+ }
154+ }
155+
156+ function trigger() {
157+ Qt.openUrlExternally(settings.appstoreUri)
158+ }
159+ }
160+
118161 Loader {
119162 id: listLoader
120163 anchors { left: parent.left; top: sectionsContainer.bottom; right: parent.right; bottom: parent.bottom; leftMargin: units.gu(1); rightMargin: units.gu(1) }
164+
165+ KeyNavigation.up: headerFocusScope
166+ KeyNavigation.down: searchField
167+ KeyNavigation.backtab: headerFocusScope
168+ KeyNavigation.tab: searchField
169+
121170 sourceComponent: {
122171 switch (sections.selectedIndex) {
123172 case 0: return aToZComponent;
@@ -167,10 +216,13 @@ FocusScope {
167216 Component {
168217 id: mostUsedComponent
169218 DrawerListView {
219+ id: mostUsedListView
170220
171221 header: MoreAppsHeader {
172222 width: parent.width
173223 height: units.gu(6)
224+ highlighted: headerFocusScope.activeFocus
225+ onClicked: headerFocusScope.trigger();
174226 }
175227
176228 model: AppDrawerProxyModel {
@@ -196,6 +248,9 @@ FocusScope {
196248 bottomMargin: units.gu(1)
197249 clip: true
198250
251+ interactive: true
252+ focus: index == mostUsedListView.currentIndex
253+
199254 model: sortProxyModel
200255
201256 delegateWidth: units.gu(8)
@@ -209,10 +264,13 @@ FocusScope {
209264 Component {
210265 id: aToZComponent
211266 DrawerListView {
267+ id: aToZListView
212268
213269 header: MoreAppsHeader {
214270 width: parent.width
215271 height: units.gu(6)
272+ highlighted: headerFocusScope.activeFocus
273+ onClicked: headerFocusScope.trigger();
216274 }
217275
218276 model: AppDrawerProxyModel {
@@ -244,7 +302,11 @@ FocusScope {
244302 anchors { left: parent.left; top: categoryNameLabel.bottom; right: parent.right; topMargin: units.gu(1) }
245303 height: rows * delegateHeight
246304
247− interactive: false
305+ interactive: true
306+ focus: index == aToZListView.currentIndex
307+ onFocusChanged: print("drawer grid", index, "has focus", focus)
308+
309+ onCurrentIndexChanged: print("grid currentIndex changed", currentIndex)
248310
249311 model: AppDrawerProxyModel {
250312 id: categoryModel
@@ -263,10 +325,13 @@ FocusScope {
263325 Component {
264326 id: drawerDelegateComponent
265327 AbstractButton {
328+ id: drawerDelegate
266329 width: GridView.view.cellWidth
267330 height: units.gu(10)
268331 objectName: "drawerItem_" + model.appId
269332
333+ property bool focused: index === GridView.view.currentIndex && GridView.view.activeFocus
334+
270335 onClicked: root.applicationSelected(model.appId)
271336
272337 Column {
@@ -290,6 +355,17 @@ FocusScope {
290355 source: model.icon
291356 }
292357 sourceFillMode: UbuntuShape.PreserveAspectCrop
358+
359+ Image {
360+ objectName: "focusRing"
361+ anchors.centerIn: parent
362+ height: width * 15 / 16
363+ width: parent.width + units.gu(1)
364+ source: "graphics/launcher-app-focus-ring.svg"
365+ sourceSize.width: width
366+ sourceSize.height: height
367+ visible: drawerDelegate.focused
368+ }
293369 }
294370
295371 Label {