Merge lp:~canonical-dx-team/unity/unity.fix-701543-2 into lp:unity

Proposed by Mirco Müller
Status: Merged
Approved by: Mirco Müller
Approved revision: no longer in the source branch.
Merged at revision: 875
Proposed branch: lp:~canonical-dx-team/unity/unity.fix-701543-2
Merge into: lp:unity
Diff against target: 567 lines (+218/-41)
11 files modified
src/Launcher.cpp (+30/-20)
src/Launcher.h (+1/-1)
src/LauncherIcon.cpp (+5/-2)
src/LauncherIcon.h (+1/-1)
src/PlacesController.cpp (+1/-1)
src/QuicklistView.cpp (+92/-2)
src/QuicklistView.h (+8/-1)
src/UBusMessages.h (+4/-2)
src/unityshell.cpp (+55/-10)
src/unityshell.h (+19/-1)
tests/CMakeLists.txt (+2/-0)
To merge this branch: bzr merge lp:~canonical-dx-team/unity/unity.fix-701543-2
Reviewer Review Type Date Requested Status
Didier Roche-Tolomelli Approve
Review via email: mp+50577@code.launchpad.net

Description of the change

Much blood, sweat, tears, pain, loss of hair and health brings you quicklist-keyboard-navigation.

- CursorRight or Shift-F10 opens quicklist.
- CursorUp/Down does what you would guess.
- ESC exits the whole key-nav
- SPACE/ENTER triggers highlighted quicklist-menu-item

Unresolved issues:
disabled quicklist-menu items are not handled yet, since I've not been able to find an app, which has those.

To post a comment you must log in.
Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

approved, +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Launcher.cpp'
2--- src/Launcher.cpp 2011-02-18 20:54:27 +0000
3+++ src/Launcher.cpp 2011-02-21 13:25:37 +0000
4@@ -204,7 +204,7 @@
5 OnMouseWheel.connect (sigc::mem_fun (this, &Launcher::RecvMouseWheel));
6 OnKeyPressed.connect (sigc::mem_fun (this, &Launcher::RecvKeyPressed));
7 OnEndFocus.connect (sigc::mem_fun (this, &Launcher::exitKeyNavMode));
8-
9+
10 QuicklistManager::Default ()->quicklist_opened.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistOpened));
11 QuicklistManager::Default ()->quicklist_closed.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistClosed));
12
13@@ -363,8 +363,7 @@
14
15 void
16 Launcher::startKeyNavMode ()
17-{
18-
19+{
20 _navmod_show_launcher = true;
21 EnsureHiddenState ();
22
23@@ -376,6 +375,17 @@
24 }
25
26 void
27+Launcher::leaveKeyNavMode ()
28+{
29+ _last_icon_index = _current_icon_index;
30+ _current_icon_index = -1;
31+ QueueDraw ();
32+ ubus_server_send_message (ubus_server_get_default (),
33+ UBUS_LAUNCHER_END_KEY_NAV,
34+ NULL);
35+}
36+
37+void
38 Launcher::exitKeyNavMode ()
39 {
40 if (!_navmod_show_launcher)
41@@ -386,10 +396,10 @@
42
43 _last_icon_index = _current_icon_index;
44 _current_icon_index = -1;
45+ QueueDraw ();
46 ubus_server_send_message (ubus_server_get_default (),
47- UBUS_LAUNCHER_EXIT_KEY_NAV,
48+ UBUS_LAUNCHER_END_KEY_NAV,
49 NULL);
50- NeedRedraw ();
51 }
52
53 void
54@@ -1257,7 +1267,7 @@
55 _hidden = hidden;
56 SetTimeStruct (&_times[TIME_AUTOHIDE], &_times[TIME_AUTOHIDE], ANIM_DURATION_SHORT);
57
58- _parent->EnableInputWindow(!hidden, "launcher");
59+ _parent->EnableInputWindow(!hidden, "launcher", false, false);
60
61 if (!hidden && _launcher_action_state == ACTION_DRAG_EXTERNAL)
62 ProcessDndLeave ();
63@@ -1439,7 +1449,7 @@
64 }
65 else
66 {
67- _parent->EnableInputWindow(true, "launcher");
68+ _parent->EnableInputWindow(true, "launcher", false, false);
69 g_timeout_add (1000, &Launcher::StrutHack, this);
70 _parent->InputWindowEnableStruts(true);
71 }
72@@ -2409,7 +2419,7 @@
73 switch (key_sym)
74 {
75 // up (move selection up or go to global-menu if at top-most icon)
76- case XK_Up:
77+ case NUX_VK_UP:
78 if (_current_icon_index > 0)
79 _current_icon_index--;
80 else
81@@ -2421,7 +2431,7 @@
82 break;
83
84 // down (move selection down and unfold launcher if needed)
85- case XK_Down:
86+ case NUX_VK_DOWN:
87 if (_current_icon_index < _model->Size ())
88 {
89 _current_icon_index++;
90@@ -2430,8 +2440,8 @@
91 break;
92
93 // esc/left (close quicklist or exit laucher key-focus)
94- case XK_Left:
95- case XK_Escape:
96+ case NUX_VK_LEFT:
97+ case NUX_VK_ESCAPE:
98 // hide again
99 exitKeyNavMode ();
100 break;
101@@ -2444,42 +2454,42 @@
102 // open quicklist of currently selected icon
103 it = _model->at (_current_icon_index);
104 if (it != (LauncherModel::iterator)NULL)
105- (*it)->OpenQuicklist ();
106+ (*it)->OpenQuicklist (true);
107 }
108- exitKeyNavMode ();
109+ leaveKeyNavMode ();
110 }
111 break;
112
113- case XK_Right:
114+ case NUX_VK_RIGHT:
115 {
116 // open quicklist of currently selected icon
117 it = _model->at (_current_icon_index);
118 if (it != (LauncherModel::iterator)NULL)
119- (*it)->OpenQuicklist ();
120+ (*it)->OpenQuicklist (true);
121 }
122- exitKeyNavMode ();
123+ leaveKeyNavMode ();
124 break;
125
126 // <SPACE> (open a new instance)
127- case XK_space:
128+ case NUX_VK_SPACE:
129 {
130 // start currently selected icon
131 it = _model->at (_current_icon_index);
132 if (it != (LauncherModel::iterator)NULL)
133 (*it)->OpenInstance ();
134 }
135- exitKeyNavMode ();
136+ leaveKeyNavMode ();
137 break;
138
139 // <RETURN> (start/activate currently selected icon)
140- case XK_Return:
141+ case NUX_VK_ENTER:
142 {
143 // start currently selected icon
144 it = _model->at (_current_icon_index);
145 if (it != (LauncherModel::iterator)NULL)
146 (*it)->Activate ();
147 }
148- exitKeyNavMode ();
149+ leaveKeyNavMode ();
150 break;
151
152 // Shortcuts to launch applications
153
154=== modified file 'src/Launcher.h'
155--- src/Launcher.h 2011-02-18 20:54:27 +0000
156+++ src/Launcher.h 2011-02-21 13:25:37 +0000
157@@ -139,10 +139,10 @@
158
159 virtual void RecvQuicklistOpened (QuicklistView *quicklist);
160 virtual void RecvQuicklistClosed (QuicklistView *quicklist);
161-
162
163 void startKeyNavMode ();
164 void exitKeyNavMode ();
165+ void leaveKeyNavMode ();
166
167 sigc::signal<void, char *, LauncherIcon *> launcher_dropped;
168 protected:
169
170=== modified file 'src/LauncherIcon.cpp'
171--- src/LauncherIcon.cpp 2011-02-11 17:03:24 +0000
172+++ src/LauncherIcon.cpp 2011-02-21 13:25:37 +0000
173@@ -343,7 +343,7 @@
174 _tooltip->ShowWindow (false);
175 }
176
177-void LauncherIcon::OpenQuicklist ()
178+void LauncherIcon::OpenQuicklist (bool default_to_first_item)
179 {
180 _tooltip->ShowWindow (false);
181 _quicklist->RemoveAllMenuItem ();
182@@ -381,7 +381,10 @@
183 _quicklist->AddMenuItem (item);
184 }
185 }
186-
187+
188+ if (default_to_first_item)
189+ _quicklist->DefaultToFirstItem ();
190+
191 int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w;
192 int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y;
193 QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y);
194
195=== modified file 'src/LauncherIcon.h'
196--- src/LauncherIcon.h 2011-02-11 17:03:24 +0000
197+++ src/LauncherIcon.h 2011-02-21 13:25:37 +0000
198@@ -90,7 +90,7 @@
199 void RecvMouseUp (int button);
200
201 void HideTooltip ();
202- void OpenQuicklist ();
203+ void OpenQuicklist (bool default_to_first_item = false);
204
205 void SetCenter (nux::Point3 center);
206 nux::Point3 GetCenter ();
207
208=== modified file 'src/PlacesController.cpp'
209--- src/PlacesController.cpp 2011-02-17 16:06:14 +0000
210+++ src/PlacesController.cpp 2011-02-21 13:25:37 +0000
211@@ -78,7 +78,7 @@
212 return;
213
214 _window->ShowWindow (true, false);
215- _window->EnableInputWindow (true, "places", true);
216+ _window->EnableInputWindow (true, "places", false, true);
217 _window->GrabPointer ();
218 _window->GrabKeyboard ();
219 _window->NeedRedraw ();
220
221=== modified file 'src/QuicklistView.cpp'
222--- src/QuicklistView.cpp 2011-02-13 00:46:10 +0000
223+++ src/QuicklistView.cpp 2011-02-21 13:25:37 +0000
224@@ -38,6 +38,9 @@
225
226 #include "Introspectable.h"
227
228+#include "ubus-server.h"
229+#include "UBusMessages.h"
230+
231 NUX_IMPLEMENT_OBJECT_TYPE (QuicklistView);
232
233 QuicklistView::QuicklistView ()
234@@ -91,10 +94,85 @@
235 OnMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseClick));
236 OnMouseMove.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseMove));
237 OnMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDrag));
238-
239+ OnKeyPressed.connect (sigc::mem_fun (this, &QuicklistView::RecvKeyPressed));
240+
241 _mouse_down = false;
242 _enable_quicklist_for_testing = false;
243 _compute_blur_bkg = true;
244+
245+ _current_item_index = 0;
246+}
247+
248+void
249+QuicklistView::RecvKeyPressed (unsigned int key_sym,
250+ unsigned long key_code,
251+ unsigned long key_state)
252+{
253+ switch (key_sym)
254+ {
255+ // up (highlight previous menu-item)
256+ case NUX_VK_UP:
257+ if (_current_item_index > 0)
258+ {
259+ GetNthItems (_current_item_index)->_prelight = false;
260+ _current_item_index--;
261+ GetNthItems (_current_item_index)->_prelight = true;
262+ QueueDraw ();
263+ }
264+ break;
265+
266+ // down (highlight next menu-item)
267+ case NUX_VK_DOWN:
268+ if (_current_item_index < GetNumItems () - 1)
269+ {
270+ GetNthItems (_current_item_index)->_prelight = false;
271+ _current_item_index++;
272+ GetNthItems (_current_item_index)->_prelight = true;
273+ QueueDraw ();
274+ }
275+ break;
276+
277+ // left (close quicklist, go back to laucher key-nav)
278+ case NUX_VK_LEFT:
279+ _current_item_index = 0;
280+ GetNthItems (_current_item_index)->_prelight = true;
281+ Hide ();
282+ // inform Launcher we switch back to Launcher key-nav
283+ ubus_server_send_message (ubus_server_get_default (),
284+ UBUS_QUICKLIST_END_KEY_NAV,
285+ NULL);
286+ break;
287+
288+ // esc (close quicklist, exit key-nav)
289+ case NUX_VK_ESCAPE:
290+ _current_item_index = 0;
291+ GetNthItems (_current_item_index)->_prelight = true;
292+ Hide ();
293+ // inform UnityScreen we leave key-nav completely
294+ ubus_server_send_message (ubus_server_get_default (),
295+ UBUS_LAUNCHER_END_KEY_NAV,
296+ NULL);
297+ break;
298+
299+ // <SPACE>, <RETURN> (activate selected menu-item)
300+ case NUX_VK_SPACE:
301+ case NUX_VK_ENTER:
302+ if (_current_item_index >= 0 && _current_item_index < GetNumItems ())
303+ {
304+
305+ dbusmenu_menuitem_handle_event (GetNthItems (_current_item_index)->_menuItem,
306+ "clicked",
307+ NULL,
308+ 0);
309+ _current_item_index = 0;
310+ GetNthItems (_current_item_index)->_prelight = true;
311+ Hide ();
312+ }
313+ break;
314+
315+ default:
316+ break;
317+ }
318 }
319
320 QuicklistView::~QuicklistView ()
321@@ -185,7 +263,8 @@
322 {
323 // FIXME: ShowWindow shouldn't need to be called first
324 ShowWindow (true);
325- EnableInputWindow (true, "quicklist", true);
326+ EnableInputWindow (true, "quicklist", true, false);
327+ SetInputFocus ();
328 GrabPointer ();
329 NeedRedraw ();
330
331@@ -256,6 +335,8 @@
332 return nux::eMouseEventSolved;
333 }
334
335+ ret = OnEvent (ievent, ret, ProcessEventInfo);
336+
337 return ret;
338 }
339
340@@ -785,6 +866,15 @@
341 return l;
342 }
343
344+void QuicklistView::DefaultToFirstItem ()
345+{
346+ if (GetNumItems () >= 1)
347+ {
348+ GetNthItems (0)->_prelight= true;
349+ QueueDraw ();
350+ }
351+}
352+
353 static inline void ql_blurinner (guchar* pixel,
354 gint *zR,
355 gint *zG,
356
357=== modified file 'src/QuicklistView.h'
358--- src/QuicklistView.h 2011-01-12 16:15:14 +0000
359+++ src/QuicklistView.h 2011-02-21 13:25:37 +0000
360@@ -89,7 +89,8 @@
361 QuicklistMenuItem* GetNthItems (int index);
362 QuicklistMenuItemType GetNthType (int index);
363 std::list<QuicklistMenuItem*> GetChildren ();
364-
365+ void DefaultToFirstItem ();
366+
367 void TestMenuItems (DbusmenuMenuitem* root);
368
369 // Introspection
370@@ -113,6 +114,10 @@
371 void RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
372 void RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
373 void RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags);
374+
375+ void RecvKeyPressed (unsigned int key_sym,
376+ unsigned long key_code,
377+ unsigned long key_state);
378
379 void PreLayoutManagement ();
380
381@@ -175,6 +180,8 @@
382 // Introspection
383 gchar *_name;
384
385+ // used by keyboard/a11y-navigation
386+ int _current_item_index;
387 };
388
389 #endif // QUICKLISTVIEW_H
390
391=== modified file 'src/UBusMessages.h'
392--- src/UBusMessages.h 2011-02-05 14:50:55 +0000
393+++ src/UBusMessages.h 2011-02-21 13:25:37 +0000
394@@ -39,8 +39,10 @@
395
396 // Signal send by Launcher/Quicklist when it wants to exit key-nav and wants to
397 // get rid of keyboard-input-focus
398-#define UBUS_LAUNCHER_EXIT_KEY_NAV "LAUNCHER_EXIT_KEY_NAV"
399-#define UBUS_QUICKLIST_EXIT_KEY_NAV "QUICKLIST_EXIT_KEY_NAV"
400+#define UBUS_LAUNCHER_START_KEY_NAV "LAUNCHER_START_KEY_NAV"
401+#define UBUS_LAUNCHER_END_KEY_NAV "LAUNCHER_END_KEY_NAV"
402+#define UBUS_QUICKLIST_START_KEY_NAV "QUICKLIST_START_KEY_NAV"
403+#define UBUS_QUICKLIST_END_KEY_NAV "QUICKLIST_END_KEY_NAV"
404
405 // Signal to send on icon action and that you want to request hiding the launcher
406 #define UBUS_LAUNCHER_ACTION_DONE "LAUNCHER_ACTION_DONE"
407
408=== modified file 'src/unityshell.cpp'
409--- src/unityshell.cpp 2011-02-18 18:24:57 +0000
410+++ src/unityshell.cpp 2011-02-21 13:25:37 +0000
411@@ -248,10 +248,19 @@
412 return false;
413 }
414
415-bool
416-UnityScreen::setKeyboardFocusKeyInitiate (CompAction *action,
417- CompAction::State state,
418- CompOption::Vector &options)
419+void
420+UnityScreen::restartLauncherKeyNav ()
421+{
422+ // set input-focus on launcher-window and start key-nav mode
423+ if (newFocusedWindow != NULL)
424+ {
425+ newFocusedWindow->moveInputFocusTo ();
426+ launcher->startKeyNavMode ();
427+ }
428+}
429+
430+void
431+UnityScreen::startLauncherKeyNav ()
432 {
433 // get CompWindow* of launcher-window
434 newFocusedWindow = screen->findWindow (launcherWindow->GetInputWindowId ());
435@@ -266,12 +275,28 @@
436 newFocusedWindow->moveInputFocusTo ();
437 launcher->startKeyNavMode ();
438 }
439+}
440+
441+bool
442+UnityScreen::setKeyboardFocusKeyInitiate (CompAction *action,
443+ CompAction::State state,
444+ CompOption::Vector &options)
445+{
446+ startLauncherKeyNav ();
447
448 return false;
449 }
450
451 void
452-UnityScreen::OnExitKeyNav (GVariant* data, void* value)
453+UnityScreen::OnLauncherStartKeyNav (GVariant* data, void* value)
454+{
455+ UnityScreen *self = (UnityScreen*) value;
456+
457+ self->startLauncherKeyNav ();
458+}
459+
460+void
461+UnityScreen::OnLauncherEndKeyNav (GVariant* data, void* value)
462 {
463 UnityScreen *self = (UnityScreen*) value;
464
465@@ -281,6 +306,15 @@
466 self->lastFocusedWindow->moveInputFocusTo ();
467 }
468
469+void
470+UnityScreen::OnQuicklistEndKeyNav (GVariant* data,
471+ void* value)
472+{
473+ UnityScreen *self = (UnityScreen*) value;
474+
475+ self->restartLauncherKeyNav ();
476+}
477+
478 gboolean
479 UnityScreen::initPluginActions (gpointer data)
480 {
481@@ -599,9 +633,20 @@
482 optionSetPanelFirstMenuInitiate (boost::bind (&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3));
483 optionSetPanelFirstMenuTerminate(boost::bind (&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3));
484
485- ubus_server_register_interest (ubus_server_get_default (),
486- UBUS_LAUNCHER_EXIT_KEY_NAV,
487- (UBusCallback)&UnityScreen::OnExitKeyNav,
488+ UBusServer* ubus = ubus_server_get_default ();
489+ ubus_server_register_interest (ubus,
490+ UBUS_LAUNCHER_START_KEY_NAV,
491+ (UBusCallback)&UnityScreen::OnLauncherStartKeyNav,
492+ this);
493+
494+ ubus_server_register_interest (ubus,
495+ UBUS_LAUNCHER_END_KEY_NAV,
496+ (UBusCallback)&UnityScreen::OnLauncherEndKeyNav,
497+ this);
498+
499+ ubus_server_register_interest (ubus,
500+ UBUS_QUICKLIST_END_KEY_NAV,
501+ (UBusCallback)&UnityScreen::OnQuicklistEndKeyNav,
502 this);
503
504 g_timeout_add (0, &UnityScreen::initPluginActions, this);
505@@ -656,7 +701,7 @@
506 self->launcherWindow->SetLayout(layout);
507 self->launcherWindow->SetBackgroundColor(nux::Color(0x00000000));
508 self->launcherWindow->ShowWindow(true);
509- self->launcherWindow->EnableInputWindow(true, "launcher");
510+ self->launcherWindow->EnableInputWindow(true, "launcher", false, false);
511 self->launcherWindow->InputWindowEnableStruts(true);
512
513 /* FIXME: this should not be manual, should be managed with a
514@@ -687,7 +732,7 @@
515 self->panelWindow->SetLayout(layout);
516 self->panelWindow->SetBackgroundColor(nux::Color(0x00000000));
517 self->panelWindow->ShowWindow(true);
518- self->panelWindow->EnableInputWindow(true, "panel");
519+ self->panelWindow->EnableInputWindow(true, "panel", false, false);
520 self->panelWindow->InputWindowEnableStruts(true);
521
522 /* FIXME: this should not be manual, should be managed with a
523
524=== modified file 'src/unityshell.h'
525--- src/unityshell.h 2011-02-17 09:56:22 +0000
526+++ src/unityshell.h 2011-02-21 13:25:37 +0000
527@@ -161,8 +161,26 @@
528 strutHackTimeout (gpointer data);
529
530 static void
531+ OnStartKeyNav (GVariant* data, void* value);
532+
533+ static void
534 OnExitKeyNav (GVariant* data, void* value);
535-
536+
537+ void
538+ startLauncherKeyNav ();
539+
540+ void
541+ restartLauncherKeyNav ();
542+
543+ static void
544+ OnQuicklistEndKeyNav (GVariant* data, void* value);
545+
546+ static void
547+ OnLauncherStartKeyNav (GVariant* data, void* value);
548+
549+ static void
550+ OnLauncherEndKeyNav (GVariant* data, void* value);
551+
552 Launcher *launcher;
553 LauncherController *controller;
554 PanelView *panelView;
555
556=== modified file 'tests/CMakeLists.txt'
557--- tests/CMakeLists.txt 2011-02-17 16:48:20 +0000
558+++ tests/CMakeLists.txt 2011-02-21 13:25:37 +0000
559@@ -241,6 +241,8 @@
560 ../src/QuicklistMenuItemSeparator.h
561 ../src/QuicklistView.cpp
562 ../src/QuicklistView.h
563+ ../src/ubus-server.cpp
564+ ../src/ubus-server.h
565 )
566
567 add_executable (test-places-backend