Merge lp:~tintou/slingshot/gtk-popover into lp:~elementary-pantheon/slingshot/trunk

Proposed by Corentin Noël on 2015-01-18
Status: Merged
Approved by: Daniel Fore on 2015-02-01
Approved revision: 505
Merged at revision: 500
Proposed branch: lp:~tintou/slingshot/gtk-popover
Merge into: lp:~elementary-pantheon/slingshot/trunk
Diff against target: 1152 lines (+196/-392)
11 files modified
CMakeLists.txt (+1/-2)
cmake/ValaPrecompile.cmake (+0/-1)
src/Pixels.vala (+2/-2)
src/Slingshot.vala (+1/-2)
src/SlingshotView.vala (+142/-104)
src/Widgets/AppEntry.vala (+22/-28)
src/Widgets/CategoryView.vala (+2/-4)
src/Widgets/Grid.vala (+18/-20)
src/Widgets/PopoverMenu.vala (+0/-188)
src/Widgets/SearchItem.vala (+2/-2)
src/Widgets/SearchView.vala (+6/-39)
To merge this branch: bzr merge lp:~tintou/slingshot/gtk-popover
Reviewer Review Type Date Requested Status
Daniel Fore 2015-01-18 Needs Fixing on 2015-01-18
Review via email: mp+246836@code.launchpad.net

Commit message

Make use of Gtk.Popover instead of Granite.Popover.
Animates the view change from the edges.
Use real size of App Buttons (removed useless and wrong code)

Description of the change

Make use of Gtk.Popover instead of Granite.Popover.
Animates the view change from the edges.
Use real size of App Buttons (removed useless and wrong code)

To post a comment you must log in.
lp:~tintou/slingshot/gtk-popover updated on 2015-01-18
501. By Corentin Noël on 2015-01-18

Fixed RTL animation.

502. By Corentin Noël on 2015-01-18

Use Gtk.STYLE_CLASS_FLAT instead of "app" class.

Daniel Fore (danrabbit) wrote :

This seems to be quite an improvement overall. Gaining regular right click menus and also the cut/copy/paste/etc menu is killer.

I love that the animations go to the edge of the popover. Very sexy!

Something that is annoying is that it seems to animate from the bottom up. I see this as a regression. Ideally it would animate from the origin towards the opposite corner of the display. But at least the current version animates from the center out.

It does seem that this makes Slingshot shorter, which is a bit weird at first, but I think it'll be easy to get used to. I wouldn't really consider this a regression.

When navigating by keyboard, I noticed that moving from the 2nd-to-last to the last page, you can lose the selection if you go from the 2nd (or 3rd) row and there is only 1 row on the last page.

The scrolled window in the search view should have a right margin. Unfortunately because of the rounded corners, it seems to hang off of the bottom right corner of the popover.

There is also a small jump where the popover resizes between grid and search views

lp:~tintou/slingshot/gtk-popover updated on 2015-01-18
503. By Corentin Noël on 2015-01-18

Restore Granite's popover appearing behavior.
Fixed RTL navigation.

Daniel Fore (danrabbit) wrote :

If I open a right click menu and then click outside the popover, it will not be dismissed no matter how many times I click outside the popover

review: Needs Fixing
Cody Garver (codygarver) wrote :

So far I've only found these problems:

* Dan's right click issue mentioned above
* The Popover arrow is closer to the panel than before
* Hovering over icons with cursor gives no highlight
* The top search result is no longer highlighted

lp:~tintou/slingshot/gtk-popover updated on 2015-02-01
504. By Corentin Noël on 2015-02-01

Grab pointer action after showing a menu.

505. By Corentin Noël on 2015-02-01

Fixed alignments with other popovers.

Corentin Noël (tintou) wrote :

I fixed the right click issue and the popover arrow being closer than before.
Hovering is now fixed with new theme revisions.

Daniel Fore (danrabbit) wrote :

I can confirm:
* right click issue is fixed.
* Popover top is aligned with other popover tops
* Hovering over items is indeed a theme problem now

With the search results, focus doesn't seem to want to leave the search box even with pressing arrow keys or tab. Did something change there?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-10-17 01:18:02 +0000
+++ CMakeLists.txt 2015-02-01 15:13:29 +0000
@@ -83,7 +83,6 @@
83 src/Widgets/SearchItem.vala83 src/Widgets/SearchItem.vala
84 src/Widgets/Sidebar.vala84 src/Widgets/Sidebar.vala
85 src/Widgets/CategoryView.vala85 src/Widgets/CategoryView.vala
86 src/Widgets/PopoverMenu.vala
87PACKAGES86PACKAGES
88 ${CORE_DEPS}87 ${CORE_DEPS}
89 ${UI_DEPS}88 ${UI_DEPS}
@@ -128,4 +127,4 @@
128add_schema ("org.pantheon.desktop.slingshot.gschema.xml")127add_schema ("org.pantheon.desktop.slingshot.gschema.xml")
129128
130# Translations129# Translations
131add_subdirectory (po)
132\ No newline at end of file130\ No newline at end of file
131add_subdirectory (po)
133132
=== modified file 'cmake/ValaPrecompile.cmake'
--- cmake/ValaPrecompile.cmake 2014-07-21 11:27:34 +0000
+++ cmake/ValaPrecompile.cmake 2015-02-01 15:13:29 +0000
@@ -229,7 +229,6 @@
229 ${vala_pkg_opts} 229 ${vala_pkg_opts}
230 ${ARGS_OPTIONS} 230 ${ARGS_OPTIONS}
231 "-g"231 "-g"
232 "--save-temps"
233 ${in_files} 232 ${in_files}
234 ${custom_vapi_arguments}233 ${custom_vapi_arguments}
235 COMMAND234 COMMAND
236235
=== modified file 'src/Pixels.vala'
--- src/Pixels.vala 2014-08-14 20:09:55 +0000
+++ src/Pixels.vala 2015-02-01 15:13:29 +0000
@@ -1,9 +1,9 @@
1namespace Slingshot.Pixels {1namespace Slingshot.Pixels {
22
3 const int PADDING = 17;3 const int PADDING = 17;
4 const int ROW_SPACING = 20;4 const int ROW_SPACING = 12;
5 const int ITEM_SIZE = 130;5 const int ITEM_SIZE = 130;
6 const int BOTTOM_SPACE = 180;6 const int BOTTOM_SPACE = 180;
7 const int SIDEBAR_GRID_PADDING = 5;7 const int SIDEBAR_GRID_PADDING = 5;
8 const int SIDEBAR_WIDTH = PADDING + ITEM_SIZE - SIDEBAR_GRID_PADDING - 1;8 const int SIDEBAR_WIDTH = PADDING + ITEM_SIZE - SIDEBAR_GRID_PADDING - 1;
9}
10\ No newline at end of file9\ No newline at end of file
10}
1111
=== modified file 'src/Slingshot.vala'
--- src/Slingshot.vala 2014-06-12 09:14:57 +0000
+++ src/Slingshot.vala 2015-02-01 15:13:29 +0000
@@ -69,12 +69,11 @@
69 dbus_service = new DBusService (view);69 dbus_service = new DBusService (view);
7070
71 if (!silent) {71 if (!silent) {
72 //view.move_to_coords (0, 0);
73 view.show_slingshot ();72 view.show_slingshot ();
74 }73 }
75 } else {74 } else {
76 if (view.visible && !silent)75 if (view.visible && !silent)
77 view.hide (); 76 view.hide ();
78 else77 else
79 view.show_slingshot ();78 view.show_slingshot ();
80 }79 }
8180
=== modified file 'src/SlingshotView.vala'
--- src/SlingshotView.vala 2014-11-08 10:49:08 +0000
+++ src/SlingshotView.vala 2015-02-01 15:13:29 +0000
@@ -24,15 +24,13 @@
24 SEARCH_VIEW24 SEARCH_VIEW
25 }25 }
2626
27 public class SlingshotView : Granite.Widgets.PopOver {27 public class SlingshotView : Granite.Widgets.CompositedWindow {
2828
29 // Widgets29 // Widgets
30 public Gtk.SearchEntry search_entry;30 public Gtk.SearchEntry search_entry;
31 public Gtk.Stack stack;31 public Gtk.Stack stack;
32 public Granite.Widgets.ModeButton view_selector;32 public Granite.Widgets.ModeButton view_selector;
33 private Gtk.Revealer view_selector_revealer;33 private Gtk.Revealer view_selector_revealer;
34 // Single popover to use for all of app as context menu
35 private Widgets.NofocusPopover context_popover;
3634
37 // Views35 // Views
38 private Widgets.Grid grid_view;36 private Widgets.Grid grid_view;
@@ -44,6 +42,8 @@
44 public Gtk.Stack main_stack;42 public Gtk.Stack main_stack;
45 public Gtk.Box content_area;43 public Gtk.Box content_area;
46 private Gtk.EventBox event_box;44 private Gtk.EventBox event_box;
45 private Gtk.Popover popover;
46 private Gtk.Grid ref_grid;
4747
48 public Backend.AppSystem app_system;48 public Backend.AppSystem app_system;
49 private Gee.ArrayList<GMenu.TreeDirectory> categories;49 private Gee.ArrayList<GMenu.TreeDirectory> categories;
@@ -75,13 +75,17 @@
75 private int category_column_focus = 0;75 private int category_column_focus = 0;
76 private int category_row_focus = 0;76 private int category_row_focus = 0;
7777
78 private int primary_monitor = 0;
79
78 public SlingshotView () {80 public SlingshotView () {
7981
80 // Window properties82 // Window properties
81 this.title = "Slingshot";83 this.title = "Slingshot";
82 this.skip_pager_hint = true;84 this.skip_pager_hint = true;
83 this.skip_taskbar_hint = true;85 this.skip_taskbar_hint = true;
84 set_keep_above (true);86 this.set_keep_above (true);
87 this.set_type_hint (Gdk.WindowTypeHint.MENU);
88 this.focus_on_map = true;
8589
86 // Have the window in the right place90 // Have the window in the right place
87 read_settings (true);91 read_settings (true);
@@ -94,12 +98,14 @@
94 categories = app_system.get_categories ();98 categories = app_system.get_categories ();
95 apps = app_system.get_apps ();99 apps = app_system.get_apps ();
96100
97 if (Slingshot.settings.screen_resolution != @"$(screen.get_width ())x$(screen.get_height ())")101 primary_monitor = screen.get_primary_monitor ();
102 Gdk.Rectangle geometry;
103 screen.get_monitor_geometry (primary_monitor, out geometry);
104 if (Slingshot.settings.screen_resolution != @"$(geometry.width)x$(geometry.height)")
98 setup_size ();105 setup_size ();
99106
100 height_request = calculate_grid_height () + Pixels.BOTTOM_SPACE;107 height_request = calculate_grid_height () + Pixels.BOTTOM_SPACE;
101 setup_ui ();108 setup_ui ();
102 context_popover = new Widgets.NofocusPopover (this, event_box);
103109
104 connect_signals ();110 connect_signals ();
105 debug ("Apps loaded");111 debug ("Apps loaded");
@@ -115,16 +121,18 @@
115 }121 }
116122
117 private void setup_size () {123 private void setup_size () {
118
119 debug ("In setup_size ()");124 debug ("In setup_size ()");
120 Slingshot.settings.screen_resolution = @"$(screen.get_width ())x$(screen.get_height ())";125 primary_monitor = screen.get_primary_monitor ();
126 Gdk.Rectangle geometry;
127 screen.get_monitor_geometry (primary_monitor, out geometry);
128 Slingshot.settings.screen_resolution = @"$(geometry.width)x$(geometry.height)";
121 default_columns = 5;129 default_columns = 5;
122 default_rows = 3;130 default_rows = 3;
123 while ((calculate_grid_width () >= 2 * screen.get_width () / 3)) {131 while ((calculate_grid_width () >= 2 * geometry.width / 3)) {
124 default_columns--;132 default_columns--;
125 }133 }
126134
127 while ((calculate_grid_height () >= 2 * screen.get_height () / 3)) {135 while ((calculate_grid_height () >= 2 * geometry.width / 3)) {
128 default_rows--;136 default_rows--;
129 }137 }
130138
@@ -142,15 +150,17 @@
142 // Create the base container150 // Create the base container
143 container = new Gtk.Grid ();151 container = new Gtk.Grid ();
144 container.row_spacing = 12;152 container.row_spacing = 12;
153 container.margin_top = 12;
145154
146 // Add top bar155 // Add top bar
147 top = new Gtk.Grid ();156 top = new Gtk.Grid ();
148 top.orientation = Gtk.Orientation.HORIZONTAL;157 top.orientation = Gtk.Orientation.HORIZONTAL;
149 top.margin_start = 12;158 top.margin_start = 6;
150 top.margin_end = 12;159 top.margin_end = 6;
151160
152 view_selector = new Granite.Widgets.ModeButton ();161 view_selector = new Granite.Widgets.ModeButton ();
153 view_selector.margin_end = 12;162 view_selector.margin_end = 6;
163 view_selector.margin_start = 6;
154 view_selector_revealer = new Gtk.Revealer ();164 view_selector_revealer = new Gtk.Revealer ();
155 view_selector_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT;165 view_selector_revealer.transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT;
156 view_selector_revealer.add (view_selector);166 view_selector_revealer.add (view_selector);
@@ -171,7 +181,8 @@
171 search_entry = new Gtk.SearchEntry ();181 search_entry = new Gtk.SearchEntry ();
172 search_entry.placeholder_text = _("Search Apps");182 search_entry.placeholder_text = _("Search Apps");
173 search_entry.hexpand = true;183 search_entry.hexpand = true;
174 search_entry.button_press_event.connect ((e) => {return e.button == 3;});184 search_entry.margin_start = 6;
185 search_entry.margin_end = 6;
175186
176 if (Slingshot.settings.show_category_filter) {187 if (Slingshot.settings.show_category_filter) {
177 top.add (view_selector_revealer);188 top.add (view_selector_revealer);
@@ -191,6 +202,7 @@
191202
192 // Create the "SEARCH_VIEW"203 // Create the "SEARCH_VIEW"
193 search_view = new Widgets.SearchView (this);204 search_view = new Widgets.SearchView (this);
205 search_view.margin_end = 6;
194 search_view.start_search.connect ((match, target) => {206 search_view.start_search.connect ((match, target) => {
195 search.begin (search_entry.text, match, target);207 search.begin (search_entry.text, match, target);
196 });208 });
@@ -203,22 +215,24 @@
203 event_box = new Gtk.EventBox ();215 event_box = new Gtk.EventBox ();
204 event_box.add (container);216 event_box.add (container);
205 // Add the container to the dialog's content area217 // Add the container to the dialog's content area
206 content_area = get_content_area () as Gtk.Box;218
207 content_area.pack_start (event_box);219 ref_grid = new Gtk.Grid ();
208 content_area.set_margin_start (SHADOW_SIZE-1);220 this.add (ref_grid);
209 content_area.set_margin_end (SHADOW_SIZE-1);221
210 content_area.set_margin_top (SHADOW_SIZE-1);222 popover = new Gtk.Popover (ref_grid);
211 content_area.set_margin_bottom (SHADOW_SIZE-1);223 popover.add (event_box);
224 popover.set_position (Gtk.PositionType.TOP);
225
226 this.show.connect (() => popover.show ());
212227
213 if (Slingshot.settings.use_category)228 if (Slingshot.settings.use_category)
214 set_modality (Modality.CATEGORY_VIEW);229 set_modality (Modality.CATEGORY_VIEW);
215 else230 else
216 set_modality (Modality.NORMAL_VIEW);231 set_modality (Modality.NORMAL_VIEW);
217 debug ("Ui setup completed");232 debug ("Ui setup completed");
218
219 }233 }
220234
221 private void grab_device () {235 public void grab_device () {
222 var display = Gdk.Display.get_default ();236 var display = Gdk.Display.get_default ();
223 var pointer = display.get_device_manager ().get_client_pointer ();237 var pointer = display.get_device_manager ().get_client_pointer ();
224 var keyboard = pointer.associated_device;238 var keyboard = pointer.associated_device;
@@ -259,6 +273,14 @@
259 return false;273 return false;
260 }274 }
261275
276 public override void get_preferred_width (out int minimum_width, out int natural_width) {
277 popover.get_preferred_width (out minimum_width, out natural_width);
278 }
279
280 public override void get_preferred_height (out int minimum_height, out int natural_height) {
281 popover.get_preferred_height (out minimum_height, out natural_height);
282 }
283
262 public override bool map_event (Gdk.EventAny event) {284 public override bool map_event (Gdk.EventAny event) {
263 if (visible)285 if (visible)
264 grab_device ();286 grab_device ();
@@ -286,7 +308,12 @@
286308
287 event_box.key_press_event.connect (on_key_press);309 event_box.key_press_event.connect (on_key_press);
288 search_entry.key_press_event.connect (search_entry_key_press);310 search_entry.key_press_event.connect (search_entry_key_press);
289311 // Showing a menu reverts the effect of the grab_device function.
312 search_entry.populate_popup.connect ((menu) => {
313 menu.hide.connect (() => {
314 grab_device ();
315 });
316 });
290 search_entry.search_changed.connect (() => {317 search_entry.search_changed.connect (() => {
291 if (modality != Modality.SEARCH_VIEW)318 if (modality != Modality.SEARCH_VIEW)
292 set_modality (Modality.SEARCH_VIEW);319 set_modality (Modality.SEARCH_VIEW);
@@ -321,15 +348,23 @@
321348
322 // position on the right monitor when settings changed349 // position on the right monitor when settings changed
323 screen.size_changed.connect (() => {350 screen.size_changed.connect (() => {
324 setup_size ();351 Gdk.Rectangle geometry;
325 reposition (false);352 screen.get_monitor_geometry (screen.get_primary_monitor (), out geometry);
353 if (Slingshot.settings.screen_resolution != @"$(geometry.width)x$(geometry.height)") {
354 setup_size ();
355 }
356 reposition ();
326 });357 });
327 screen.monitors_changed.connect (() => {358 screen.monitors_changed.connect (() => {
328 reposition (false);359 reposition ();
329 });360 });
330361
331 get_style_context ().notify["direction"].connect (() => {362 get_style_context ().notify["direction"].connect (() => {
332 reposition (false);363 reposition ();
364 });
365
366 popover.hide.connect (() => {
367 hide ();
333 });368 });
334369
335 // check for change in gala settings370 // check for change in gala settings
@@ -340,19 +375,6 @@
340 motion_notify_event.connect (hotcorner_trigger);375 motion_notify_event.connect (hotcorner_trigger);
341 }376 }
342377
343 public void show_popover_menu (Gtk.Widget menu, Gtk.Widget relative) {
344 context_popover = new Widgets.NofocusPopover (this, event_box);
345 context_popover.set_relative_to (relative);
346 context_popover.add (menu);
347 context_popover.show_all ();
348
349 var entry = relative as Widgets.AppEntry;
350 if (entry != null)
351 entry.app_launched.connect (() => {context_popover.hide ();});
352
353 relative.grab_focus ();
354 }
355
356 private void gala_settings_changed () {378 private void gala_settings_changed () {
357 if (Slingshot.settings.gala_settings.hotcorner_topleft == "open-launcher") {379 if (Slingshot.settings.gala_settings.hotcorner_topleft == "open-launcher") {
358 can_trigger_hotcorner = true;380 can_trigger_hotcorner = true;
@@ -361,22 +383,20 @@
361 }383 }
362 }384 }
363385
364 private void reposition (bool show=true) {386 private void reposition () {
365 debug("Repositioning");387 debug("Repositioning");
366388
367 Gdk.Rectangle monitor_dimensions, app_launcher_pos;389 Gdk.Rectangle monitor_dimensions;
368 screen.get_monitor_geometry (this.screen.get_primary_monitor(), out monitor_dimensions);390 screen.get_monitor_geometry (this.screen.get_primary_monitor(), out monitor_dimensions);
369 app_launcher_pos = Gdk.Rectangle () { x = monitor_dimensions.x,391 if (get_style_context ().direction == Gtk.TextDirection.LTR) {
370 y = monitor_dimensions.y,392 popover.set_pointing_to ({36, 0, 0, 0});
371 width = 100,393 // Added 36px to y to be aligned with other popovers.
372 height = 30394 move (monitor_dimensions.x, monitor_dimensions.y + 36);
373 };395 } else {
374396 popover.set_pointing_to ({ref_grid.get_window ().get_width () - 36, 0, 0, 0});
375 if (get_style_context ().direction == Gtk.TextDirection.RTL) {397 // Added 36px to y to be aligned with other popovers.
376 app_launcher_pos.x += monitor_dimensions.width - this.get_window ().get_width ();398 move (monitor_dimensions.x + monitor_dimensions.width - this.get_window ().get_width (), monitor_dimensions.y + 36);
377 }399 }
378
379 move_to_rect (app_launcher_pos, show);
380 }400 }
381401
382 private void change_view_mode (string key) {402 private void change_view_mode (string key) {
@@ -519,40 +539,27 @@
519 break;539 break;
520540
521 case "Left":541 case "Left":
522 if (modality == Modality.NORMAL_VIEW) {542 if (modality != Modality.NORMAL_VIEW && modality != Modality.CATEGORY_VIEW)
523 if (event.state == Gdk.ModifierType.SHIFT_MASK) {// Shift + Left
524 grid_view.go_to_previous ();
525 } else {
526 normal_move_focus (-1, 0);
527 }
528 } else if (modality == Modality.CATEGORY_VIEW) {
529 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Left
530 category_view.app_view.go_to_previous ();
531 else if (!search_entry.has_focus) {//the user has already selected an AppEntry
532 category_move_focus (-1, 0);
533 }
534 } else
535 return false;543 return false;
544
545 if (get_style_context ().direction == Gtk.TextDirection.LTR) {
546 move_left (event);
547 } else {
548 move_right (event);
549 }
550
536 break;551 break;
537
538 case "Right":552 case "Right":
539 if (modality == Modality.NORMAL_VIEW) {553 if (modality != Modality.NORMAL_VIEW && modality != Modality.CATEGORY_VIEW)
540 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right554 return false;
541 grid_view.go_to_next ();555
542 else556 if (get_style_context ().direction == Gtk.TextDirection.LTR) {
543 normal_move_focus (+1, 0);557 move_right (event);
544 } else if (modality == Modality.CATEGORY_VIEW) {
545 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right
546 category_view.app_view.go_to_next ();
547 else if (search_entry.has_focus) // there's no AppEntry selected, the user is switching category
548 top_left_focus ();
549 else //the user has already selected an AppEntry
550 category_move_focus (+1, 0);
551 } else {558 } else {
552 return false;559 move_left (event);
553 }560 }
561
554 break;562 break;
555
556 case "Up":563 case "Up":
557 if (modality == Modality.NORMAL_VIEW) {564 if (modality == Modality.NORMAL_VIEW) {
558 normal_move_focus (0, -1);565 normal_move_focus (0, -1);
@@ -667,7 +674,6 @@
667 }674 }
668675
669 public override bool scroll_event (Gdk.EventScroll event) {676 public override bool scroll_event (Gdk.EventScroll event) {
670 context_popover.hide ();
671 switch (event.direction.to_string ()) {677 switch (event.direction.to_string ()) {
672 case "GDK_SCROLL_UP":678 case "GDK_SCROLL_UP":
673 case "GDK_SCROLL_LEFT":679 case "GDK_SCROLL_LEFT":
@@ -687,15 +693,14 @@
687 }693 }
688694
689 return false;695 return false;
690
691 }696 }
692697
693 public void show_slingshot () {698 public void show_slingshot () {
694 context_popover.hide ();
695 search_entry.text = "";699 search_entry.text = "";
696700
697 reposition ();701 reposition ();
698 show_all ();702 show_all ();
703 popover.show_all ();
699 present ();704 present ();
700705
701 set_focus (null);706 set_focus (null);
@@ -708,6 +713,44 @@
708 stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;713 stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
709 }714 }
710715
716 /*
717 * Moves the current view to the left (undependent of the TextDirection).
718 */
719 private void move_left (Gdk.EventKey event) {
720 if (modality == Modality.NORMAL_VIEW) {
721 if (event.state == Gdk.ModifierType.SHIFT_MASK) {// Shift + Left
722 grid_view.go_to_previous ();
723 } else {
724 normal_move_focus (-1, 0);
725 }
726 } else if (modality == Modality.CATEGORY_VIEW) {
727 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Left
728 category_view.app_view.go_to_previous ();
729 else if (!search_entry.has_focus) {//the user has already selected an AppEntry
730 category_move_focus (-1, 0);
731 }
732 }
733 }
734
735 /*
736 * Moves the current view to the right (undependent of the TextDirection).
737 */
738 private void move_right (Gdk.EventKey event) {
739 if (modality == Modality.NORMAL_VIEW) {
740 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right
741 grid_view.go_to_next ();
742 else
743 normal_move_focus (+1, 0);
744 } else if (modality == Modality.CATEGORY_VIEW) {
745 if (event.state == Gdk.ModifierType.SHIFT_MASK) // Shift + Right
746 category_view.app_view.go_to_next ();
747 else if (search_entry.has_focus) // there's no AppEntry selected, the user is switching category
748 top_left_focus ();
749 else //the user has already selected an AppEntry
750 category_move_focus (+1, 0);
751 }
752 }
753
711 private void set_modality (Modality new_modality) {754 private void set_modality (Modality new_modality) {
712 modality = new_modality;755 modality = new_modality;
713756
@@ -780,23 +823,18 @@
780 }823 }
781824
782 public void populate_grid_view () {825 public void populate_grid_view () {
783
784 grid_view.clear ();826 grid_view.clear ();
785
786 foreach (Backend.App app in app_system.get_apps_by_name ()) {827 foreach (Backend.App app in app_system.get_apps_by_name ()) {
787828 var app_entry = new Widgets.AppEntry (app);
788 var app_entry = new Widgets.AppEntry (app, this);
789 app_entry.app_launched.connect (() => hide ());829 app_entry.app_launched.connect (() => hide ());
790 grid_view.append (app_entry);830 grid_view.append (app_entry);
791 app_entry.show_all ();831 app_entry.show_all ();
792 }832 }
793833
794
795 stack.set_visible_child_name ("normal");834 stack.set_visible_child_name ("normal");
796 }835 }
797836
798 private void read_settings (bool first_start = false, bool check_columns = true, bool check_rows = true) {837 private void read_settings (bool first_start = false, bool check_columns = true, bool check_rows = true) {
799
800 if (check_columns) {838 if (check_columns) {
801 if (Slingshot.settings.columns > 3)839 if (Slingshot.settings.columns > 3)
802 default_columns = Slingshot.settings.columns;840 default_columns = Slingshot.settings.columns;
@@ -819,33 +857,35 @@
819 category_view.app_view.resize (default_rows, default_columns);857 category_view.app_view.resize (default_rows, default_columns);
820 category_view.show_filtered_apps (category_view.category_ids.get (category_view.category_switcher.selected));858 category_view.show_filtered_apps (category_view.category_ids.get (category_view.category_switcher.selected));
821 }859 }
822
823 }860 }
824861
825 private void normal_move_focus (int delta_column, int delta_row) {862 private void normal_move_focus (int delta_column, int delta_row) {
826 if (get_focus () as Widgets.AppEntry != null) { // we check if any AppEntry has focus. If it does, we move863 if (get_focus () as Widgets.AppEntry != null) { // we check if any AppEntry has focus. If it does, we move
827 if (column_focus + delta_column < 0 || row_focus + delta_row < 0)864 if (column_focus + delta_column < 0 || row_focus + delta_row < 0)
828 return;865 return;
866
829 var new_focus = grid_view.get_child_at (column_focus + delta_column, row_focus + delta_row); // we check if the new widget exists867 var new_focus = grid_view.get_child_at (column_focus + delta_column, row_focus + delta_row); // we check if the new widget exists
830 if (new_focus == null) {868 if (new_focus == null) {
831 if (delta_column <= 0)869 if (delta_column <= 0)
832 return;870 return;
833 else {871 else {
834 new_focus = grid_view.get_child_at (column_focus + delta_column, 0);872 new_focus = grid_view.get_child_at (column_focus + delta_column, 0);
835 delta_row = -row_focus; // so it's 0 at the end
836 if (new_focus == null)873 if (new_focus == null)
837 return;874 return;
875
876 row_focus = -delta_row; // so it's 0 at the end
838 }877 }
839 }878 }
879
840 column_focus += delta_column;880 column_focus += delta_column;
841 row_focus += delta_row;881 row_focus += delta_row;
842 if (delta_column > 0 && column_focus % grid_view.get_page_columns () == 0 ) //check if we need to change page882 if (delta_column > 0 && column_focus % grid_view.get_page_columns () == 0 ) //check if we need to change page
843 grid_view.go_to_next ();883 grid_view.go_to_next ();
844 else if (delta_column < 0 && (column_focus + 1) % grid_view.get_page_columns () == 0) //check if we need to change page884 else if (delta_column < 0 && (column_focus + 1) % grid_view.get_page_columns () == 0) //check if we need to change page
845 grid_view.go_to_previous ();885 grid_view.go_to_previous ();
886
846 new_focus.grab_focus ();887 new_focus.grab_focus ();
847 }888 } else { // we move to the first app in the top left corner of the current page
848 else { // we move to the first app in the top left corner of the current page
849 column_focus = (grid_view.get_current_page ()-1) * grid_view.get_page_columns ();889 column_focus = (grid_view.get_current_page ()-1) * grid_view.get_page_columns ();
850 if (column_focus >= 0)890 if (column_focus >= 0)
851 grid_view.get_child_at (column_focus, 0).grab_focus ();891 grid_view.get_child_at (column_focus, 0).grab_focus ();
@@ -860,36 +900,34 @@
860 category_view.category_switcher.selected--;900 category_view.category_switcher.selected--;
861 top_left_focus ();901 top_left_focus ();
862 return;902 return;
863 }903 } else if (delta_row > 0 && category_view.category_switcher.selected != category_view.category_switcher.cat_size - 1) {
864 else if (delta_row > 0 && category_view.category_switcher.selected != category_view.category_switcher.cat_size - 1) {
865 category_view.category_switcher.selected++;904 category_view.category_switcher.selected++;
866 top_left_focus ();905 top_left_focus ();
867 return;906 return;
868 }907 } else if (delta_column > 0 && (category_column_focus + delta_column) % category_view.app_view.get_page_columns () == 0
869 else if (delta_column > 0 && (category_column_focus + delta_column) % category_view.app_view.get_page_columns () == 0
870 && category_view.app_view.get_current_page ()+ 1 != category_view.app_view.get_n_pages ()) {908 && category_view.app_view.get_current_page ()+ 1 != category_view.app_view.get_n_pages ()) {
871 category_view.app_view.go_to_next ();909 category_view.app_view.go_to_next ();
872 top_left_focus ();910 top_left_focus ();
873 return;911 return;
874 }912 } else if (category_column_focus == 0 && delta_column < 0) {
875 else if (category_column_focus == 0 && delta_column < 0) {
876 search_entry.grab_focus ();913 search_entry.grab_focus ();
877 category_column_focus = 0;914 category_column_focus = 0;
878 category_row_focus = 0;915 category_row_focus = 0;
879 return;916 return;
917 } else {
918 return;
880 }919 }
881 else
882 return;
883 }920 }
921
884 category_column_focus += delta_column;922 category_column_focus += delta_column;
885 category_row_focus += delta_row;923 category_row_focus += delta_row;
886 if (delta_column > 0 && category_column_focus % category_view.app_view.get_page_columns () == 0 ) { // check if we need to change page924 if (delta_column > 0 && category_column_focus % category_view.app_view.get_page_columns () == 0 ) { // check if we need to change page
887 category_view.app_view.go_to_next ();925 category_view.app_view.go_to_next ();
888 }926 } else if (delta_column < 0 && (category_column_focus + 1) % category_view.app_view.get_page_columns () == 0) {
889 else if (delta_column < 0 && (category_column_focus + 1) % category_view.app_view.get_page_columns () == 0) {
890 // check if we need to change page927 // check if we need to change page
891 category_view.app_view.go_to_previous ();928 category_view.app_view.go_to_previous ();
892 }929 }
930
893 new_focus.grab_focus ();931 new_focus.grab_focus ();
894 }932 }
895933
@@ -908,4 +946,4 @@
908 }946 }
909 }947 }
910948
911}
912\ No newline at end of file949\ No newline at end of file
950}
913951
=== modified file 'src/Widgets/AppEntry.vala'
--- src/Widgets/AppEntry.vala 2014-10-17 04:41:55 +0000
+++ src/Widgets/AppEntry.vala 2015-02-01 15:13:29 +0000
@@ -32,10 +32,9 @@
32 private bool dragging = false; //prevent launching32 private bool dragging = false; //prevent launching
3333
34 private Backend.App application;34 private Backend.App application;
35 private unowned SlingshotView view;35 private Gtk.Menu menu;
3636
37 public AppEntry (Backend.App app, SlingshotView view) {37 public AppEntry (Backend.App app) {
38 this.view = view;
39 Gtk.TargetEntry dnd = {"text/uri-list", 0, 0};38 Gtk.TargetEntry dnd = {"text/uri-list", 0, 0};
40 Gtk.drag_source_set (this, Gdk.ModifierType.BUTTON1_MASK, {dnd},39 Gtk.drag_source_set (this, Gdk.ModifierType.BUTTON1_MASK, {dnd},
41 Gdk.DragAction.COPY);40 Gdk.DragAction.COPY);
@@ -50,7 +49,7 @@
50 icon_size = Slingshot.settings.icon_size;49 icon_size = Slingshot.settings.icon_size;
51 icon = app.icon;50 icon = app.icon;
5251
53 get_style_context ().add_class ("app");52 get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
5453
55 app_label = new Gtk.Label (app_name);54 app_label = new Gtk.Label (app_name);
56 app_label.halign = Gtk.Align.CENTER;55 app_label.halign = Gtk.Align.CENTER;
@@ -75,11 +74,19 @@
75 add (grid);74 add (grid);
76 set_size_request (Pixels.ITEM_SIZE, Pixels.ITEM_SIZE);75 set_size_request (Pixels.ITEM_SIZE, Pixels.ITEM_SIZE);
7776
77 menu = new Gtk.Menu ();
78 create_menu ();
79
78 this.clicked.connect (launch_app);80 this.clicked.connect (launch_app);
81 // Showing a menu reverts the effect of the grab_device function.
82 menu.hide.connect (() => {
83 var slingshot_app = (Gtk.Application) GLib.Application.get_default ();
84 ((SlingshotView)slingshot_app.active_window).grab_device ();
85 });
7986
80 this.button_release_event.connect ((e) => {87 this.button_press_event.connect ((e) => {
81 if (e.button == Gdk.BUTTON_SECONDARY) {88 if (e.button == Gdk.BUTTON_SECONDARY && menu.get_children ().length () > 0) {
82 show_menu ();89 menu.popup (null, null, null, e.button, e.time);
83 return true;90 return true;
84 }91 }
85 return false;92 return false;
@@ -120,7 +127,7 @@
120 app_launched ();127 app_launched ();
121 }128 }
122129
123 private void show_menu () {130 private void create_menu () {
124 // Display the apps static quicklist items in a popover menu131 // Display the apps static quicklist items in a popover menu
125 if (application.actions == null) {132 if (application.actions == null) {
126 try {133 try {
@@ -130,24 +137,13 @@
130 }137 }
131 }138 }
132139
133 var menu = new PopoverMenu ();
134 foreach (var action in application.actions) {140 foreach (var action in application.actions) {
135 var values = application.actions_map.get (action).split (";;");141 var menuitem = new Gtk.MenuItem.with_label (action);
136 Gdk.Pixbuf? icon = null;142 menu.add (menuitem);
137 var flags = Gtk.IconLookupFlags.FORCE_SIZE;143
138144 menuitem.activate.connect (() => {
139 try {
140 if (values.length > 1 && values[1] != "" && values[1] != null)
141 icon = Slingshot.icon_theme.load_icon (values[1], 16, flags);
142 } catch (Error e) {
143 error ("Error loading quicklist icon");
144 }
145
146 var menuitem = new Widgets.PopoverMenuItem (action, icon);
147 menu.add_menu_item (menuitem);
148
149 menuitem.activated.connect (() => {
150 try {145 try {
146 var values = application.actions_map.get (action).split (";;");
151 AppInfo.create_from_commandline (values[0], null, AppInfoCreateFlags.NONE).launch (null, null);147 AppInfo.create_from_commandline (values[0], null, AppInfoCreateFlags.NONE).launch (null, null);
152 app_launched ();148 app_launched ();
153 } catch (Error e) {149 } catch (Error e) {
@@ -155,9 +151,7 @@
155 }151 }
156 });152 });
157 }153 }
158154 menu.show_all ();
159 if (menu.get_size () > 0)
160 view.show_popover_menu (menu, this);
161 }155 }
162156
163}
164\ No newline at end of file157\ No newline at end of file
158}
165159
=== modified file 'src/Widgets/CategoryView.vala'
--- src/Widgets/CategoryView.vala 2014-10-27 19:01:28 +0000
+++ src/Widgets/CategoryView.vala 2015-02-01 15:13:29 +0000
@@ -43,10 +43,8 @@
43 separator = new Gtk.Separator (Gtk.Orientation.VERTICAL);43 separator = new Gtk.Separator (Gtk.Orientation.VERTICAL);
4444
45 category_switcher = new Sidebar ();45 category_switcher = new Sidebar ();
46 category_switcher.can_focus = false;
4746
48 app_view = new Widgets.Grid (view.rows, view.columns - 1);47 app_view = new Widgets.Grid (view.rows, view.columns - 1);
49 app_view.margin_start = Pixels.SIDEBAR_GRID_PADDING;
5048
51 container.add (category_switcher);49 container.add (category_switcher);
52 container.add (separator);50 container.add (separator);
@@ -97,7 +95,7 @@
97 }95 }
9896
99 private void add_app (Backend.App app) {97 private void add_app (Backend.App app) {
100 var app_entry = new AppEntry (app, view);98 var app_entry = new AppEntry (app);
101 app_entry.app_launched.connect (() => view.hide ());99 app_entry.app_launched.connect (() => view.hide ());
102 app_view.append (app_entry);100 app_view.append (app_entry);
103 app_view.show_all ();101 app_view.show_all ();
@@ -114,4 +112,4 @@
114112
115 }113 }
116114
117}
118\ No newline at end of file115\ No newline at end of file
116}
119117
=== modified file 'src/Widgets/Grid.vala'
--- src/Widgets/Grid.vala 2014-10-15 21:57:37 +0000
+++ src/Widgets/Grid.vala 2015-02-01 15:13:29 +0000
@@ -34,16 +34,17 @@
3434
35 private uint current_row = 0;35 private uint current_row = 0;
36 private uint current_col = 0;36 private uint current_col = 0;
37
37 private Page page;38 private Page page;
3839
39 public Grid (int rows, int columns) {40 public Grid (int rows, int columns) {
40 margin_start = 12;
41 margin_end = 12;
42 page.rows = rows;41 page.rows = rows;
43 page.columns = columns;42 page.columns = columns;
44 page.number = 1;43 page.number = 1;
45 var main_grid = new Gtk.Grid ();44 var main_grid = new Gtk.Grid ();
46 main_grid.orientation = Gtk.Orientation.VERTICAL;45 main_grid.orientation = Gtk.Orientation.VERTICAL;
46 main_grid.row_spacing = 6;
47 main_grid.margin_bottom = 12;
47 stack = new Gtk.Stack ();48 stack = new Gtk.Stack ();
48 stack.expand = true;49 stack.expand = true;
49 stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;50 stack.transition_type = Gtk.StackTransitionType.SLIDE_LEFT_RIGHT;
@@ -61,13 +62,15 @@
61 create_new_grid ();62 create_new_grid ();
62 go_to_number (1);63 go_to_number (1);
63 }64 }
64 65
65 private void create_new_grid () {66 private void create_new_grid () {
66 // Grid properties67 // Grid properties
67 current_grid = new Gtk.Grid ();68 current_grid = new Gtk.Grid ();
68 current_grid.expand = true;69 current_grid.expand = true;
69 current_grid.row_homogeneous = true;70 current_grid.row_homogeneous = true;
70 current_grid.column_homogeneous = true;71 current_grid.column_homogeneous = true;
72 current_grid.margin_start = 12;
73 current_grid.margin_end = 12;
7174
72 current_grid.row_spacing = Pixels.ROW_SPACING;75 current_grid.row_spacing = Pixels.ROW_SPACING;
73 current_grid.column_spacing = 0;76 current_grid.column_spacing = 0;
@@ -99,25 +102,16 @@
99 }102 }
100 }103 }
101104
102 public override void get_preferred_width (out int minimum_width, out int natural_width) {
103 minimum_width = (int)page.columns * Pixels.ITEM_SIZE;
104 natural_width = minimum_width;
105 }
106
107 public override void get_preferred_height (out int minimum_height, out int natural_height) {
108 minimum_height = (int)page.rows * Pixels.ITEM_SIZE + ((int)page.rows - 1) * Pixels.ROW_SPACING;
109 natural_height = minimum_height;
110 }
111
112 public void clear () {105 public void clear () {
113 foreach (Gtk.Grid grid in grids.values) {106 foreach (Gtk.Grid grid in grids.values) {
114 foreach (Gtk.Widget widget in grid.get_children ()) {107 foreach (Gtk.Widget widget in grid.get_children ()) {
115 widget.destroy ();108 widget.destroy ();
116 }109 }
110
117 grid.destroy ();111 grid.destroy ();
118 }112 }
113
119 grids.clear ();114 grids.clear ();
120
121 current_row = 0;115 current_row = 0;
122 current_col = 0;116 current_col = 0;
123 page.number = 1;117 page.number = 1;
@@ -125,11 +119,15 @@
125 stack.set_visible_child (current_grid);119 stack.set_visible_child (current_grid);
126 }120 }
127121
128 public Gtk.Widget get_child_at (int column, int row) {122 public Gtk.Widget? get_child_at (int column, int row) {
129 var col = ((int)(column/page.columns))+1;123 var col = ((int)(column/page.columns))+1;
130 124
131 var grid = grids.get (col);125 var grid = grids.get (col);
132 return grid.get_child_at (column - (int)page.columns*(col-1), row);126 if (grid != null) {
127 return grid.get_child_at (column - (int)page.columns*(col-1), row) as Widgets.AppEntry;
128 } else {
129 return null;
130 }
133 }131 }
134132
135 public int get_page_columns () {133 public int get_page_columns () {
@@ -152,7 +150,7 @@
152 int page_number = get_current_page ()+1;150 int page_number = get_current_page ()+1;
153 if (page_number <= get_n_pages ())151 if (page_number <= get_n_pages ())
154 stack.set_visible_child_name (page_number.to_string ());152 stack.set_visible_child_name (page_number.to_string ());
155 153
156 page_switcher.update_selected ();154 page_switcher.update_selected ();
157 }155 }
158156
@@ -160,7 +158,7 @@
160 int page_number = get_current_page ()-1;158 int page_number = get_current_page ()-1;
161 if (page_number > 0)159 if (page_number > 0)
162 stack.set_visible_child_name (page_number.to_string ());160 stack.set_visible_child_name (page_number.to_string ());
163 161
164 page_switcher.update_selected ();162 page_switcher.update_selected ();
165 }163 }
166164
@@ -181,4 +179,4 @@
181 page.number = 1;179 page.number = 1;
182 }180 }
183 }181 }
184}
185\ No newline at end of file182\ No newline at end of file
183}
186184
=== removed file 'src/Widgets/PopoverMenu.vala'
--- src/Widgets/PopoverMenu.vala 2014-10-18 01:57:49 +0000
+++ src/Widgets/PopoverMenu.vala 1970-01-01 00:00:00 +0000
@@ -1,188 +0,0 @@
1// -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-
2//
3// Copyright (C) 2011-2012 Giulio Collura
4// Copyright (C) 2014 Maddie May <madelynn@madelynnmay.com>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18//
19
20// A menu to be used inside of popovers for when a normal context
21// menu can't be used
22namespace Slingshot.Widgets {
23
24public class PopoverMenu : Gtk.Grid {
25 private int line_count = 0;
26 private Gee.ArrayList<PopoverMenuItem> items = new Gee.ArrayList<PopoverMenuItem> ();
27
28 public PopoverMenu () {
29 row_homogeneous = true;
30 column_homogeneous = true;
31 }
32
33 public void add_menu_item (PopoverMenuItem item) {
34 line_count++;
35 this.items.add (item);
36 this.attach (item.child, 0, line_count, 1 , 1);
37 }
38
39 public int get_size () {
40 return items.size;
41 }
42
43 public override void show () {
44 base.show ();
45 bool has_image = false;
46 foreach (PopoverMenuItem item in items) {
47 if (item.image != null)
48 has_image = true;
49 }
50
51 if (!has_image) {
52 foreach (PopoverMenuItem item in items) {
53 item.label_widget.margin_left = item.label_widget.margin_right = 8;
54 item.space_box.hide ();
55 }
56 }
57 }
58}
59
60public class PopoverMenuItem : Object {
61 public Gtk.Widget child = null;
62 public signal void activated ();
63 public Gtk.Image? image;
64 public Gtk.Box? space_box;
65 public Gtk.Label label_widget;
66
67 public PopoverMenuItem (string label, Gdk.Pixbuf? icon) {
68 var button = new Gtk.Button ();
69 button.get_style_context ().add_class (Gtk.STYLE_CLASS_MENUITEM);
70
71 var grid = new Gtk.Grid ();
72 if (icon != null) {
73 image = new Gtk.Image.from_pixbuf (icon);
74 image.margin_left = 2;
75 image.halign = Gtk.Align.START;
76 grid.attach (image, 0, 0, 1, 1);
77 } else {
78 space_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
79 space_box.set_size_request (24, 16);
80 grid.attach (space_box, 0, 0, 1, 1);
81 }
82
83 label_widget = new Gtk.Label.with_mnemonic (label);
84 label_widget.margin_left = 2;
85 label_widget.margin_right = 16;
86 label_widget.justify = Gtk.Justification.LEFT;
87 label_widget.set_alignment (0, 0);
88 grid.attach (label_widget, 1, 0, 1, 1);
89
90 button.add (grid);
91 button.relief = Gtk.ReliefStyle.NONE;
92 button.clicked.connect (on_activate);
93 child = button;
94 }
95
96 private void on_activate () {
97 activated ();
98 }
99}
100
101// A popover that doesn't grab focus
102public class NofocusPopover : Gtk.Popover {
103 private Gtk.Container parent_container;
104 private unowned SlingshotView view;
105
106 private const string POPOVER_STYLESHEET = """
107 .popover,
108 .popover.osd,
109 GtkPopover {
110 border-radius: 0px;
111 margin: 0px;
112 text-shadow: none;
113 }
114 """;
115
116 public NofocusPopover (SlingshotView view, Gtk.Container parent) {
117 this.view = view;
118 this.parent_container = parent;
119 connect_popover_signals (parent);
120 modal = false;
121 parent.button_release_event.connect (hide_popover_menu);
122 parent.button_press_event.connect (hide_popover_menu);
123 get_style_context ().add_class (Gtk.STYLE_CLASS_MENU);
124 Granite.Widgets.Utils.set_theming_for_screen (get_screen (), POPOVER_STYLESHEET,
125 Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
126 }
127
128 public void connect_popover_signals (Gtk.Container parent) {
129 foreach (Gtk.Widget child in parent.get_children ()) {
130 if (child is Gtk.Container) {
131 Gtk.Container container = child as Gtk.Container;
132 connect_popover_signals (container);
133 }
134
135 if (child is Widgets.Switcher) {
136 var switcher = child as Widgets.Switcher;
137 switcher.on_stack_changed.connect (switched);
138 }
139
140 child.button_release_event.connect (hide_popover_menu);
141 child.button_press_event.connect (hide_popover_menu);
142 }
143 }
144
145 private void disconnect_popover_signals (Gtk.Container parent) {
146 foreach (Gtk.Widget child in parent.get_children ()) {
147 if (child is Gtk.Container) {
148 Gtk.Container container = child as Gtk.Container;
149 disconnect_popover_signals (container);
150 }
151
152 if (child is Widgets.Switcher) {
153 var switcher = child as Widgets.Switcher;
154 switcher.on_stack_changed.disconnect (switched);
155 }
156
157 child.button_release_event.disconnect (hide_popover_menu);
158 child.button_press_event.disconnect (hide_popover_menu);
159 }
160 }
161
162 public void switched () {
163 this.hide ();
164 }
165
166 public bool hide_popover_menu (Gdk.EventButton event) {
167 if (this.visible) {
168 view.set_focus (null);
169 view.search_entry.grab_focus ();
170
171 this.hide ();
172 // Block here to replicate context menu behavior
173 return true;
174 }
175 // Visible can be false but the popover still thinks it's up
176 // and will show when it's view is switched back to
177 // in that case don't block forwarding but make sure it is
178 // really hidden
179 this.hide ();
180 return false;
181 }
182
183 ~NofocusPopover () {
184 disconnect_popover_signals (parent_container);
185 }
186}
187
188} // End namespace
189\ No newline at end of file0\ No newline at end of file
1901
=== modified file 'src/Widgets/SearchItem.vala'
--- src/Widgets/SearchItem.vala 2014-11-08 05:40:53 +0000
+++ src/Widgets/SearchItem.vala 2015-02-01 15:13:29 +0000
@@ -35,7 +35,7 @@
35 public SearchItem (Backend.App app, string search_term = "") {35 public SearchItem (Backend.App app, string search_term = "") {
36 Object (app: app);36 Object (app: app);
37 37
38 get_style_context ().add_class ("app");38 get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
3939
40 var markup = Backend.SynapseSearch.markup_string_with_search (app.name, search_term);40 var markup = Backend.SynapseSearch.markup_string_with_search (app.name, search_term);
4141
@@ -97,4 +97,4 @@
97 }97 }
98 }98 }
9999
100}
101\ No newline at end of file100\ No newline at end of file
101}
102102
=== modified file 'src/Widgets/SearchView.vala'
--- src/Widgets/SearchView.vala 2014-11-08 05:40:53 +0000
+++ src/Widgets/SearchView.vala 2015-02-01 15:13:29 +0000
@@ -19,8 +19,6 @@
19namespace Slingshot.Widgets {19namespace Slingshot.Widgets {
2020
21 public class SearchView : Gtk.ScrolledWindow {21 public class SearchView : Gtk.ScrolledWindow {
22 const int CONTEXT_WIDTH = 200;
23 const int CONTEXT_ARROW_SIZE = 12;
24 const int MAX_RESULTS = 20;22 const int MAX_RESULTS = 20;
25 const int MAX_RESULTS_BEFORE_LIMIT = 10;23 const int MAX_RESULTS_BEFORE_LIMIT = 10;
2624
@@ -32,8 +30,6 @@
32 private SearchItem selected_app = null;30 private SearchItem selected_app = null;
33 private Gtk.Box main_box;31 private Gtk.Box main_box;
3432
35 private Gtk.Revealer revealer;
36 private Gtk.EventBox context;
37 private Gtk.Box context_box;33 private Gtk.Box context_box;
38 private Gtk.Fixed context_fixed;34 private Gtk.Fixed context_fixed;
39 private int context_selected_y;35 private int context_selected_y;
@@ -87,30 +83,20 @@
8783
88 public SearchView (SlingshotView parent) {84 public SearchView (SlingshotView parent) {
89 view = parent;85 view = parent;
9086 hscrollbar_policy = Gtk.PolicyType.NEVER;
91 items = new Gee.HashMap<Backend.App, SearchItem> ();87 items = new Gee.HashMap<Backend.App, SearchItem> ();
9288
93 main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);89 main_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
94 main_box.margin_start = 12;90 main_box.margin_start = 12;
95 main_box.margin_end = 12;
9691
97 context_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);92 context_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
98 context_fixed = new Gtk.Fixed ();93 context_fixed = new Gtk.Fixed ();
99 context_fixed.margin_start = CONTEXT_ARROW_SIZE;94 context_fixed.margin_start = 12;
100 context_fixed.put (context_box, 0, 0);95 context_fixed.put (context_box, 0, 0);
101 context = new Gtk.EventBox ();
102 context.draw.connect (draw_context);
103 context.add (context_fixed);
104
105 revealer = new Gtk.Revealer ();
106 revealer.transition_duration = 400;
107 revealer.transition_type = Gtk.RevealerTransitionType.CROSSFADE;
108 revealer.no_show_all = true;
109 revealer.add (context);
11096
111 var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);97 var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
112 box.pack_start (main_box, true);98 box.pack_start (main_box, true);
113 box.pack_start (revealer, false);99 box.pack_start (context_fixed, false);
114100
115 add_with_viewport (box);101 add_with_viewport (box);
116 }102 }
@@ -189,7 +175,7 @@
189 header.margin_start = 8;175 header.margin_start = 8;
190 header.margin_bottom = 4;176 header.margin_bottom = 4;
191 header.use_markup = true;177 header.use_markup = true;
192 header.get_style_context ().add_class ("category-label");178 header.get_style_context ().add_class ("h4");
193 header.show ();179 header.show ();
194 main_box.pack_start (header, false);180 main_box.pack_start (header, false);
195181
@@ -252,10 +238,7 @@
252 app.start_search.connect ((search, target) => start_search (search, target));238 app.start_search.connect ((search, target) => start_search (search, target));
253 context_box.pack_start (new SearchItem (app));239 context_box.pack_start (new SearchItem (app));
254 }240 }
255 context.show_all ();241 context_box.show_all ();
256
257 revealer.show ();
258 revealer.set_reveal_child (true);
259242
260 Gtk.Allocation alloc;243 Gtk.Allocation alloc;
261 selected_app.get_allocation (out alloc);244 selected_app.get_allocation (out alloc);
@@ -267,9 +250,6 @@
267 } else {250 } else {
268 in_context_view = false;251 in_context_view = false;
269252
270 revealer.set_reveal_child (false);
271 revealer.hide ();
272
273 // trigger update of selection253 // trigger update of selection
274 selected = selected;254 selected = selected;
275 }255 }
@@ -332,19 +312,6 @@
332 return null;312 return null;
333 }313 }
334314
335 private bool draw_context (Cairo.Context cr) {
336 cr.rectangle (CONTEXT_ARROW_SIZE, 0, context.get_allocated_width (), context.get_allocated_height ());
337
338 cr.move_to (CONTEXT_ARROW_SIZE, context_selected_y + 6);
339 cr.rel_line_to (-CONTEXT_ARROW_SIZE, 12);
340 cr.rel_line_to (CONTEXT_ARROW_SIZE, 12);
341 cr.close_path ();
342
343 cr.set_source_rgb (0.85, 0.85, 0.85);
344 cr.fill ();
345 return false;
346 }
347
348 /**315 /**
349 * Launch selected app316 * Launch selected app
350 *317 *
@@ -358,4 +325,4 @@
358325
359 }326 }
360327
361}
362\ No newline at end of file328\ No newline at end of file
329}

Subscribers

People subscribed via source and target branches