Merge lp:~zeitgeist/plank/zeitgeist into lp:plank

Proposed by Rico Tzschichholz
Status: Work in progress
Proposed branch: lp:~zeitgeist/plank/zeitgeist
Merge into: lp:plank
Diff against target: 322 lines (+189/-3)
5 files modified
configure.ac (+29/-0)
lib/Items/ApplicationDockItemProvider.vala (+141/-1)
lib/Items/DefaultApplicationDockItemProvider.vala (+11/-2)
lib/Items/TransientDockItem.vala (+5/-0)
lib/libplank.symbols (+3/-0)
To merge this branch: bzr merge lp:~zeitgeist/plank/zeitgeist
Reviewer Review Type Date Requested Status
Docky Core Pending
Review via email: mp+282842@code.launchpad.net

This proposal supersedes a proposal from 2014-01-27.

To post a comment you must log in.
Revision history for this message
Danielle Foré (danrabbit) wrote : Posted in a previous version of this proposal

I like the idea, but I'm worried about things just popping up unexpectedly. I think it might make sense to wait for the user to open one of the suggested apps and then "smart-pin" it at that time. In this way, we're not actually adding the item, we're just not removing it :p

lp:~zeitgeist/plank/zeitgeist updated
1489. By Rico Tzschichholz

preferenceswindow: Allow changing the backing DockController

1490. By Rico Tzschichholz

unity: Expose API to handle LauncherEntry DBus clients

1491. By Rico Tzschichholz

po: Update translations

1492. By Rico Tzschichholz

Cast callbacks to GLib.SourceFunc where possible

Unmerged revisions

1493. By Rico Tzschichholz

WIP Add zeitgeist support for adding suggested applications

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2015-11-03 12:01:37 +0000
3+++ configure.ac 2016-01-30 20:46:42 +0000
4@@ -265,6 +265,34 @@
5 fi
6 AM_CONDITIONAL([HAVE_DBUSMENU], [test "x$enable_dbusmenu" = "xyes"])
7
8+# Support suggested applications provided with zeitgeist
9+ZEITGEIST_MIN_VERSION=0.3
10+ZEITGEIST_PKGS="zeitgeist-1.0 >= $ZEITGEIST_MIN_VERSION"
11+ZEITGEIST2_PKGS="zeitgeist-2.0 >= $ZEITGEIST_MIN_VERSION"
12+AC_ARG_ENABLE([zeitgeist],
13+ AS_HELP_STRING([--enable-zeitgeist],
14+ [Enable suggested applications provided with zeitgeist-1.0]),
15+ [enable_zeitgeist=$enableval], [enable_zeitgeist=no])
16+AC_ARG_ENABLE([zeitgeist2],
17+ AS_HELP_STRING([--enable-zeitgeist2],
18+ [Enable suggested applications provided with zeitgeist-2.0]),
19+ [enable_zeitgeist2=$enableval],
20+ [PKG_CHECK_MODULES(ZEITGEIST, $ZEITGEIST2_PKGS, [enable_zeitgeist2=yes], [enable_zeitgeist2=no])])
21+if test "x$enable_zeitgeist" = "xyes" -a "x$enable_zeitgeist2" = "xyes" ; then
22+ AC_MSG_ERROR([Not possible to build against both, zeitgeist-1.0 and zeitgeist-2.0.])
23+fi
24+if test "x$enable_zeitgeist" = "xyes" -a "x$enable_zeitgeist2" = "xno" ; then
25+ PLANK_CORE_OPTIONAL_PKGS="$PLANK_CORE_OPTIONAL_PKGS $ZEITGEIST_PKGS"
26+ PLANK_CORE_VALA_PKGS="$PLANK_CORE_VALA_PKGS --pkg zeitgeist-1.0"
27+ VALAFLAGS="$VALAFLAGS --define HAVE_ZEITGEIST"
28+fi
29+if test "x$enable_zeitgeist" = "xno" -a "x$enable_zeitgeist2" = "xyes" ; then
30+ PLANK_CORE_OPTIONAL_PKGS="$PLANK_CORE_OPTIONAL_PKGS $ZEITGEIST2_PKGS"
31+ PLANK_CORE_VALA_PKGS="$PLANK_CORE_VALA_PKGS --pkg zeitgeist-2.0"
32+ VALAFLAGS="$VALAFLAGS --define HAVE_ZEITGEIST2"
33+ enable_zeitgeist=yes
34+fi
35+AM_CONDITIONAL([HAVE_ZEITGEIST], [test "x$enable_zeitgeist" = "xyes" -o "x$enable_zeitgeist2" = "xyes"])
36
37
38 AC_SUBST(PLANK_CORE_OPTIONAL_PKGS)
39@@ -426,6 +454,7 @@
40 Use gee-0.8.................: ${enable_gee_0_8}
41 Dbusmenu support............: ${enable_dbusmenu}
42 HiDPI support...............: ${enable_hidpi}
43+ Zeitgeist support...........: ${enable_zeitgeist}
44 XInput Barriers support.....: ${enable_barriers}
45
46 Apport support..............: ${enable_apport}
47
48=== modified file 'lib/Items/ApplicationDockItemProvider.vala'
49--- lib/Items/ApplicationDockItemProvider.vala 2016-01-30 12:08:11 +0000
50+++ lib/Items/ApplicationDockItemProvider.vala 2016-01-30 20:46:42 +0000
51@@ -34,6 +34,11 @@
52 bool delay_items_monitor_handle = false;
53 Gee.ArrayList<GLib.File> queued_files;
54
55+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
56+ Zeitgeist.Log zglog = Zeitgeist.Log.get_default();
57+ Gee.ArrayList<TransientDockItem> suggested_app_items = new Gee.ArrayList<TransientDockItem> ();
58+#endif
59+
60 /**
61 * Creates a new container for dock items.
62 *
63@@ -61,12 +66,32 @@
64 } catch (Error e) {
65 critical ("Unable to watch the launchers directory. (%s)", e.message);
66 }
67+
68+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
69+ // FIXME Workaround to have an initialized PositionManager
70+ Idle.add (() => {
71+ // FIXME
72+ //controller.position_manager.notify["MaxItemCount"].connect (update_suggested_apps);
73+ update_suggested_apps ();
74+ return false;
75+ });
76+
77+ // FIXME Update suggested apps in a "proper" interval
78+ Timeout.add_seconds (3600, () => {
79+ update_suggested_apps ();
80+ return true;
81+ });
82+#endif
83 }
84
85 ~ApplicationDockItemProvider ()
86 {
87 queued_files = null;
88
89+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
90+ // FIXME
91+ //controller.position_manager.notify["MaxItemCount"].disconnect (update_suggested_apps);
92+#endif
93 Matcher.get_default ().application_opened.disconnect (app_opened);
94
95 if (items_monitor != null) {
96@@ -198,6 +223,84 @@
97 return item_list.to_array ();
98 }
99
100+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
101+ public void update_suggested_apps ()
102+ {
103+ Logger.verbose ("ApplicationDockItemProvider.update_suggested_apps ()");
104+
105+ // FIXME
106+ //var max_item_count = controller.position_manager.MaxItemCount;
107+ var max_item_count = 15;
108+ //var max_item_count = controller.position_manager.MaxItemCount;
109+ var num_events = 3;
110+ if (get_n_items (true, suggested_app_items) >= max_item_count - num_events)
111+ return;
112+
113+ Logger.verbose ("ApplicationDockItemProvider.update_suggested_apps ().run (%i)", num_events);
114+
115+#if HAVE_ZEITGEIST
116+ var templates = new PtrArray ();
117+#else
118+ var templates = new GenericArray<Zeitgeist.Event> ();
119+#endif
120+ // Consider used applications within the last 2 months
121+ var now = new DateTime.now_local ().to_unix () * 1000;
122+ var start = now - 60 * 86400000;
123+ var time_range = new Zeitgeist.TimeRange (start, now);
124+
125+ var event = new Zeitgeist.Event ();
126+#if HAVE_ZEITGEIST
127+ var subject = new Zeitgeist.Subject ();
128+ subject.set_uri ("application://*");
129+#else
130+ var subject = new Zeitgeist.Subject.full ("application://*");
131+#endif
132+ event.add_subject (subject);
133+ templates.add (event);
134+
135+ zglog.find_events.begin (time_range, templates, Zeitgeist.StorageState.ANY, num_events,
136+ Zeitgeist.ResultType.MOST_POPULAR_SUBJECTS, null, (obj, res) => {
137+ Zeitgeist.ResultSet events = zglog.find_events.end (res);
138+ var new_suggested_app_items = new Gee.ArrayList<TransientDockItem> ();
139+ foreach (var e in events) {
140+#if HAVE_ZEITGEIST
141+ var app_uri = e.get_subject (0).get_uri ();
142+#else
143+ var app_uri = e.subjects[0].uri;
144+#endif
145+
146+ // Find a matching desktop-file and create new TransientDockItem
147+ var desktop_file = desktop_file_for_application_uri (app_uri);
148+ if (desktop_file == null)
149+ continue;
150+
151+ var launcher_uri = desktop_file.get_uri ();
152+ DockItem? current_item = item_for_uri (launcher_uri);
153+ if (current_item == null) {
154+ current_item = new TransientDockItem.with_launcher (launcher_uri);
155+ add (current_item);
156+ Logger.verbose ("SuggestedApp added: %s[%s, %i]", current_item.Text, current_item.Launcher, (int)current_item);
157+ new_suggested_app_items.add (current_item as TransientDockItem);
158+ } else if (current_item is TransientDockItem) {
159+ Logger.verbose ("SuggestedApp confirmed: %s[%s, %i]", current_item.Text, current_item.Launcher, (int)current_item);
160+ new_suggested_app_items.add (current_item as TransientDockItem);
161+ }
162+ }
163+
164+ suggested_app_items.remove_all (new_suggested_app_items);
165+ foreach (var item in suggested_app_items) {
166+ if (!can_remove_transient_item (item))
167+ return;
168+
169+ Logger.verbose ("SuggestedApp removed: %s[%s, %i]", item.Text, item.Launcher, (int)item);
170+ remove (item);
171+ }
172+
173+ suggested_app_items = new_suggested_app_items;
174+ });
175+ }
176+#endif
177+
178 protected virtual void app_opened (Bamf.Application app)
179 {
180 // Make sure internal window-list of Wnck is most up to date
181@@ -260,6 +363,12 @@
182 }
183
184 queued_files.clear ();
185+
186+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
187+ // Update suggested applications while it is possible the
188+ // added application(s) were
189+ update_suggested_apps ();
190+#endif
191 }
192
193 [CCode (instance_pos = -1)]
194@@ -291,6 +400,37 @@
195 process_queued_files ();
196 }
197
198+ public bool can_remove_transient_item (TransientDockItem item)
199+ {
200+ return (item != null
201+ && item.App == null
202+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
203+ && !suggested_app_items.contains (item)
204+#endif
205+ && !item.has_unity_info ());
206+ }
207+
208+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
209+ int get_n_items (bool visible_only, Gee.List<DockElement>? ignore = null)
210+ {
211+ unowned Gee.List<DockElement> elements = (visible_only ? visible_elements : internal_elements);
212+ var elements_count = elements.size;
213+
214+ //foreach (var item in items)
215+ // if (item.is_virtual ());
216+ // items_count--;
217+
218+ if (ignore == null)
219+ return elements_count;
220+
221+ foreach (var element in ignore)
222+ if (elements.contains (element))
223+ elements_count--;
224+
225+ return elements_count;
226+ }
227+#endif
228+
229 protected override void connect_element (DockElement element)
230 {
231 base.connect_element (element);
232@@ -332,7 +472,7 @@
233 // Remove item which only exists because of the presence of
234 // this removed LauncherEntry interface
235 unowned TransientDockItem? transient_item = item as TransientDockItem;
236- if (transient_item != null && transient_item.App == null)
237+ if (can_remove_transient_item (transient_item))
238 remove (transient_item);
239
240 break;
241
242=== modified file 'lib/Items/DefaultApplicationDockItemProvider.vala'
243--- lib/Items/DefaultApplicationDockItemProvider.vala 2015-11-03 10:37:19 +0000
244+++ lib/Items/DefaultApplicationDockItemProvider.vala 2016-01-30 20:46:42 +0000
245@@ -1,5 +1,6 @@
246 //
247 // Copyright (C) 2013 Rico Tzschichholz
248+// Copyright (C) 2013 Seif Lotfy
249 //
250 // This file is part of Plank.
251 //
252@@ -124,8 +125,9 @@
253
254 void app_closed (DockItem item)
255 {
256- if (item is TransientDockItem
257- && !(((TransientDockItem) item).has_unity_info ()))
258+ unowned TransientDockItem transient_item = (item as TransientDockItem);
259+ transient_item.App = null;
260+ if (can_remove_transient_item (transient_item))
261 remove (item);
262 }
263
264@@ -222,7 +224,14 @@
265 app = ((ApplicationDockItem) item).App;
266
267 if (app == null || !app.is_running ()) {
268+ // TODO Replace the item if it is a suggested appliction
269 remove (item);
270+
271+#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
272+ // Update suggested applications while it is possible the
273+ // removed application is one
274+ update_suggested_apps ();
275+#endif
276 return;
277 }
278
279
280=== modified file 'lib/Items/TransientDockItem.vala'
281--- lib/Items/TransientDockItem.vala 2015-11-03 10:37:19 +0000
282+++ lib/Items/TransientDockItem.vala 2016-01-30 20:46:42 +0000
283@@ -95,6 +95,11 @@
284 return false;
285 }
286
287+ public bool is_virtual ()
288+ {
289+ return (App == null);
290+ }
291+
292 /**
293 * {@inheritDoc}
294 */
295
296=== modified file 'lib/libplank.symbols'
297--- lib/libplank.symbols 2016-01-30 12:08:11 +0000
298+++ lib/libplank.symbols 2016-01-30 20:46:42 +0000
299@@ -49,6 +49,7 @@
300 plank_application_dock_item_new_with_dockitem_filename
301 plank_application_dock_item_parse_launcher
302 plank_application_dock_item_provider_app_opened
303+plank_application_dock_item_provider_can_remove_transient_item
304 plank_application_dock_item_provider_construct
305 plank_application_dock_item_provider_delay_items_monitor
306 plank_application_dock_item_provider_get_item_list_string
307@@ -57,6 +58,7 @@
308 plank_application_dock_item_provider_item_for_application
309 plank_application_dock_item_provider_new
310 plank_application_dock_item_provider_resume_items_monitor
311+plank_application_dock_item_provider_update_suggested_apps
312 plank_application_dock_item_set_urgent
313 plank_application_dock_item_unity_reset
314 plank_application_dock_item_unity_update
315@@ -679,6 +681,7 @@
316 plank_transient_dock_item_construct
317 plank_transient_dock_item_construct_with_launcher
318 plank_transient_dock_item_get_type
319+plank_transient_dock_item_is_virtual
320 plank_transient_dock_item_new
321 plank_transient_dock_item_new_with_launcher
322 plank_unity_add_client

Subscribers

People subscribed via source and target branches

to status/vote changes: