Merge lp:~canonical-dx-team/unity/unity.fix-646712 into lp:unity
- unity.fix-646712
- Merge into trunk
Proposed by
Mirco Müller
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 885 | ||||
Proposed branch: | lp:~canonical-dx-team/unity/unity.fix-646712 | ||||
Merge into: | lp:unity | ||||
Diff against target: |
352 lines (+222/-2) 4 files modified
src/Launcher.cpp (+177/-1) src/Launcher.h (+20/-1) src/LauncherIcon.cpp (+22/-0) src/LauncherIcon.h (+3/-0) |
||||
To merge this branch: | bzr merge lp:~canonical-dx-team/unity/unity.fix-646712 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Didier Roche-Tolomelli | Approve | ||
Review via email: mp+50899@code.launchpad.net |
Commit message
Description of the change
This branch makes the superkey-overlays show up on the launcher, if the Super-key is held down. The first 10 icons get labels and trash-can and workspace-switcher get special labels.
To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote : | # |
I didn't know about the dynamic-mapping for trashcan, workspaces-switcher and places.
Revision history for this message
Mirco Müller (macslow) wrote : | # |
Fixed
Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote : | # |
Approved!
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-23 12:20:41 +0000 | |||
3 | +++ src/Launcher.cpp 2011-02-24 09:32:15 +0000 | |||
4 | @@ -292,6 +292,10 @@ | |||
5 | 292 | _arrow_rtl = nux::CreateTexture2DFromFile (PKGDATADIR"/launcher_arrow_rtl.png", -1, true); | 292 | _arrow_rtl = nux::CreateTexture2DFromFile (PKGDATADIR"/launcher_arrow_rtl.png", -1, true); |
6 | 293 | _arrow_empty_rtl = nux::CreateTexture2DFromFile (PKGDATADIR"/launcher_arrow_outline_rtl.png", -1, true); | 293 | _arrow_empty_rtl = nux::CreateTexture2DFromFile (PKGDATADIR"/launcher_arrow_outline_rtl.png", -1, true); |
7 | 294 | 294 | ||
8 | 295 | for (int i = 0; i < MAX_SUPERKEY_LABELS - 1; i++) | ||
9 | 296 | _superkey_labels[i] = cairoToTexture2D ((char) ('1' + i), LAUNCHER_ICON_SIZE, LAUNCHER_ICON_SIZE); | ||
10 | 297 | _superkey_labels[9] = cairoToTexture2D ((char) ('0'), LAUNCHER_ICON_SIZE, LAUNCHER_ICON_SIZE); | ||
11 | 298 | |||
12 | 295 | _enter_y = 0; | 299 | _enter_y = 0; |
13 | 296 | _dnd_security = 15; | 300 | _dnd_security = 15; |
14 | 297 | _launcher_drag_delta = 0; | 301 | _launcher_drag_delta = 0; |
15 | @@ -351,7 +355,11 @@ | |||
16 | 351 | 355 | ||
17 | 352 | Launcher::~Launcher() | 356 | Launcher::~Launcher() |
18 | 353 | { | 357 | { |
20 | 354 | 358 | for (int i = 0; i < MAX_SUPERKEY_LABELS; i++) | |
21 | 359 | { | ||
22 | 360 | if (_superkey_labels[i]) | ||
23 | 361 | _superkey_labels[i]->UnReference (); | ||
24 | 362 | } | ||
25 | 355 | } | 363 | } |
26 | 356 | 364 | ||
27 | 357 | /* Introspection */ | 365 | /* Introspection */ |
28 | @@ -362,6 +370,120 @@ | |||
29 | 362 | } | 370 | } |
30 | 363 | 371 | ||
31 | 364 | void | 372 | void |
32 | 373 | Launcher::DrawRoundedRectangle (cairo_t* cr, | ||
33 | 374 | double aspect, | ||
34 | 375 | double x, | ||
35 | 376 | double y, | ||
36 | 377 | double cornerRadius, | ||
37 | 378 | double width, | ||
38 | 379 | double height) | ||
39 | 380 | { | ||
40 | 381 | double radius = cornerRadius / aspect; | ||
41 | 382 | |||
42 | 383 | // top-left, right of the corner | ||
43 | 384 | cairo_move_to (cr, x + radius, y); | ||
44 | 385 | |||
45 | 386 | // top-right, left of the corner | ||
46 | 387 | cairo_line_to (cr, x + width - radius, y); | ||
47 | 388 | |||
48 | 389 | // top-right, below the corner | ||
49 | 390 | cairo_arc (cr, | ||
50 | 391 | x + width - radius, | ||
51 | 392 | y + radius, | ||
52 | 393 | radius, | ||
53 | 394 | -90.0f * G_PI / 180.0f, | ||
54 | 395 | 0.0f * G_PI / 180.0f); | ||
55 | 396 | |||
56 | 397 | // bottom-right, above the corner | ||
57 | 398 | cairo_line_to (cr, x + width, y + height - radius); | ||
58 | 399 | |||
59 | 400 | // bottom-right, left of the corner | ||
60 | 401 | cairo_arc (cr, | ||
61 | 402 | x + width - radius, | ||
62 | 403 | y + height - radius, | ||
63 | 404 | radius, | ||
64 | 405 | 0.0f * G_PI / 180.0f, | ||
65 | 406 | 90.0f * G_PI / 180.0f); | ||
66 | 407 | |||
67 | 408 | // bottom-left, right of the corner | ||
68 | 409 | cairo_line_to (cr, x + radius, y + height); | ||
69 | 410 | |||
70 | 411 | // bottom-left, above the corner | ||
71 | 412 | cairo_arc (cr, | ||
72 | 413 | x + radius, | ||
73 | 414 | y + height - radius, | ||
74 | 415 | radius, | ||
75 | 416 | 90.0f * G_PI / 180.0f, | ||
76 | 417 | 180.0f * G_PI / 180.0f); | ||
77 | 418 | |||
78 | 419 | // top-left, right of the corner | ||
79 | 420 | cairo_arc (cr, | ||
80 | 421 | x + radius, | ||
81 | 422 | y + radius, | ||
82 | 423 | radius, | ||
83 | 424 | 180.0f * G_PI / 180.0f, | ||
84 | 425 | 270.0f * G_PI / 180.0f); | ||
85 | 426 | } | ||
86 | 427 | |||
87 | 428 | nux::BaseTexture* | ||
88 | 429 | Launcher::cairoToTexture2D (const char label, int width, int height) | ||
89 | 430 | { | ||
90 | 431 | nux::BaseTexture* texture = NULL; | ||
91 | 432 | nux::CairoGraphics* cg = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, | ||
92 | 433 | width, | ||
93 | 434 | height); | ||
94 | 435 | cairo_t* cr = cg->GetContext (); | ||
95 | 436 | PangoLayout* layout = NULL; | ||
96 | 437 | PangoContext* pangoCtx = NULL; | ||
97 | 438 | PangoFontDescription* desc = NULL; | ||
98 | 439 | GtkSettings* settings = gtk_settings_get_default (); // not ref'ed | ||
99 | 440 | gchar* fontName = NULL; | ||
100 | 441 | double label_x = 18.0f; | ||
101 | 442 | double label_y = 18.0f; | ||
102 | 443 | double label_w = 18.0f; | ||
103 | 444 | double label_h = 18.0f; | ||
104 | 445 | double label_r = 3.0f; | ||
105 | 446 | |||
106 | 447 | cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); | ||
107 | 448 | cairo_paint (cr); | ||
108 | 449 | cairo_scale (cr, 1.0f, 1.0f); | ||
109 | 450 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); | ||
110 | 451 | DrawRoundedRectangle (cr, 1.0f, label_x, label_y, label_r, label_w, label_h); | ||
111 | 452 | cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.65f); | ||
112 | 453 | cairo_fill (cr); | ||
113 | 454 | |||
114 | 455 | layout = pango_cairo_create_layout (cr); | ||
115 | 456 | g_object_get (settings, "gtk-font-name", &fontName, NULL); | ||
116 | 457 | desc = pango_font_description_from_string (fontName); | ||
117 | 458 | pango_font_description_set_size (desc, 11 * PANGO_SCALE); | ||
118 | 459 | pango_layout_set_font_description (layout, desc); | ||
119 | 460 | pango_layout_set_text (layout, &label, 1); | ||
120 | 461 | pangoCtx = pango_layout_get_context (layout); // is not ref'ed | ||
121 | 462 | |||
122 | 463 | PangoRectangle logRect; | ||
123 | 464 | PangoRectangle inkRect; | ||
124 | 465 | pango_layout_get_extents (layout, &inkRect, &logRect); | ||
125 | 466 | |||
126 | 467 | /* position and paint text */ | ||
127 | 468 | cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); | ||
128 | 469 | double x = label_x - ((logRect.width / PANGO_SCALE) - label_w) / 2.0f; | ||
129 | 470 | double y = label_y - ((logRect.height / PANGO_SCALE) - label_h) / 2.0f - 1; | ||
130 | 471 | cairo_move_to (cr, x, y); | ||
131 | 472 | pango_cairo_show_layout (cr, layout); | ||
132 | 473 | |||
133 | 474 | nux::NBitmapData* bitmap = cg->GetBitmap (); | ||
134 | 475 | texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); | ||
135 | 476 | texture->Update (bitmap); | ||
136 | 477 | delete bitmap; | ||
137 | 478 | delete cg; | ||
138 | 479 | g_object_unref (layout); | ||
139 | 480 | pango_font_description_free (desc); | ||
140 | 481 | g_free (fontName); | ||
141 | 482 | |||
142 | 483 | return texture; | ||
143 | 484 | } | ||
144 | 485 | |||
145 | 486 | void | ||
146 | 365 | Launcher::startKeyNavMode () | 487 | Launcher::startKeyNavMode () |
147 | 366 | { | 488 | { |
148 | 367 | _navmod_show_launcher = true; | 489 | _navmod_show_launcher = true; |
149 | @@ -1184,6 +1306,7 @@ | |||
150 | 1184 | void Launcher::StartKeyShowLauncher () | 1306 | void Launcher::StartKeyShowLauncher () |
151 | 1185 | { | 1307 | { |
152 | 1186 | _super_show_launcher = true; | 1308 | _super_show_launcher = true; |
153 | 1309 | QueueDraw (); | ||
154 | 1187 | SetTimeStruct (&_times[TIME_TAP_SUPER], NULL, ANIM_DURATION_SHORT); | 1310 | SetTimeStruct (&_times[TIME_TAP_SUPER], NULL, ANIM_DURATION_SHORT); |
155 | 1188 | EnsureHiddenState (); | 1311 | EnsureHiddenState (); |
156 | 1189 | } | 1312 | } |
157 | @@ -1194,6 +1317,7 @@ | |||
158 | 1194 | clock_gettime (CLOCK_MONOTONIC, ¤t); | 1317 | clock_gettime (CLOCK_MONOTONIC, ¤t); |
159 | 1195 | 1318 | ||
160 | 1196 | _super_show_launcher = false; | 1319 | _super_show_launcher = false; |
161 | 1320 | QueueDraw (); | ||
162 | 1197 | 1321 | ||
163 | 1198 | // it's a tap on super | 1322 | // it's a tap on super |
164 | 1199 | if (TimeDelta (¤t, &_times[TIME_TAP_SUPER]) < ANIM_DURATION_SHORT) | 1323 | if (TimeDelta (¤t, &_times[TIME_TAP_SUPER]) < ANIM_DURATION_SHORT) |
165 | @@ -1682,6 +1806,10 @@ | |||
166 | 1682 | // needs to be disconnected | 1806 | // needs to be disconnected |
167 | 1683 | icon->needs_redraw.connect (sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw)); | 1807 | icon->needs_redraw.connect (sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw)); |
168 | 1684 | 1808 | ||
169 | 1809 | guint64 shortcut = icon->GetShortcut (); | ||
170 | 1810 | if (shortcut != 0 && !g_ascii_isdigit ((gchar) shortcut)) | ||
171 | 1811 | icon->SetSuperkeyLabel (cairoToTexture2D ((gchar) shortcut, LAUNCHER_ICON_SIZE, LAUNCHER_ICON_SIZE)); | ||
172 | 1812 | |||
173 | 1685 | AddChild (icon); | 1813 | AddChild (icon); |
174 | 1686 | } | 1814 | } |
175 | 1687 | 1815 | ||
176 | @@ -2090,6 +2218,51 @@ | |||
177 | 2090 | nux::Color (0xFFFFFFFF), | 2218 | nux::Color (0xFFFFFFFF), |
178 | 2091 | arg.alpha, | 2219 | arg.alpha, |
179 | 2092 | arg.icon->_xform_coords["Glow"]); | 2220 | arg.icon->_xform_coords["Glow"]); |
180 | 2221 | |||
181 | 2222 | /* draw superkey-shortcut label */ | ||
182 | 2223 | if (_super_show_launcher) | ||
183 | 2224 | { | ||
184 | 2225 | guint64 shortcut = arg.icon->GetShortcut (); | ||
185 | 2226 | |||
186 | 2227 | /* deal with dynamic labels for places, which can be set via the locale */ | ||
187 | 2228 | if (shortcut != 0 && !g_ascii_isdigit ((gchar) shortcut)) | ||
188 | 2229 | { | ||
189 | 2230 | RenderIcon (GfxContext, | ||
190 | 2231 | arg, | ||
191 | 2232 | arg.icon->GetSuperkeyLabel ()->GetDeviceTexture (), | ||
192 | 2233 | nux::Color (0xFFFFFFFF), | ||
193 | 2234 | arg.alpha, | ||
194 | 2235 | arg.icon->_xform_coords["Tile"]); | ||
195 | 2236 | } | ||
196 | 2237 | else | ||
197 | 2238 | { | ||
198 | 2239 | /* deal with the hardcoded labels used for the first 10 icons on the launcher */ | ||
199 | 2240 | gchar key = (gchar) shortcut; | ||
200 | 2241 | int index = -1; | ||
201 | 2242 | |||
202 | 2243 | switch (key) | ||
203 | 2244 | { | ||
204 | 2245 | case '1': index = 0; break; | ||
205 | 2246 | case '2': index = 1; break; | ||
206 | 2247 | case '3': index = 2; break; | ||
207 | 2248 | case '4': index = 3; break; | ||
208 | 2249 | case '5': index = 4; break; | ||
209 | 2250 | case '6': index = 5; break; | ||
210 | 2251 | case '7': index = 6; break; | ||
211 | 2252 | case '8': index = 7; break; | ||
212 | 2253 | case '9': index = 8; break; | ||
213 | 2254 | case '0': index = 9; break; | ||
214 | 2255 | } | ||
215 | 2256 | |||
216 | 2257 | if (index != -1) | ||
217 | 2258 | RenderIcon (GfxContext, | ||
218 | 2259 | arg, | ||
219 | 2260 | _superkey_labels[index]->GetDeviceTexture (), | ||
220 | 2261 | nux::Color (0xFFFFFFFF), | ||
221 | 2262 | arg.alpha, | ||
222 | 2263 | arg.icon->_xform_coords["Tile"]); | ||
223 | 2264 | } | ||
224 | 2265 | } | ||
225 | 2093 | } | 2266 | } |
226 | 2094 | 2267 | ||
227 | 2095 | void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) | 2268 | void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) |
228 | @@ -2426,7 +2599,10 @@ | |||
229 | 2426 | unsigned long key_state) | 2599 | unsigned long key_state) |
230 | 2427 | { | 2600 | { |
231 | 2428 | if (_super_show_launcher) | 2601 | if (_super_show_launcher) |
232 | 2602 | { | ||
233 | 2429 | RecvKeyPressed (key_sym, key_code, key_state); | 2603 | RecvKeyPressed (key_sym, key_code, key_state); |
234 | 2604 | QueueDraw (); | ||
235 | 2605 | } | ||
236 | 2430 | } | 2606 | } |
237 | 2431 | 2607 | ||
238 | 2432 | void | 2608 | void |
239 | 2433 | 2609 | ||
240 | === modified file 'src/Launcher.h' | |||
241 | --- src/Launcher.h 2011-02-23 11:18:17 +0000 | |||
242 | +++ src/Launcher.h 2011-02-24 09:32:15 +0000 | |||
243 | @@ -38,6 +38,9 @@ | |||
244 | 38 | #define ANIM_DURATION 200 | 38 | #define ANIM_DURATION 200 |
245 | 39 | #define ANIM_DURATION_LONG 350 | 39 | #define ANIM_DURATION_LONG 350 |
246 | 40 | 40 | ||
247 | 41 | #define MAX_SUPERKEY_LABELS 10 | ||
248 | 42 | #define LAUNCHER_ICON_SIZE 54 | ||
249 | 43 | |||
250 | 41 | class LauncherModel; | 44 | class LauncherModel; |
251 | 42 | class QuicklistView; | 45 | class QuicklistView; |
252 | 43 | class LauncherIcon; | 46 | class LauncherIcon; |
253 | @@ -341,7 +344,21 @@ | |||
254 | 341 | 344 | ||
255 | 342 | void SetOffscreenRenderTarget (nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture); | 345 | void SetOffscreenRenderTarget (nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture); |
256 | 343 | void RestoreSystemRenderTarget (); | 346 | void RestoreSystemRenderTarget (); |
258 | 344 | 347 | ||
259 | 348 | void | ||
260 | 349 | DrawRoundedRectangle (cairo_t* cr, | ||
261 | 350 | double aspect, | ||
262 | 351 | double x, | ||
263 | 352 | double y, | ||
264 | 353 | double cornerRadius, | ||
265 | 354 | double width, | ||
266 | 355 | double height); | ||
267 | 356 | |||
268 | 357 | nux::BaseTexture* | ||
269 | 358 | cairoToTexture2D (const char label, | ||
270 | 359 | int width, | ||
271 | 360 | int height); | ||
272 | 361 | |||
273 | 345 | std::list<char *> StringToUriList (char * input); | 362 | std::list<char *> StringToUriList (char * input); |
274 | 346 | 363 | ||
275 | 347 | nux::HLayout* m_Layout; | 364 | nux::HLayout* m_Layout; |
276 | @@ -421,6 +438,8 @@ | |||
277 | 421 | nux::BaseTexture* _arrow_empty_ltr; | 438 | nux::BaseTexture* _arrow_empty_ltr; |
278 | 422 | nux::BaseTexture* _arrow_empty_rtl; | 439 | nux::BaseTexture* _arrow_empty_rtl; |
279 | 423 | 440 | ||
280 | 441 | nux::BaseTexture* _superkey_labels[MAX_SUPERKEY_LABELS]; | ||
281 | 442 | |||
282 | 424 | nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_drag_texture; | 443 | nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_drag_texture; |
283 | 425 | nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_progress_texture; | 444 | nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_progress_texture; |
284 | 426 | 445 | ||
285 | 427 | 446 | ||
286 | === modified file 'src/LauncherIcon.cpp' | |||
287 | --- src/LauncherIcon.cpp 2011-02-23 10:21:23 +0000 | |||
288 | +++ src/LauncherIcon.cpp 2011-02-24 09:32:15 +0000 | |||
289 | @@ -73,6 +73,7 @@ | |||
290 | 73 | _shortcut = 0; | 73 | _shortcut = 0; |
291 | 74 | 74 | ||
292 | 75 | _emblem = 0; | 75 | _emblem = 0; |
293 | 76 | _superkey_label = 0; | ||
294 | 76 | 77 | ||
295 | 77 | _quicklist = new QuicklistView (); | 78 | _quicklist = new QuicklistView (); |
296 | 78 | _quicklist_is_initialized = false; | 79 | _quicklist_is_initialized = false; |
297 | @@ -106,6 +107,9 @@ | |||
298 | 106 | if (_center_stabilize_handle) | 107 | if (_center_stabilize_handle) |
299 | 107 | g_source_remove (_center_stabilize_handle); | 108 | g_source_remove (_center_stabilize_handle); |
300 | 108 | _center_stabilize_handle = 0; | 109 | _center_stabilize_handle = 0; |
301 | 110 | |||
302 | 111 | if (_superkey_label) | ||
303 | 112 | _superkey_label->UnReference (); | ||
304 | 109 | } | 113 | } |
305 | 110 | 114 | ||
306 | 111 | bool | 115 | bool |
307 | @@ -688,6 +692,24 @@ | |||
308 | 688 | needs_redraw.emit (this); | 692 | needs_redraw.emit (this); |
309 | 689 | } | 693 | } |
310 | 690 | 694 | ||
311 | 695 | void | ||
312 | 696 | LauncherIcon::SetSuperkeyLabel (nux::BaseTexture* label) | ||
313 | 697 | { | ||
314 | 698 | if (_superkey_label == label) | ||
315 | 699 | return; | ||
316 | 700 | |||
317 | 701 | if (_superkey_label) | ||
318 | 702 | _superkey_label->UnReference (); | ||
319 | 703 | |||
320 | 704 | _superkey_label = label; | ||
321 | 705 | } | ||
322 | 706 | |||
323 | 707 | nux::BaseTexture* | ||
324 | 708 | LauncherIcon::GetSuperkeyLabel () | ||
325 | 709 | { | ||
326 | 710 | return _superkey_label; | ||
327 | 711 | } | ||
328 | 712 | |||
329 | 691 | void | 713 | void |
330 | 692 | LauncherIcon::SetEmblemIconName (const char *name) | 714 | LauncherIcon::SetEmblemIconName (const char *name) |
331 | 693 | { | 715 | { |
332 | 694 | 716 | ||
333 | === modified file 'src/LauncherIcon.h' | |||
334 | --- src/LauncherIcon.h 2011-02-22 17:05:31 +0000 | |||
335 | +++ src/LauncherIcon.h 2011-02-24 09:32:15 +0000 | |||
336 | @@ -176,6 +176,8 @@ | |||
337 | 176 | void SetSortPriority (int priority); | 176 | void SetSortPriority (int priority); |
338 | 177 | 177 | ||
339 | 178 | void SetEmblem (nux::BaseTexture *emblem); | 178 | void SetEmblem (nux::BaseTexture *emblem); |
340 | 179 | void SetSuperkeyLabel (nux::BaseTexture* label); | ||
341 | 180 | nux::BaseTexture* GetSuperkeyLabel (); | ||
342 | 179 | 181 | ||
343 | 180 | virtual std::list<DbusmenuMenuitem *> GetMenus (); | 182 | virtual std::list<DbusmenuMenuitem *> GetMenus (); |
344 | 181 | virtual nux::BaseTexture * GetTextureForSize (int size) = 0; | 183 | virtual nux::BaseTexture * GetTextureForSize (int size) = 0; |
345 | @@ -258,6 +260,7 @@ | |||
346 | 258 | IconType _icon_type; | 260 | IconType _icon_type; |
347 | 259 | 261 | ||
348 | 260 | nux::BaseTexture* _emblem; | 262 | nux::BaseTexture* _emblem; |
349 | 263 | nux::BaseTexture* _superkey_label; | ||
350 | 261 | 264 | ||
351 | 262 | bool _quirks[QUIRK_LAST]; | 265 | bool _quirks[QUIRK_LAST]; |
352 | 263 | struct timespec _quirk_times[QUIRK_LAST]; | 266 | struct timespec _quirk_times[QUIRK_LAST]; |
160 + if (_super_ show_launcher)
(and following)… Can you please avoid by any mean to hardcode the keys?
The places can set dynamic values in their .place file for that for instance, so it won't scale. We will probably change the "t" and "w" shortcut as well. So having them in one place is better.
if you go over the model, I think you can get both the index and the shortcut.