Merge lp:~parnold-x/slingshot/recent-apps into lp:~elementary-pantheon/slingshot/trunk

Proposed by Djax on 2014-10-05
Status: Work in progress
Proposed branch: lp:~parnold-x/slingshot/recent-apps
Merge into: lp:~elementary-pantheon/slingshot/trunk
Diff against target: 630 lines (+279/-33)
10 files modified
lib/synapse-core/desktop-file-service.vala (+3/-0)
src/Backend/App.vala (+13/-2)
src/Backend/AppSystem.vala (+32/-6)
src/Backend/RelevancyService.vala (+17/-0)
src/SlingshotView.vala (+28/-3)
src/Widgets/CategoryView.vala (+70/-11)
src/Widgets/Grid.vala (+67/-6)
src/Widgets/SearchView.vala (+3/-3)
src/Widgets/Sidebar.vala (+1/-1)
src/Widgets/Switcher.vala (+45/-1)
To merge this branch: bzr merge lp:~parnold-x/slingshot/recent-apps
Reviewer Review Type Date Requested Status
Cody Garver 2015-09-01 Resubmit on 2016-02-23
Daniel Fore 2014-10-05 Approve on 2015-09-01
Sam Hewitt (community) ux 2014-10-05 Approve on 2014-10-05
Review via email: mp+237186@code.launchpad.net

Description of the change

https://bugs.launchpad.net/slingshot/+bug/1375069
Add a page for most recently used applications. The page only shows up when data is available.
To also show hidden apps, etc. I used Synapse as DataSource. (By the way there are a couple of classes in synapse and slingshot that have basically the same functionality...)
If this is not wanted then we can also use the standard GMenu.Tree as source, but then we can only show apps that are also grouped in the categories in the recent used page...

To post a comment you must log in.
Sam Hewitt (snwh) wrote :

All well and good, but perhaps instead of referring to "face-cool" refer to "document-recent-symbolic" which would be the appropriate icon –the hourglass is a from a non-default theme. :)

Sam Hewitt (snwh) wrote :

Correction: document-open-recent-symbolic

Djax (parnold-x) wrote :

I thought "face-cool" is a good placeholder till someone tells me what icon I should use :)
Changed to document-open-recent-symbolic

Daniel Fore (danrabbit) wrote :

Can we have a tooltip for the tab button? Something like "Recently used apps"

Sam Hewitt (snwh) wrote :

Looks good to me!

review: Approve (ux)
lp:~parnold-x/slingshot/recent-apps updated on 2014-10-15
457. By Cody Garver on 2014-10-05

No longer whitelist ibus-setup.desktop. It's bloody frightful. Whatever feature is needed from here should be added to lp:switchboard-plug-keyboard or something.

458. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-12

Launchpad automatic translations update.

459. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-13

Launchpad automatic translations update.

460. By Daniel Fore on 2014-10-14

no ellipsis

461. By Corentin Noël on 2014-10-15

* Get a consistent search entry.
 * Do search asynchronously.
 * Animate the view change with recent Gtk technology.
 * Simplify the code regarding the addition of margins.

462. By Corentin Noël on 2014-10-15

Fixes RTL positionning

463. By Corentin Noël on 2014-10-15

Switch margin_left and margin_right to margin_start and margin_end.

464. By Corentin Noël on 2014-10-15

Updated translation template.

Daniel Fore (danrabbit) wrote :

Hm I get a Gtk-Critical with this branch that I don't get from trunk:

[23:25:52.955918 Gtk-Critical] gtk_container_remove: assertion 'GTK_IS_WIDGET (widget)' failed
[23:25:52.959185 Gtk-Critical] gtk_container_remove: assertion 'GTK_IS_WIDGET (widget)' failed

Cassidy James Blaede (cassidyjames) wrote :

I feel like I should be able to scroll to the recents view; I can scroll away from it and as of now I can only get there by clicking the little icon. :P

Cassidy James Blaede (cassidyjames) wrote :

Cody Garver had a genius thought: Could we make it a new view, switchable with the view switcher (View as Icons, View in Categories, View Recent)?

Cassidy James Blaede (cassidyjames) wrote :

Also something I've noticed while using: it doesn't seem to add new apps right away (when they're launched). How often does it add apps to the Recent view?

Cassidy James Blaede (cassidyjames) wrote :

And one last (related) item: Clearing usage data from the Security & Privacy plug does not clear the recent view, which I feel like it should. I'm not completely sure how that works. :P

lp:~parnold-x/slingshot/recent-apps updated on 2014-10-16
465. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-16

Launchpad automatic translations update.

Djax (parnold-x) wrote :

@danrabbit
fixed
@cassidyjames
scroll should be fixed (no scroll mouse here)

It adds recent apps here without any problem. But I just noticed zeitgeist only updates the most recent apps if the toggle in the privacy plug called in german "data privacy" is on???

I still get data from zeitgeist after clearing with the plug, so this is another issue. But the data is sometimes shortly kind of corrupted and then reappears?!

I will make another branch with the view switcher idea to compare.

Djax (parnold-x) wrote :

Mhh, also noticed that searched apps don't update the relevancyservice from slingshot. Any thought how this should be solved? Best way would be perhaps to switch everything to the slingshot backend but this is propably a isis+1 thing.
Otherwise it will be kind of a hack I think.

Djax (parnold-x) wrote :

And here a branch with the recent apps as view switcher.
Just quick n dirty as prototype so the switcher will show always and so on.
https://code.launchpad.net/~parnold-x/+junk/slingshot-recent-apps-view-switcher

Djax (parnold-x) wrote :

added recent update for searched apps but it is a bit of a hack. If anyone knows a better approach...

lp:~parnold-x/slingshot/recent-apps updated on 2014-10-16
466. By Corentin Noël on 2014-10-16

Adapt to category bar size.

Cody Garver (codygarver) wrote :

The recent apps view switcher branch does not compile

SlingshotView.vala: error: The name `scrolled_normal' does not exist in the context of `Slingshot.SlingshotView.setup_ui'

lp:~parnold-x/slingshot/recent-apps updated on 2014-10-17
467. By meese on 2014-10-17

adds a popover context menu used for showing quicklist items on right click (lp:1294917)

468. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-17

Launchpad automatic translations update.

Djax (parnold-x) wrote :

@codygarver
Strange. Compiles just fine here with vala 0.24.

Cody Garver (codygarver) wrote :

Djax, it happens when you merge the code with trunk e.g.

bzr branch lp:slingshot s

cd s

bzr merge lp:~parnold-x/+junk/slingshot-recent-apps-view-switcher

# compile and run

Daniel Fore (danrabbit) wrote :

I don't think I like the view switcher solution. With the other two buttons, you're viewing the same data but in a different format. With the history view, you're viewing totally different data. It feels weird to me.

lp:~parnold-x/slingshot/recent-apps updated on 2015-02-24
469. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-19

Launchpad automatic translations update.

470. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-20

Launchpad automatic translations update.

471. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-22

Launchpad automatic translations update.

472. By meese on 2014-10-23

fix quicklist icons showing up when they are not supposed to

473. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-24

Launchpad automatic translations update.

474. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-25

Launchpad automatic translations update.

475. By Launchpad Translations on behalf of elementary-pantheon on 2014-10-28

Launchpad automatic translations update.

476. By Corentin Noël on 2014-10-28

Fixed regression triggered by rev 466, now the category view has always an item selected

477. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-04

Launchpad automatic translations update.

478. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-05

Launchpad automatic translations update.

479. By Djax on 2014-11-08

Support dragging apps in search view (lp:1008352)

480. By Corentin Noël on 2014-11-09

Simplify and fix layout size detection

481. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-12

Launchpad automatic translations update.

482. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-13

Launchpad automatic translations update.

483. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-14

Launchpad automatic translations update.

484. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-25

Launchpad automatic translations update.

485. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-26

Launchpad automatic translations update.

486. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-28

Launchpad automatic translations update.

487. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-29

Launchpad automatic translations update.

488. By Launchpad Translations on behalf of elementary-pantheon on 2014-11-30

Launchpad automatic translations update.

489. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-01

Launchpad automatic translations update.

490. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-06

Launchpad automatic translations update.

491. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-08

Launchpad automatic translations update.

492. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-12

Launchpad automatic translations update.

493. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-13

Launchpad automatic translations update.

494. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-23

Launchpad automatic translations update.

495. By Launchpad Translations on behalf of elementary-pantheon on 2014-12-24

Launchpad automatic translations update.

496. By Cody Garver on 2014-12-29

Blacklist htop.desktop

497. By Launchpad Translations on behalf of elementary-pantheon on 2015-01-05

Launchpad automatic translations update.

498. By Launchpad Translations on behalf of elementary-pantheon on 2015-01-09

Launchpad automatic translations update.

499. By Launchpad Translations on behalf of elementary-pantheon on 2015-01-10

Launchpad automatic translations update.

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

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)

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

Fixed grab loss after Drag'n'Drop.

502. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-03

Launchpad automatic translations update.

503. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-10

Launchpad automatic translations update.

504. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-12

Launchpad automatic translations update.

505. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-17

Launchpad automatic translations update.

506. By Rico Tzschichholz on 2015-02-17

appentry: Use one Gtk.Menu which gets created on demand

507. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-19

Launchpad automatic translations update.

508. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-20

Launchpad automatic translations update.

509. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-23

Launchpad automatic translations update.

510. By Launchpad Translations on behalf of elementary-pantheon on 2015-02-24

Launchpad automatic translations update.

Daniel Fore (danrabbit) wrote :

Needs trunk merged.

I still feel this view should be in a list. Grid view doesn't make sense to me for something that's supposed to be in chronological order.

review: Needs Fixing
Djax (parnold-x) wrote :

Merged the trunk and switched to list view. Search View style.
Unfortunatly no up/down keyboard support. I think to enable this a lot of changes are needed.

Daniel Fore (danrabbit) wrote :

Hmm seems we have a small problem. Vertical scrolling will eventually switch pages. Any way we can stop that from happening for this recent page? If not maybe we should revert to being a grid view for now then.

I also feel like we should add "Recent" as a category in category view so that you can access this in both views.

Djax (parnold-x) wrote :

Ok, now that I have a normal scroll mouse I also noticed this. With my Trackpoint it scrolls just fine the focused widgets. I enable the scrolling.
To also scroll away from the recent apps list it scrolls the page switche if the bottom is reached. But I am not sure if this is good. What do you think?
We could also restrict to 9 entries so that no scrolling is needed.
The "Recent" category as first entry, last or in alphabetic order?
Also as a list view or the normal grid?

Daniel Fore (danrabbit) wrote :

> To also scroll away from the recent apps list it scrolls the page switcher if the bottom is reached. But I am not sure if this is good. What do you think?

Yep that's what I was saying that I don't think is good behavior. This shouldn't happen.

We should probably have the "Recent" category as first as it's first in the grid view

Djax (parnold-x) wrote :

Yeah, I changed it to the Recent list view scrolls till the bottom and then snaps there for a moment and then when you scroll futher it scrolls away. Ok?
As list view in the category section?

lp:~parnold-x/slingshot/recent-apps updated on 2015-03-10
511. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-03

Launchpad automatic translations update.

512. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-05

Launchpad automatic translations update.

513. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-10

Launchpad automatic translations update.

Djax (parnold-x) wrote :

Could you review again?

lp:~parnold-x/slingshot/recent-apps updated on 2015-09-01
514. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-21

Launchpad automatic translations update.

515. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-22

Launchpad automatic translations update.

516. By Viko Adi Rahmawan on 2015-03-24

* clear state flags before turning PRELIGHT on
* dont clear() on every category changes

517. By Launchpad Translations on behalf of elementary-pantheon on 2015-03-25

Launchpad automatic translations update.

518. By Launchpad Translations on behalf of elementary-pantheon on 2015-04-06

Launchpad automatic translations update.

519. By Cody Garver on 2015-04-06

Release 0.8

520. By Launchpad Translations on behalf of elementary-pantheon on 2015-04-09

Launchpad automatic translations update.

521. By Launchpad Translations on behalf of elementary-pantheon on 2015-04-25

Launchpad automatic translations update.

522. By Launchpad Translations on behalf of elementary-pantheon on 2015-04-29

Launchpad automatic translations update.

523. By Launchpad Translations on behalf of elementary-pantheon on 2015-04-30

Launchpad automatic translations update.

524. By Rory on 2015-05-08

appentry: Add 'Add to/Remove from Dock' menuitem using Plank DBusManager

525. By Cody Garver on 2015-05-08

Updated translation template

526. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-09

Launchpad automatic translations update.

527. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-10

Launchpad automatic translations update.

528. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-14

Launchpad automatic translations update.

529. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-17

Launchpad automatic translations update.

530. By Cody Garver on 2015-05-17

Bump required Gtk version to 3.12

531. By Cody Garver on 2015-05-17

Updated INSTALL dependency list

532. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-18

Launchpad automatic translations update.

533. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-19

Launchpad automatic translations update.

534. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-26

Launchpad automatic translations update.

535. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-27

Launchpad automatic translations update.

536. By Rico Tzschichholz on 2015-05-28

Adapt to gtk+ binding change of Gtk.Label to fix build with valac >= 0.28

537. By Djax on 2015-05-29

Reset search highlight to first result when search entry is empty (lp:1455991)

538. By kay van der Zander on 2015-05-29

desktop-files-plugin: fallback to possible matches if available (lp:1029612)

When user types srcatch it will still show scratch

539. By Djax on 2015-05-29

Add session actions plugin (lp:1380794)

540. By Cody Garver on 2015-05-29

Updated translation template

541. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-29

Launchpad automatic translations update.

542. By Launchpad Translations on behalf of elementary-pantheon on 2015-05-30

Launchpad automatic translations update.

543. By Cody Garver on 2015-05-30

Release 0.8.1

544. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-01

Launchpad automatic translations update.

545. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-02

Launchpad automatic translations update.

546. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-05

Launchpad automatic translations update.

547. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-06

Launchpad automatic translations update.

548. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-07

Launchpad automatic translations update.

549. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-08

Launchpad automatic translations update.

550. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-09

Launchpad automatic translations update.

551. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-10

Launchpad automatic translations update.

552. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-14

Launchpad automatic translations update.

553. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-19

Launchpad automatic translations update.

554. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-24

Launchpad automatic translations update.

555. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-25

Launchpad automatic translations update.

556. By Launchpad Translations on behalf of elementary-pantheon on 2015-06-26

Launchpad automatic translations update.

557. By Launchpad Translations on behalf of elementary-pantheon on 2015-07-06

Launchpad automatic translations update.

558. By Launchpad Translations on behalf of elementary-pantheon on 2015-07-13

Launchpad automatic translations update.

559. By Launchpad Translations on behalf of elementary-pantheon on 2015-07-28

Launchpad automatic translations update.

560. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-07

Launchpad automatic translations update.

561. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-09

Launchpad automatic translations update.

562. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-14

Launchpad automatic translations update.

563. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-20

Launchpad automatic translations update.

564. By Cody Garver on 2015-08-20

Release 0.8.1.1

565. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-28

Launchpad automatic translations update.

566. By Launchpad Translations on behalf of elementary-pantheon on 2015-08-30

Launchpad automatic translations update.

567. By Djax on 2015-09-01

add recent apps category

Daniel Fore (danrabbit) wrote :

Looks good to me :) Just needs code review

review: Approve
Daniel Fore (danrabbit) wrote :

Looks good to me :) Just needs code review

review: Approve
Rico Tzschichholz (ricotz) wrote :

*Reuse* results aka cache results in local *properly typed* fields to avoid refs/copies.

E.g. "Synapse.DesktopFileService.get_default ()" and "Synapse.DesktopFileService.get_default ().get_all_desktop_files ()"

lp:~parnold-x/slingshot/recent-apps updated on 2015-09-02
568. By Djax on 2015-09-02

cache result in local properties and codestyle

Cody Garver (codygarver) wrote :

Needs to be re-based on newer slingshot

review: Resubmit

Unmerged revisions

568. By Djax on 2015-09-02

cache result in local properties and codestyle

567. By Djax on 2015-09-01

add recent apps category

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/synapse-core/desktop-file-service.vala'
2--- lib/synapse-core/desktop-file-service.vala 2014-08-21 14:08:17 +0000
3+++ lib/synapse-core/desktop-file-service.vala 2015-09-02 08:29:49 +0000
4@@ -237,6 +237,8 @@
5 instance = null;
6 }
7
8+ public signal void init_done ();
9+
10 public async void initialize ()
11 {
12 if (init_once.is_initialized ()) return;
13@@ -251,6 +253,7 @@
14
15 yield load_all_desktop_files ();
16
17+ init_done ();
18 init_once.leave (true);
19 }
20
21
22=== modified file 'src/Backend/App.vala'
23--- src/Backend/App.vala 2014-10-18 01:57:49 +0000
24+++ src/Backend/App.vala 2015-09-02 08:29:49 +0000
25@@ -115,7 +115,6 @@
26 }
27
28 public App.from_synapse_match (Synapse.Match match, Synapse.Match? target = null) {
29-
30 app_type = AppType.SYNAPSE;
31
32 name = match.title;
33@@ -126,7 +125,19 @@
34 this.target = target;
35
36 update_icon ();
37-
38+ }
39+
40+ public App.from_synapse_info (Synapse.DesktopFileInfo info) {
41+ app_type = AppType.APP;
42+
43+ name = info.name.dup ();
44+ description = info.comment.dup () ?? name;
45+ exec = info.exec.dup ();
46+ desktop_id = info.desktop_id;
47+ generic_name = info.generic_name;
48+ icon_name = info.icon_name;
49+
50+ update_icon ();
51 }
52
53 ~App () {
54
55=== modified file 'src/Backend/AppSystem.vala'
56--- src/Backend/AppSystem.vala 2014-08-16 15:13:42 +0000
57+++ src/Backend/AppSystem.vala 2015-09-02 08:29:49 +0000
58@@ -22,7 +22,7 @@
59 const string SWITCHBOARD_PLUG_CATEGORY = "X-PANTHEON-Switchboard-Plug";
60
61 private Gee.ArrayList<GMenu.TreeDirectory> categories = null;
62- private Gee.HashMap<string, Gee.ArrayList<App>> apps = null;
63+ private Gee.TreeMap<string, Gee.ArrayList<App>> apps = null;
64 private GMenu.Tree apps_menu = null;
65
66 #if HAVE_ZEITGEIST
67@@ -31,22 +31,24 @@
68
69 public signal void changed ();
70
71+ public signal void recent_apps_available (App[] most_popular);
72+
73 construct {
74 #if HAVE_ZEITGEIST
75 rl_service = new RelevancyService ();
76- rl_service.update_complete.connect (update_popularity);
77+ rl_service.update_complete.connect (update_relevancy);
78 #endif
79
80 apps_menu = new GMenu.Tree ("pantheon-applications.menu", GMenu.TreeFlags.INCLUDE_EXCLUDED | GMenu.TreeFlags.SORT_DISPLAY_NAME);
81 apps_menu.changed.connect (update_app_system);
82
83- apps = new Gee.HashMap<string, Gee.ArrayList<App>> ();
84+ apps = new Gee.TreeMap<string, Gee.ArrayList<App>> ();
85 categories = new Gee.ArrayList<GMenu.TreeDirectory> ();
86
87 update_app_system ();
88 }
89
90- private void update_app_system () {
91+ public void update_app_system () {
92 debug ("Updating Applications menu tree...");
93 #if HAVE_ZEITGEIST
94 rl_service.refresh_popularity ();
95@@ -78,10 +80,34 @@
96 }
97
98 #if HAVE_ZEITGEIST
99- private void update_popularity () {
100+ private void update_relevancy () {
101 foreach (Gee.ArrayList<App> category in apps.values)
102 foreach (App app in category)
103 app.popularity = rl_service.get_app_popularity (app.desktop_id);
104+ update_recent_apps.begin ();
105+ }
106+
107+ private async void update_recent_apps () {
108+ // to get also hidden apps, etc. use synapse as data source
109+ App[] recent_apps = new App[rl_service.recent_apps.size];
110+ // wait for Synapse DesktopFileService to initialize on startup
111+ var desktop_file_service = Synapse.DesktopFileService.get_default ();
112+ var all_desktop_files = desktop_file_service.get_all_desktop_files ();
113+
114+ if (all_desktop_files.size == 0) {
115+ desktop_file_service.init_done.connect (() => {
116+ Idle.add(update_recent_apps.callback);
117+ });
118+ yield;
119+ }
120+ foreach (var d in all_desktop_files) {
121+ if (rl_service.recent_apps.contains (d.desktop_id)) {
122+ var app = new App.from_synapse_info (d);
123+ app.launched.connect (rl_service.app_launched);
124+ recent_apps[rl_service.recent_apps.index_of(d.desktop_id)] = app;
125+ }
126+ }
127+ recent_apps_available (recent_apps);
128 }
129 #endif
130
131@@ -118,7 +144,7 @@
132 return app_list;
133 }
134
135- public Gee.HashMap<string, Gee.ArrayList<App>> get_apps () {
136+ public Gee.TreeMap<string, Gee.ArrayList<App>> get_apps () {
137 return apps;
138 }
139
140
141=== modified file 'src/Backend/RelevancyService.vala'
142--- src/Backend/RelevancyService.vala 2014-07-10 09:40:47 +0000
143+++ src/Backend/RelevancyService.vala 2015-09-02 08:29:49 +0000
144@@ -20,9 +20,11 @@
145 #if HAVE_ZEITGEIST
146 public class Slingshot.Backend.RelevancyService : Object {
147
148+ private const int recent_apps_count = 9;
149 private Zeitgeist.Log zg_log;
150 private Zeitgeist.DataSourceRegistry zg_dsr;
151 private Gee.HashMap<string, int> app_popularity;
152+ public Gee.ArrayList<string> recent_apps { get; private set; }
153 private bool has_datahub_gio_module = false;
154 private bool refreshing = false;
155
156@@ -34,6 +36,7 @@
157
158 zg_log = new Zeitgeist.Log ();
159 app_popularity = new Gee.HashMap<string, int> ();
160+ recent_apps = new Gee.ArrayList<string> ();
161
162 refresh_popularity ();
163 check_data_sources.begin ();
164@@ -128,6 +131,20 @@
165 app_popularity[s.uri] = (int)(relevancy * MULTIPLIER);
166 index++;
167 }
168+ // additional get most recent apps
169+ Zeitgeist.ResultSet rs2 = yield zg_log.find_events (tr, ptr_arr,
170+ Zeitgeist.StorageState.ANY,
171+ recent_apps_count,
172+ Zeitgeist.ResultType.MOST_RECENT_SUBJECTS,
173+ null);
174+ recent_apps.clear ();
175+
176+ foreach (Zeitgeist.Event e in rs2) {
177+ if (e.num_subjects () <= 0) continue;
178+ Zeitgeist.Subject s = e.get_subject (0);
179+ recent_apps.add (s.uri.replace ("application://",""));
180+ }
181+
182 update_complete ();
183 refreshing = false;
184 } catch (Error err) {
185
186=== modified file 'src/SlingshotView.vala'
187--- src/SlingshotView.vala 2015-02-01 15:13:15 +0000
188+++ src/SlingshotView.vala 2015-09-02 08:29:49 +0000
189@@ -47,7 +47,7 @@
190
191 public Backend.AppSystem app_system;
192 private Gee.ArrayList<GMenu.TreeDirectory> categories;
193- public Gee.HashMap<string, Gee.ArrayList<Backend.App>> apps;
194+ public Gee.TreeMap<string, Gee.ArrayList<Backend.App>> apps;
195
196 private Modality modality;
197 private bool can_trigger_hotcorner = true;
198@@ -322,7 +322,10 @@
199 search_entry.grab_focus ();
200 search_entry.activate.connect (search_entry_activated);
201
202- search_view.app_launched.connect (() => hide ());
203+ search_view.app_launched.connect (() => {
204+ app_system.update_app_system ();
205+ hide ();
206+ });
207
208 // This function must be after creating the page switcher
209 populate_grid_view ();
210@@ -826,11 +829,33 @@
211 grid_view.clear ();
212 foreach (Backend.App app in app_system.get_apps_by_name ()) {
213 var app_entry = new Widgets.AppEntry (app);
214- app_entry.app_launched.connect (() => hide ());
215+ app_entry.app_launched.connect (() => {
216+ app_system.update_app_system ();
217+ hide ();
218+ });
219 grid_view.append (app_entry);
220 app_entry.show_all ();
221 }
222
223+ app_system.recent_apps_available.connect ((list) => {
224+ apps.set ("recent", new Gee.ArrayList<Backend.App>.wrap (list));
225+ Gtk.Widget[] widgets = {};
226+ foreach (var app in list) {
227+ var app_entry = new Widgets.SearchItem (app);
228+ app_entry.button_release_event.connect (() => {
229+ if (!app_entry.dragging) {
230+ app.launch ();
231+ app_system.update_app_system ();
232+ hide ();
233+ }
234+ return true;
235+ });
236+ widgets += app_entry;
237+ }
238+ grid_view.set_recent_apps (widgets);
239+ category_view.setup_sidebar ();
240+ });
241+
242 stack.set_visible_child_name ("normal");
243 }
244
245
246=== modified file 'src/Widgets/CategoryView.vala'
247--- src/Widgets/CategoryView.vala 2015-01-17 23:56:32 +0000
248+++ src/Widgets/CategoryView.vala 2015-09-02 08:29:49 +0000
249@@ -21,12 +21,15 @@
250 private Gtk.Grid container;
251 public Sidebar category_switcher;
252 public Gtk.Separator separator;
253- public Widgets.Grid app_view;
254+ public Widgets.Grid app_view;
255+ private Gtk.Box recent_box;
256+ private Gtk.Stack stack;
257 private SlingshotView view;
258
259 private const string ALL_APPLICATIONS = _("All Applications");
260 private const string NEW_FILTER = _("Create a new Filter");
261 private const string SWITCHBOARD_CATEGORY = "switchboard";
262+ private const string RECENT_CATEGORY = _("Recent");
263
264 private int current_position = 0;
265
266@@ -48,13 +51,37 @@
267
268 container.add (category_switcher);
269 container.add (separator);
270- container.add (app_view);
271+ stack = new Gtk.Stack ();
272+ stack.add_named (create_recent_apps (), "list");
273+ stack.add_named (app_view, "grid");
274+ container.add (stack);
275 add (container);
276
277 connect_events ();
278 setup_sidebar ();
279 }
280
281+
282+ private Gtk.Widget create_recent_apps () {
283+ var recent_scroll_window = new Gtk.ScrolledWindow (null, null);
284+ recent_scroll_window.hscrollbar_policy = Gtk.PolicyType.NEVER;
285+ recent_scroll_window.margin_end = 6;
286+ recent_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
287+ recent_box.margin_start = 12;
288+
289+ var context_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
290+ var context_fixed = new Gtk.Fixed ();
291+ context_fixed.margin_start = 12;
292+ context_fixed.put (context_box, 0, 0);
293+
294+ var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
295+ box.pack_start (recent_box, true);
296+ box.pack_start (context_fixed, false);
297+
298+ recent_scroll_window.add_with_viewport (box);
299+ return recent_scroll_window;
300+ }
301+
302 public void setup_sidebar () {
303 var old_selected = category_switcher.selected;
304 category_ids.clear ();
305@@ -62,14 +89,20 @@
306 app_view.set_size_request (-1, -1);
307 // Fill the sidebar
308 int n = 0;
309- foreach (string cat_name in view.apps.keys) {
310- if (cat_name == SWITCHBOARD_CATEGORY)
311+ if (view.apps.has_key ("recent") && view.apps["recent"].size > 0) {
312+ category_ids.set (n, "recent");
313+ category_switcher.add_category (RECENT_CATEGORY);
314+ n++;
315+ }
316+ foreach (string cat_name in view.apps.ascending_keys) {
317+ if (cat_name == SWITCHBOARD_CATEGORY || cat_name == "recent")
318 continue;
319
320 category_ids.set (n, cat_name);
321 category_switcher.add_category (GLib.dgettext ("gnome-menus-3.0", cat_name).dup ());
322 n++;
323 }
324+
325 category_switcher.show_all ();
326
327 int minimum_width;
328@@ -82,8 +115,14 @@
329
330 int columns = view.columns - removing_columns;
331 app_view.resize (view.rows, columns);
332-
333+
334+ //resize recent list view because first category entry determines layout
335+ recent_box.set_size_request (columns * 125, -1);
336 category_switcher.selected = old_selected;
337+
338+ // selected first non recent category like in grid view
339+ if (view.apps.has_key ("recent") && view.apps["recent"].size > 0)
340+ category_switcher.select_nth (1);
341 }
342
343 private void connect_events () {
344@@ -103,12 +142,32 @@
345 }
346
347 public void show_filtered_apps (string category) {
348-
349- app_view.clear ();
350- foreach (Backend.App app in view.apps[category])
351- add_app (app);
352-
353- current_position = 0;
354+ if (category == "recent") {
355+ stack.set_visible_child_name ("list");
356+ foreach (var w in recent_box.get_children ()) {
357+ w.destroy ();
358+ }
359+ foreach (Backend.App app in view.apps[category]) {
360+ var app_entry = new Widgets.SearchItem (app);
361+ app_entry.button_release_event.connect (() => {
362+ if (!app_entry.dragging) {
363+ app.launch ();
364+ view.hide ();
365+ }
366+ return true;
367+ });
368+ recent_box.pack_start (app_entry, false, false);
369+ app_entry.show_all ();
370+ }
371+ } else {
372+ stack.set_visible_child_name ("grid");
373+ app_view.clear ();
374+ foreach (Backend.App app in view.apps[category]) {
375+ add_app (app);
376+ }
377+
378+ current_position = 0;
379+ }
380
381 }
382
383
384=== modified file 'src/Widgets/Grid.vala'
385--- src/Widgets/Grid.vala 2015-02-01 15:02:37 +0000
386+++ src/Widgets/Grid.vala 2015-09-02 08:29:49 +0000
387@@ -31,12 +31,17 @@
388 private Gtk.Stack stack;
389 private Gtk.Grid current_grid;
390 private Gee.HashMap<int, Gtk.Grid> grids;
391+ private Gtk.Box recent_box;
392+ private Gtk.ScrolledWindow recent_scroll_window;
393
394 private uint current_row = 0;
395 private uint current_col = 0;
396
397 private Page page;
398
399+ private bool recent_apps_toogle_set = false;
400+ private bool recent_bottom_reached = false;
401+
402 public Grid (int rows, int columns) {
403 page.rows = rows;
404 page.columns = columns;
405@@ -59,10 +64,32 @@
406 add (main_grid);
407
408 grids = new Gee.HashMap<int, Gtk.Grid> (null, null);
409+ // recent apps at page 0
410+ create_recent_apps ();
411 create_new_grid ();
412 go_to_number (1);
413 }
414
415+ private void create_recent_apps () {
416+ recent_scroll_window = new Gtk.ScrolledWindow (null, null);
417+ recent_scroll_window.hscrollbar_policy = Gtk.PolicyType.NEVER;
418+ recent_scroll_window.margin_end = 6;
419+ recent_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
420+ recent_box.margin_start = 12;
421+
422+ var context_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
423+ var context_fixed = new Gtk.Fixed ();
424+ context_fixed.margin_start = 12;
425+ context_fixed.put (context_box, 0, 0);
426+
427+ var box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
428+ box.pack_start (recent_box, true);
429+ box.pack_start (context_fixed, false);
430+
431+ recent_scroll_window.add_with_viewport (box);
432+ stack.add_titled (recent_scroll_window, "0", "0");
433+ }
434+
435 private void create_new_grid () {
436 // Grid properties
437 current_grid = new Gtk.Grid ();
438@@ -107,13 +134,14 @@
439 foreach (Gtk.Widget widget in grid.get_children ()) {
440 widget.destroy ();
441 }
442-
443 grid.destroy ();
444 }
445-
446+ recent_scroll_window.destroy ();
447 grids.clear ();
448 current_row = 0;
449 current_col = 0;
450+ create_recent_apps ();
451+ recent_apps_toogle_set = false;
452 page.number = 1;
453 create_new_grid ();
454 stack.set_visible_child (current_grid);
455@@ -147,17 +175,29 @@
456 }
457
458 public void go_to_next () {
459- int page_number = get_current_page ()+1;
460- if (page_number <= get_n_pages ())
461+ if (get_current_page () == 0 && !recent_bottom_reached) {
462+ var v_adjust = recent_scroll_window.get_vadjustment ();
463+ if ((v_adjust.upper - v_adjust.page_size) == v_adjust.value)
464+ GLib.Timeout.add(100, () => {
465+ recent_bottom_reached = true;
466+ return false;
467+ });
468+ return;
469+ }
470+ int page_number = get_current_page () + 1;
471+ if (page_number <= get_n_pages ()) {
472 stack.set_visible_child_name (page_number.to_string ());
473+ }
474
475 page_switcher.update_selected ();
476 }
477
478 public void go_to_previous () {
479- int page_number = get_current_page ()-1;
480- if (page_number > 0)
481+ recent_bottom_reached = false;
482+ int page_number = get_current_page () - 1;
483+ if (page_number > 0 || (page_number == 0 && recent_apps_toogle_set)) {
484 stack.set_visible_child_name (page_number.to_string ());
485+ }
486
487 page_switcher.update_selected ();
488 }
489@@ -178,5 +218,26 @@
490 page.columns = columns;
491 page.number = 1;
492 }
493+
494+ public void set_recent_apps (Gtk.Widget[] recent_apps) {
495+ // don't show if nothing to show
496+ if (recent_apps.length == 0 && !recent_apps_toogle_set) {
497+ return;
498+ }
499+ foreach (var w in recent_box.get_children ()) {
500+ w.destroy ();
501+ }
502+ for (int i = 0; i < recent_apps.length; i++) {
503+ var app_entry = recent_apps[i];
504+ recent_box.pack_start (app_entry, false, false);
505+ app_entry.show_all ();
506+ }
507+ recent_box.show ();
508+ if (!recent_apps_toogle_set) {
509+ page_switcher.add_recent_apps_toggle (recent_scroll_window);
510+ recent_apps_toogle_set = true;
511+ }
512+ page_switcher.update_selected ();
513+ }
514 }
515 }
516
517=== modified file 'src/Widgets/SearchView.vala'
518--- src/Widgets/SearchView.vala 2015-05-29 00:40:47 +0000
519+++ src/Widgets/SearchView.vala 2015-09-02 08:29:49 +0000
520@@ -209,7 +209,6 @@
521 }
522
523 private void show_app (Backend.App app, string search_term) {
524-
525 var search_item = new SearchItem (app, search_term);
526 app.start_search.connect ((search, target) => start_search (search, target));
527 search_item.button_release_event.connect (() => {
528@@ -325,8 +324,9 @@
529 * @return indicates whether slingshot should now be hidden
530 */
531 public bool launch_selected () {
532-
533- return selected_app.launch_app ();
534+ var tmp = selected_app.launch_app ();
535+ app_launched ();
536+ return tmp;
537
538 }
539
540
541=== modified file 'src/Widgets/Sidebar.vala'
542--- src/Widgets/Sidebar.vala 2014-10-27 19:01:28 +0000
543+++ src/Widgets/Sidebar.vala 2015-09-02 08:29:49 +0000
544@@ -52,7 +52,7 @@
545 public Sidebar () {
546
547 store = new Gtk.TreeStore (Columns.N_COLUMNS, typeof (int), typeof (string));
548- store.set_sort_column_id (1, Gtk.SortType.ASCENDING);
549+ store.set_sort_column_id (0, Gtk.SortType.ASCENDING);
550 set_model (store);
551
552 set_headers_visible (false);
553
554=== modified file 'src/Widgets/Switcher.vala'
555--- src/Widgets/Switcher.vala 2014-09-04 05:58:55 +0000
556+++ src/Widgets/Switcher.vala 2015-09-02 08:29:49 +0000
557@@ -49,6 +49,10 @@
558 }
559
560 private void add_child (Gtk.Widget widget) {
561+ //skip recent_apps stack child
562+ if (stack.get_children ().index (widget) == 0) {
563+ return;
564+ }
565 var button = new Gtk.ToggleButton.with_label ((buttons.size +1).to_string ());
566 button.width_request = 30;
567 button.can_focus = false;
568@@ -98,6 +102,9 @@
569
570 private void on_stack_child_removed (Gtk.Widget widget) {
571 var button = buttons.get (widget);
572+ if (button == null) {
573+ return;
574+ }
575 remove (button);
576 buttons.unset (widget);
577 }
578@@ -110,8 +117,9 @@
579 public void clear_children () {
580 foreach (weak Gtk.Widget button in get_children ()) {
581 button.hide ();
582- if (button.get_parent () != null)
583+ if (button.get_parent () != null) {
584 remove (button);
585+ }
586 }
587 }
588
589@@ -124,4 +132,40 @@
590 }
591 }
592 }
593+
594+ public void add_recent_apps_toggle (Gtk.Widget widget) {
595+ var button = new Gtk.ToggleButton ();
596+ button.set_image (new Gtk.Image.from_icon_name ("document-open-recent-symbolic", Gtk.IconSize.BUTTON));
597+ button.set_tooltip_text (_("Recently used apps"));
598+ button.width_request = 30;
599+ button.can_focus = false;
600+ button.get_style_context ().add_class ("switcher");
601+ button.button_release_event.connect (() => {
602+ foreach (var entry in buttons.entries) {
603+ if (entry.value == button) {
604+ on_button_clicked (entry.key);
605+ }
606+ entry.value.active = false;
607+ }
608+ button.active = true;
609+ return true;
610+ });
611+
612+ // position recent apps toogle first
613+ Gtk.Widget[] tmp = {};
614+ foreach (var child in get_children ()) {
615+ if (!(child is Gtk.ToggleButton)) continue;
616+ tmp += child;
617+ remove (child);
618+ }
619+
620+ add (button);
621+ foreach (var child in tmp) {
622+ add (child);
623+ }
624+
625+ buttons.set (widget, button);
626+
627+ show_all ();
628+ }
629 }
630\ No newline at end of file

Subscribers

People subscribed via source and target branches