Merge lp:~david4dev/slingshot/fix-804518 into lp:~elementary-pantheon/slingshot/slingshot
- fix-804518
- Merge into slingshot
Status: | Merged |
---|---|
Merged at revision: | 128 |
Proposed branch: | lp:~david4dev/slingshot/fix-804518 |
Merge into: | lp:~elementary-pantheon/slingshot/slingshot |
Diff against target: |
777 lines (+260/-154) 6 files modified
backend/AppMonitor.vala (+37/-0) build (+3/-0) build_run (+3/-5) frontend/widgets/AppItem.vala (+37/-37) install (+5/-0) slingshot.vala (+175/-112) |
To merge this branch: | bzr merge lp:~david4dev/slingshot/fix-804518 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Danielle Foré | Approve | ||
Review via email:
|
Commit message
Description of the change
Fixes bug 804518:
- Slingshot now launches in the background. This makes it suitable for auto starting.
- If the slingshot executable is run and an instance of slingshot is already running, the slingshot window will be activated. This shows the launcher without much delay.
- Slingshot now monitors /usr/share/
- Slingshot no longer shows/unshows the desktop. This is because I couldn't work out how to this with the new functionality. IMO this is actually better because you can still look at the windows you have open. This may be useful, for example, if one of them is a guide telling you which application to run.
- Removed gradient to improve readability when running slingshot over windows (or light coloured wallpapers).
- 60. By David Green
-
If slinshot is already running, it now shows the existing instance if it is hidden and hides the existing instance if it is showing.
- 61. By David Green
-
fixed issue with slingshot showing behind windows
- 62. By David Green
-
Now shows/hides the desktop again
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
xapantu (xapantu) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Danielle Foré (danrabbit) : | # |
Preview Diff
1 | === added file 'backend/AppMonitor.vala' |
2 | --- backend/AppMonitor.vala 1970-01-01 00:00:00 +0000 |
3 | +++ backend/AppMonitor.vala 2011-08-10 18:49:27 +0000 |
4 | @@ -0,0 +1,37 @@ |
5 | +namespace Slingshot.Backend { |
6 | + |
7 | + public class AppMonitor : GLib.Object { |
8 | + |
9 | + public GLib.File system_applications; |
10 | + public GLib.File user_applications; |
11 | + |
12 | + public GLib.FileMonitor system_monitor; |
13 | + public GLib.FileMonitor user_monitor; |
14 | + |
15 | + public signal void changed (GLib.File file, GLib.File? other_file, GLib.FileMonitorEvent event_type); |
16 | + |
17 | + public void trigger_changed (GLib.File file, GLib.File? other_file, GLib.FileMonitorEvent event_type) { |
18 | + this.changed(file, other_file, event_type); |
19 | + } |
20 | + |
21 | + construct { |
22 | + this.system_applications = File.new_for_path("/usr/share/applications"); |
23 | + this.user_applications = File.new_for_path(GLib.Environment.get_user_data_dir() + "/applications"); |
24 | + try { |
25 | + this.system_monitor = this.system_applications.monitor_directory(GLib.FileMonitorFlags.NONE); |
26 | + this.system_monitor.changed.connect(this.trigger_changed); |
27 | + } catch (GLib.Error e) { |
28 | + print("Error: "+e.message+"\n"); |
29 | + } |
30 | + try { |
31 | + this.user_monitor = this.user_applications.monitor_directory(GLib.FileMonitorFlags.NONE); |
32 | + this.user_monitor.changed.connect(this.trigger_changed); |
33 | + } catch (GLib.Error e) { |
34 | + print("Error: "+e.message+"\n"); |
35 | + } |
36 | + } |
37 | + |
38 | + } |
39 | + |
40 | + |
41 | +} |
42 | |
43 | === added file 'build' |
44 | --- build 1970-01-01 00:00:00 +0000 |
45 | +++ build 2011-08-10 18:49:27 +0000 |
46 | @@ -0,0 +1,3 @@ |
47 | +#!/bin/sh |
48 | + |
49 | +valac --pkg gtk+-2.0 --pkg unique-1.0 --pkg gee-1.0 --pkg gio-unix-2.0 --pkg gio-2.0 --pkg libgnome-menu --Xcc='-DGMENU_I_KNOW_THIS_IS_UNSTABLE' --pkg libwnck-1.0 --Xcc='-DWNCK_I_KNOW_THIS_IS_UNSTABLE' slingshot.vala frontend/widgets/*.vala frontend/*.vala backend/*.vala |
50 | |
51 | === modified file 'build_run' |
52 | --- build_run 2011-02-12 12:16:02 +0000 |
53 | +++ build_run 2011-08-10 18:49:27 +0000 |
54 | @@ -1,7 +1,5 @@ |
55 | #!/bin/sh |
56 | |
57 | -valac --pkg gtk+-2.0 --pkg unique-1.0 --pkg gee-1.0 --pkg gio-unix-2.0 --pkg libgnome-menu --Xcc='-DGMENU_I_KNOW_THIS_IS_UNSTABLE' --pkg libwnck-1.0 --Xcc='-DWNCK_I_KNOW_THIS_IS_UNSTABLE' slingshot.vala frontend/widgets/*.vala frontend/*.vala backend/*.vala |
58 | - |
59 | -sudo mv slingshot /usr/bin |
60 | - |
61 | -slingshot |
62 | +./build |
63 | + |
64 | +killall slingshot ; ./slingshot |
65 | |
66 | === modified file 'frontend/widgets/AppItem.vala' |
67 | --- frontend/widgets/AppItem.vala 2011-02-12 13:16:08 +0000 |
68 | +++ frontend/widgets/AppItem.vala 2011-08-10 18:49:27 +0000 |
69 | @@ -2,13 +2,13 @@ |
70 | namespace Slingshot.Frontend { |
71 | |
72 | public class AppItem : Gtk.EventBox { |
73 | - |
74 | + |
75 | private Gdk.Pixbuf icon; |
76 | private Slingshot.Frontend.Color prominent; |
77 | private string label; |
78 | private Gtk.VBox wrapper; |
79 | private int icon_size; |
80 | - |
81 | + |
82 | const int FPS = 24; |
83 | const int DURATION = 200; |
84 | const int RUN_LENGTH = (int)(DURATION/FPS); // total number of frames |
85 | @@ -16,44 +16,44 @@ |
86 | |
87 | public AppItem (int size) { |
88 | this.icon_size = size; |
89 | - |
90 | + |
91 | // EventBox Properties |
92 | this.set_visible_window(false); |
93 | this.can_focus = true; |
94 | this.set_size_request (icon_size * 2, icon_size + 30); // 30 is the padding between icon and label and label's height |
95 | - |
96 | + |
97 | // VBox properties |
98 | this.wrapper = new Gtk.VBox (false, 0); |
99 | this.wrapper.expose_event.connect (this.draw_icon); |
100 | this.add (this.wrapper); |
101 | - |
102 | - |
103 | + |
104 | + |
105 | // Focused signals |
106 | this.expose_event.connect (this.draw_background); |
107 | this.focus_in_event.connect ( () => { this.focus_in (); return true;} ); |
108 | this.focus_out_event.connect ( () => { this.focus_out (); return true;} ); |
109 | - |
110 | + |
111 | } |
112 | - |
113 | + |
114 | public void change_app (Gdk.Pixbuf new_icon, string new_name, string new_tooltip) { |
115 | this.current_frame = 1; |
116 | - |
117 | + |
118 | // Icon |
119 | this.icon = new_icon; |
120 | this.prominent = Slingshot.Frontend.Utilities.average_color (this.icon); |
121 | - |
122 | + |
123 | // Label |
124 | this.label = new_name; |
125 | - |
126 | + |
127 | // Tooltip |
128 | this.set_tooltip_text (new_tooltip); |
129 | - |
130 | + |
131 | // Redraw |
132 | this.wrapper.queue_draw (); |
133 | } |
134 | - |
135 | + |
136 | public new void focus_in () { |
137 | - |
138 | + |
139 | GLib.Timeout.add (((int)(1000/this.FPS)), () => { |
140 | if (this.current_frame >= this.RUN_LENGTH || !this.has_focus) { |
141 | current_frame = 1; |
142 | @@ -63,11 +63,11 @@ |
143 | this.current_frame++; |
144 | return true; |
145 | }); |
146 | - |
147 | + |
148 | } |
149 | - |
150 | + |
151 | public new void focus_out () { |
152 | - |
153 | + |
154 | GLib.Timeout.add (((int)(1000/this.FPS)), () => { |
155 | if (this.current_frame >= this.RUN_LENGTH || this.has_focus) { |
156 | current_frame = 1; |
157 | @@ -77,76 +77,76 @@ |
158 | this.current_frame++; |
159 | return true; |
160 | }); |
161 | - |
162 | + |
163 | } |
164 | - |
165 | + |
166 | private bool draw_icon (Gtk.Widget widget, Gdk.EventExpose event) { |
167 | Gtk.Allocation size; |
168 | widget.get_allocation (out size); |
169 | var context = Gdk.cairo_create (widget.window); |
170 | - |
171 | + |
172 | // Draw icon |
173 | Gdk.cairo_set_source_pixbuf (context, this.icon, size.x + ((this.icon.width - size.width) / -2.0), size.y); |
174 | context.paint (); |
175 | - |
176 | + |
177 | // Truncate text |
178 | Cairo.TextExtents extents; |
179 | context.select_font_face ("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.NORMAL); |
180 | context.set_font_size (11.5); |
181 | Slingshot.Frontend.Utilities.truncate_text (context, size, 10, this.label, out this.label, out extents); // truncate text |
182 | - |
183 | + |
184 | // Draw text shadow |
185 | context.move_to ((size.x + size.width/2 - extents.width/2) + 1, (size.y + size.height - 10) + 1); |
186 | context.set_source_rgba (0.0, 0.0, 0.0, 0.8); |
187 | context.show_text (this.label); |
188 | - |
189 | - // Draw normal text |
190 | - context.set_source_rgba (1.0, 1.0, 1.0, 1.0); |
191 | + |
192 | + // Draw normal text |
193 | + context.set_source_rgba (1.0, 1.0, 1.0, 1.0); |
194 | context.move_to (size.x + size.width/2 - extents.width/2, size.y + size.height - 10); |
195 | context.show_text (this.label); |
196 | - |
197 | + |
198 | return false; |
199 | } |
200 | - |
201 | + |
202 | private bool draw_background (Gtk.Widget widget, Gdk.EventExpose event) { |
203 | Gtk.Allocation size; |
204 | widget.get_allocation (out size); |
205 | var context = Gdk.cairo_create (widget.window); |
206 | - |
207 | + |
208 | double progress; |
209 | if (this.current_frame > 1) { |
210 | progress = (double)this.RUN_LENGTH/(double)this.current_frame; |
211 | } else { |
212 | progress = 1; |
213 | } |
214 | - |
215 | + |
216 | if (this.has_focus) { |
217 | - |
218 | + |
219 | var linear_gradient = new Cairo.Pattern.linear (size.x, size.y, size.x, size.y + size.height); |
220 | linear_gradient.add_color_stop_rgba (0.0, this.prominent.R, this.prominent.G, this.prominent.B, 0.0); |
221 | linear_gradient.add_color_stop_rgba (0.5, this.prominent.R, this.prominent.G, this.prominent.B, 0.25/progress); |
222 | linear_gradient.add_color_stop_rgba (1.0, this.prominent.R, this.prominent.G, this.prominent.B, 0.4/progress); |
223 | - |
224 | + |
225 | context.set_source (linear_gradient); |
226 | Slingshot.Frontend.Utilities.draw_rounded_rectangle (context, 10, 0.5, size); |
227 | context.fill (); |
228 | - |
229 | + |
230 | } else { |
231 | - if (this.current_frame > 1) { |
232 | + if (this.current_frame > 1) { |
233 | var linear_gradient = new Cairo.Pattern.linear (size.x, size.y, size.x, size.y + size.height); |
234 | linear_gradient.add_color_stop_rgba (0.0, this.prominent.R, this.prominent.G, this.prominent.B, 0.0); |
235 | linear_gradient.add_color_stop_rgba (0.5, this.prominent.R, this.prominent.G, this.prominent.B, 0.25 - 0.25/progress); |
236 | linear_gradient.add_color_stop_rgba (1.0, this.prominent.R, this.prominent.G, this.prominent.B, 0.4 - 0.4/progress); |
237 | - |
238 | + |
239 | context.set_source (linear_gradient); |
240 | Slingshot.Frontend.Utilities.draw_rounded_rectangle (context, 10, 0.5, size); |
241 | context.fill (); |
242 | } |
243 | } |
244 | - |
245 | + |
246 | return false; |
247 | } |
248 | - |
249 | - |
250 | + |
251 | + |
252 | } |
253 | } |
254 | |
255 | === added file 'install' |
256 | --- install 1970-01-01 00:00:00 +0000 |
257 | +++ install 2011-08-10 18:49:27 +0000 |
258 | @@ -0,0 +1,5 @@ |
259 | +#!/bin/sh |
260 | + |
261 | +./build |
262 | + |
263 | +sudo mv slingshot /usr/bin/ |
264 | |
265 | === modified file 'slingshot.vala' |
266 | --- slingshot.vala 2011-02-19 14:51:06 +0000 |
267 | +++ slingshot.vala 2011-08-10 18:49:27 +0000 |
268 | @@ -3,11 +3,11 @@ |
269 | public GLib.List<Slingshot.Frontend.AppItem> children = new GLib.List<Slingshot.Frontend.AppItem> (); |
270 | public Slingshot.Frontend.Searchbar searchbar; |
271 | public Slingshot.Frontend.Grid grid; |
272 | - |
273 | + |
274 | public Gee.ArrayList<Gee.HashMap<string, string>> apps = new Gee.ArrayList<Gee.HashMap<string, string>> (); |
275 | public Gee.HashMap<string, Gdk.Pixbuf> icons = new Gee.HashMap<string, Gdk.Pixbuf>(); |
276 | public Gee.ArrayList<Gee.HashMap<string, string>> filtered = new Gee.ArrayList<Gee.HashMap<string, string>> (); |
277 | - |
278 | + |
279 | public Slingshot.Frontend.Indicators pages; |
280 | public Slingshot.Frontend.Indicators categories; |
281 | public Gee.ArrayList<GMenu.TreeDirectory> all_categories = Slingshot.Backend.GMenuEntries.get_categories (); |
282 | @@ -15,11 +15,13 @@ |
283 | public int total_pages; |
284 | public Gtk.HBox top_spacer; |
285 | |
286 | + Slingshot.Backend.AppMonitor monitor; |
287 | + public bool is_showing; |
288 | + |
289 | public SlingshotWindow () { |
290 | - |
291 | - // Show desktop |
292 | - Wnck.Screen.get_default().toggle_showing_desktop (true); |
293 | - |
294 | + |
295 | + this.is_showing = false; |
296 | + |
297 | // Window properties |
298 | this.title = "Slingshot"; |
299 | this.skip_pager_hint = true; |
300 | @@ -27,13 +29,13 @@ |
301 | this.set_type_hint (Gdk.WindowTypeHint.NORMAL); |
302 | this.maximize (); |
303 | this.stick (); |
304 | - this.set_keep_above (true); |
305 | - |
306 | + this.set_keep_above(true); |
307 | + |
308 | // Set icon size |
309 | Gdk.Rectangle monitor_dimensions; |
310 | Gdk.Screen screen = Gdk.Screen.get_default(); |
311 | screen.get_monitor_geometry(screen.get_primary_monitor(), out monitor_dimensions); |
312 | - |
313 | + |
314 | double suggested_size = (Math.pow (monitor_dimensions.width * monitor_dimensions.height, ((double) (1.0/3.0))) / 1.6); |
315 | if (suggested_size < 27) { |
316 | this.icon_size = 24; |
317 | @@ -44,22 +46,22 @@ |
318 | } else if (suggested_size >= 56) { |
319 | this.icon_size = 64; |
320 | } |
321 | - |
322 | + |
323 | // Get all apps |
324 | - Slingshot.Backend.GMenuEntries.enumerate_apps (Slingshot.Backend.GMenuEntries.get_all (), this.icons, this.icon_size, out this.apps); |
325 | - |
326 | + this.refresh_apps(); |
327 | + |
328 | // Add container wrapper |
329 | var wrapper = new Gtk.EventBox (); // used for the scrolling and button press events |
330 | wrapper.set_visible_window (false); |
331 | this.add (wrapper); |
332 | - |
333 | + |
334 | // Add container |
335 | var container = new Gtk.VBox (false, 15); |
336 | wrapper.add (container); |
337 | - |
338 | + |
339 | // Add top bar |
340 | var top = new Gtk.HBox (false, 0); |
341 | - |
342 | + |
343 | this.categories = new Slingshot.Frontend.Indicators (); |
344 | this.categories.child_activated.connect (this.change_category); |
345 | this.categories.append ("All"); |
346 | @@ -68,18 +70,18 @@ |
347 | } |
348 | this.categories.set_active (0); |
349 | top.pack_start (this.categories, true, true, 15); |
350 | - |
351 | + |
352 | this.top_spacer = new Gtk.HBox (false, 0); |
353 | this.top_spacer.realize.connect ( () => { this.top_spacer.visible = false; } ); |
354 | this.top_spacer.can_focus = true; |
355 | top.pack_start (this.top_spacer, false, false, 0); |
356 | - |
357 | + |
358 | this.searchbar = new Slingshot.Frontend.Searchbar ("Start typing to search..."); |
359 | this.searchbar.changed.connect (this.search); |
360 | top.pack_start (this.searchbar, false, true, 15); |
361 | - |
362 | - container.pack_start (top, false, true, 15); |
363 | - |
364 | + |
365 | + container.pack_start (top, false, true, 15); |
366 | + |
367 | // Make icon grid and populate |
368 | if (monitor_dimensions.width > monitor_dimensions.height) { // normal landscape orientation |
369 | this.grid = new Slingshot.Frontend.Grid (4, 6); |
370 | @@ -87,77 +89,82 @@ |
371 | this.grid = new Slingshot.Frontend.Grid (6, 4); |
372 | } |
373 | container.pack_start (this.grid, true, true, 0); |
374 | - |
375 | + |
376 | this.populate_grid (); |
377 | - |
378 | + |
379 | // Add pages |
380 | this.pages = new Slingshot.Frontend.Indicators (); |
381 | this.pages.child_activated.connect ( () => { this.update_grid (this.filtered); } ); |
382 | - |
383 | + |
384 | var pages_wrapper = new Gtk.HBox (false, 0); |
385 | - pages_wrapper.set_size_request (-1, 30); |
386 | + pages_wrapper.set_size_request (-1, 30); |
387 | container.pack_end (pages_wrapper, false, true, 15); |
388 | - |
389 | + |
390 | // Find number of pages and populate |
391 | this.update_pages (this.apps); |
392 | if (this.total_pages > 1) { |
393 | pages_wrapper.pack_start (this.pages, true, false, 0); |
394 | for (int p = 1; p <= this.total_pages; p++) { |
395 | this.pages.append (p.to_string ()); |
396 | - } |
397 | + } |
398 | } |
399 | this.pages.set_active (0); |
400 | - |
401 | + |
402 | // Signals and callbacks |
403 | - this.button_release_event.connect ( () => { this.destroy(); return false; }); |
404 | + this.button_release_event.connect ( () => { this.hide_slingshot(); return false; }); |
405 | this.expose_event.connect (this.draw_background); |
406 | - this.focus_out_event.connect ( () => { this.destroy(); return true; } ); // close slingshot when the window loses focus |
407 | + this.focus_out_event.connect ( () => { this.hide_slingshot(); return true; } ); // close slingshot when the window loses focus |
408 | + |
409 | + //set up app monitor |
410 | + //refreshes when apps are added/removed |
411 | + this.monitor = new Slingshot.Backend.AppMonitor(); |
412 | + this.monitor.changed.connect(this.refresh_apps); |
413 | } |
414 | - |
415 | - private void populate_grid () { |
416 | - |
417 | + |
418 | + private void populate_grid () { |
419 | + |
420 | for (int r = 0; r < this.grid.n_rows; r++) { |
421 | - |
422 | + |
423 | for (int c = 0; c < this.grid.n_columns; c++) { |
424 | - |
425 | + |
426 | var item = new Slingshot.Frontend.AppItem (this.icon_size); |
427 | this.children.append (item); |
428 | - |
429 | + |
430 | item.button_press_event.connect ( () => { item.grab_focus (); return true; } ); |
431 | item.enter_notify_event.connect ( () => { item.grab_focus (); return true; } ); |
432 | item.leave_notify_event.connect ( () => { this.top_spacer.grab_focus (); return true; } ); |
433 | item.button_release_event.connect ( () => { |
434 | - |
435 | + |
436 | try { |
437 | new GLib.DesktopAppInfo.from_filename (this.filtered.get((int) (this.children.index(item) + (this.pages.active * this.grid.n_columns * this.grid.n_rows)))["desktop_file"]).launch (null, null); |
438 | - this.destroy(); |
439 | + this.hide_slingshot(); |
440 | } catch (GLib.Error e) { |
441 | stdout.printf("Error! Load application: " + e.message); |
442 | } |
443 | - |
444 | + |
445 | return true; |
446 | - |
447 | + |
448 | }); |
449 | - |
450 | + |
451 | this.grid.attach (item, c, c + 1, r, r + 1, Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.EXPAND, 0, 0); |
452 | - |
453 | - } |
454 | - } |
455 | + |
456 | + } |
457 | + } |
458 | } |
459 | - |
460 | - private void update_grid (Gee.ArrayList<Gee.HashMap<string, string>> apps) { |
461 | - |
462 | + |
463 | + private void update_grid (Gee.ArrayList<Gee.HashMap<string, string>> apps) { |
464 | + |
465 | int item_iter = (int)(this.pages.active * this.grid.n_columns * this.grid.n_rows); |
466 | for (int r = 0; r < this.grid.n_rows; r++) { |
467 | - |
468 | + |
469 | for (int c = 0; c < this.grid.n_columns; c++) { |
470 | - |
471 | + |
472 | int table_pos = c + (r * (int)this.grid.n_columns); // position in table right now |
473 | - |
474 | + |
475 | var item = this.children.nth_data(table_pos); |
476 | if (item_iter < apps.size) { |
477 | var current_item = apps.get(item_iter); |
478 | - |
479 | + |
480 | // Update app |
481 | if (current_item["description"] == null || current_item["description"] == "") { |
482 | item.change_app (icons[current_item["command"]], current_item["name"], current_item["name"]); |
483 | @@ -169,36 +176,36 @@ |
484 | } else { // fill with a blank one |
485 | item.visible = false; |
486 | } |
487 | - |
488 | + |
489 | item_iter++; |
490 | - |
491 | + |
492 | } |
493 | } |
494 | - |
495 | + |
496 | // Update number of pages |
497 | this.update_pages (apps); |
498 | - |
499 | + |
500 | // Grab first one's focus |
501 | this.children.nth_data (0).grab_focus (); |
502 | } |
503 | - |
504 | + |
505 | private void change_category () { |
506 | this.filtered.clear (); |
507 | - |
508 | + |
509 | if (this.categories.active != 0) { |
510 | Slingshot.Backend.GMenuEntries.enumerate_apps (Slingshot.Backend.GMenuEntries.get_applications_for_category (this.all_categories.get (this.categories.active - 1)), this.icons, this.icon_size, out this.filtered); |
511 | } else { |
512 | this.filtered.add_all (this.apps); |
513 | } |
514 | - |
515 | + |
516 | this.pages.set_active (0); // go back to first page in category |
517 | } |
518 | - |
519 | + |
520 | private void update_pages (Gee.ArrayList<Gee.HashMap<string, string>> apps) { |
521 | // Find current number of pages and update count |
522 | var num_pages = (int) (apps.size / (this.grid.n_columns * this.grid.n_rows)); |
523 | (double) apps.size % (double) (this.grid.n_columns * this.grid.n_rows) > 0 ? this.total_pages = num_pages + 1 : this.total_pages = num_pages; |
524 | - |
525 | + |
526 | // Update pages |
527 | if (this.total_pages > 1) { |
528 | this.pages.visible = true; |
529 | @@ -208,41 +215,41 @@ |
530 | } else { |
531 | this.pages.visible = false; |
532 | } |
533 | - |
534 | + |
535 | } |
536 | - |
537 | + |
538 | private void search() { |
539 | - |
540 | + |
541 | var current_text = this.searchbar.text.down (); |
542 | - |
543 | + |
544 | this.categories.set_active_no_signal (0); // switch to first page |
545 | this.filtered.clear (); |
546 | - |
547 | + |
548 | foreach (Gee.HashMap<string, string> app in this.apps) { |
549 | if (current_text in app["name"].down () || current_text in app["description"].down () || current_text in app["command"].down ()) { |
550 | this.filtered.add (app); |
551 | } |
552 | - } |
553 | - |
554 | - this.pages.set_active (0); |
555 | - |
556 | + } |
557 | + |
558 | + this.pages.set_active (0); |
559 | + |
560 | this.queue_draw (); |
561 | } |
562 | - |
563 | + |
564 | private void page_left() { |
565 | - |
566 | + |
567 | if (this.pages.active >= 1) { |
568 | this.pages.set_active (this.pages.active - 1); |
569 | } |
570 | - |
571 | + |
572 | } |
573 | - |
574 | + |
575 | private void page_right() { |
576 | - |
577 | + |
578 | if ((this.pages.active + 1) < this.total_pages) { |
579 | this.pages.set_active (this.pages.active + 1); |
580 | } |
581 | - |
582 | + |
583 | } |
584 | |
585 | private bool draw_background (Gtk.Widget widget, Gdk.EventExpose event) { |
586 | @@ -253,21 +260,19 @@ |
587 | // Semi-dark background |
588 | var linear_gradient = new Cairo.Pattern.linear (size.x, size.y, size.x, size.y + size.height); |
589 | linear_gradient.add_color_stop_rgba (0.0, 0.0, 0.0, 0.0, 0.65); |
590 | - linear_gradient.add_color_stop_rgba (0.85, 0.0, 0.0, 0.0, 0.65); |
591 | - linear_gradient.add_color_stop_rgba (0.99, 0.0, 0.0, 0.0, 0.0); |
592 | - |
593 | + |
594 | context.set_source (linear_gradient); |
595 | context.paint (); |
596 | - |
597 | + |
598 | return false; |
599 | } |
600 | - |
601 | + |
602 | // Keyboard shortcuts |
603 | public override bool key_press_event (Gdk.EventKey event) { |
604 | switch (Gdk.keyval_name (event.keyval)) { |
605 | - |
606 | + |
607 | case "Escape": |
608 | - this.destroy (); |
609 | + this.hide_slingshot (); |
610 | return true; |
611 | case "ISO_Left_Tab": |
612 | this.page_left (); |
613 | @@ -284,7 +289,10 @@ |
614 | } |
615 | return true; |
616 | case "BackSpace": |
617 | - this.searchbar.text = this.searchbar.text.slice (0, (int) this.searchbar.text.length - 1); |
618 | + int len = (int) this.searchbar.text.length; |
619 | + if (len > 0) { |
620 | + this.searchbar.text = this.searchbar.text.slice (0,len - 1); |
621 | + } |
622 | return true; |
623 | case "Left": |
624 | var current_item = this.grid.get_children ().index (this.get_focus ()); |
625 | @@ -292,7 +300,7 @@ |
626 | this.page_left (); |
627 | return true; |
628 | } |
629 | - |
630 | + |
631 | break; |
632 | case "Right": |
633 | var current_item = this.grid.get_children ().index (this.get_focus ()); |
634 | @@ -308,16 +316,16 @@ |
635 | this.searchbar.text = this.searchbar.text + event.str; |
636 | break; |
637 | } |
638 | - |
639 | + |
640 | base.key_press_event (event); |
641 | return false; |
642 | - |
643 | + |
644 | } |
645 | - |
646 | + |
647 | // Scrolling left/right for pages |
648 | public override bool scroll_event (Gdk.EventScroll event) { |
649 | switch (event.direction.to_string()) { |
650 | - |
651 | + |
652 | case "GDK_SCROLL_UP": |
653 | case "GDK_SCROLL_LEFT": |
654 | this.page_left (); |
655 | @@ -326,43 +334,98 @@ |
656 | case "GDK_SCROLL_RIGHT": |
657 | this.page_right (); |
658 | break; |
659 | - |
660 | + |
661 | } |
662 | - |
663 | + |
664 | return false; |
665 | } |
666 | - |
667 | + |
668 | + public void refresh_apps () { |
669 | + print("Refreshing applications list\n"); |
670 | + Slingshot.Backend.GMenuEntries.enumerate_apps (Slingshot.Backend.GMenuEntries.get_all (), this.icons, this.icon_size, out this.apps); |
671 | + } |
672 | + |
673 | + public void hide_slingshot () { |
674 | + this.iconify(); |
675 | + this.categories.set_active (0); |
676 | + this.change_category(); |
677 | + this.searchbar.text = ""; |
678 | + this.is_showing = false; |
679 | + Wnck.Screen.get_default().toggle_showing_desktop(false); |
680 | + } |
681 | + |
682 | + public void show_slingshot () { |
683 | + Wnck.Screen.get_default().toggle_showing_desktop(true); |
684 | + this.deiconify(); |
685 | + this.is_showing = true; |
686 | + } |
687 | + |
688 | + public void toggle_slingshot () { |
689 | + if (this.is_showing) { |
690 | + print("Hiding slingshot.\n"); |
691 | + this.hide_slingshot(); |
692 | + } else { |
693 | + print("Showing slingshot.\n"); |
694 | + this.show_slingshot(); |
695 | + } |
696 | + } |
697 | + |
698 | // Override destroy for fade out and stuff |
699 | public new void destroy () { |
700 | // Restore windows |
701 | - Wnck.Screen.get_default ().toggle_showing_desktop (false); |
702 | - |
703 | + //Wnck.Screen.get_default ().toggle_showing_desktop (false); |
704 | + |
705 | base.destroy(); |
706 | Gtk.main_quit(); |
707 | } |
708 | - |
709 | -} |
710 | + |
711 | +} |
712 | + |
713 | + |
714 | +public class SlingshotApp : GLib.Object { |
715 | + |
716 | + Unique.App app; |
717 | + SlingshotWindow main_win; |
718 | + |
719 | + public SlingshotApp (/*string[] args*/) { |
720 | + this.app = new Unique.App("org.elementary.slingshot", null); |
721 | + if (this.app.is_running) { |
722 | + print("Slingshot is already running.\n"); |
723 | + Unique.Command command = Unique.Command.ACTIVATE; |
724 | + this.app.send_message (command, new Unique.MessageData()); |
725 | + } else { |
726 | + this.app.message_received.connect(this.toggle); |
727 | + this.create(/*args*/); |
728 | + } |
729 | + } |
730 | + |
731 | + public Unique.Response toggle (int command, Unique.MessageData message_data, uint time_) { |
732 | + if (command == Unique.Command.ACTIVATE) { |
733 | + print("Toggling slingshot.\n"); |
734 | + this.main_win.toggle_slingshot(); |
735 | + } |
736 | + return Unique.Response.OK; |
737 | + } |
738 | + |
739 | + void create (/*string[] args*/) { |
740 | + //Gtk.init(ref args); |
741 | + print("Starting new slingshot instance.\n"); |
742 | + this.main_win = new SlingshotWindow(); |
743 | + this.main_win.show_all(); |
744 | + this.main_win.iconify(); |
745 | + Gtk.main(); |
746 | + } |
747 | + |
748 | +} |
749 | + |
750 | |
751 | int main (string[] args) { |
752 | |
753 | - Gtk.init (ref args); |
754 | - |
755 | - Unique.App app = new Unique.App ("org.elementary.slingshot", null); |
756 | - |
757 | - if (app.is_running) { //close if already running |
758 | - Unique.Command command = Unique.Command.NEW; |
759 | - app.send_message (command, new Unique.MessageData()); |
760 | - } else { |
761 | - |
762 | - var main_win = new SlingshotWindow (); |
763 | - main_win.show_all (); |
764 | - |
765 | - app.watch_window (main_win); |
766 | - |
767 | - Gtk.main (); |
768 | - } |
769 | - |
770 | + Gtk.init(ref args); //~ |
771 | + |
772 | + new SlingshotApp(/*args*/); |
773 | + |
774 | return 1; |
775 | - |
776 | + |
777 | } |
778 |
Apparently, this branch has been merged separately (i.e. the branch hasn't been merged directly but parts were taken) so we have these features in the trunk now.
Thanks for your work :)