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

Proposed by Rico Tzschichholz on 2016-01-16
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 2016-01-16 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.
Daniel Fore (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 on 2016-01-30
1489. By Rico Tzschichholz on 2016-01-26

preferenceswindow: Allow changing the backing DockController

1490. By Rico Tzschichholz on 2016-01-30

unity: Expose API to handle LauncherEntry DBus clients

1491. By Rico Tzschichholz on 2016-01-30

po: Update translations

1492. By Rico Tzschichholz on 2016-01-30

Cast callbacks to GLib.SourceFunc where possible

Unmerged revisions

1493. By Rico Tzschichholz on 2016-01-16

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
=== modified file 'configure.ac'
--- configure.ac 2015-11-03 12:01:37 +0000
+++ configure.ac 2016-01-30 20:46:42 +0000
@@ -265,6 +265,34 @@
265fi265fi
266AM_CONDITIONAL([HAVE_DBUSMENU], [test "x$enable_dbusmenu" = "xyes"])266AM_CONDITIONAL([HAVE_DBUSMENU], [test "x$enable_dbusmenu" = "xyes"])
267267
268# Support suggested applications provided with zeitgeist
269ZEITGEIST_MIN_VERSION=0.3
270ZEITGEIST_PKGS="zeitgeist-1.0 >= $ZEITGEIST_MIN_VERSION"
271ZEITGEIST2_PKGS="zeitgeist-2.0 >= $ZEITGEIST_MIN_VERSION"
272AC_ARG_ENABLE([zeitgeist],
273 AS_HELP_STRING([--enable-zeitgeist],
274 [Enable suggested applications provided with zeitgeist-1.0]),
275 [enable_zeitgeist=$enableval], [enable_zeitgeist=no])
276AC_ARG_ENABLE([zeitgeist2],
277 AS_HELP_STRING([--enable-zeitgeist2],
278 [Enable suggested applications provided with zeitgeist-2.0]),
279 [enable_zeitgeist2=$enableval],
280 [PKG_CHECK_MODULES(ZEITGEIST, $ZEITGEIST2_PKGS, [enable_zeitgeist2=yes], [enable_zeitgeist2=no])])
281if test "x$enable_zeitgeist" = "xyes" -a "x$enable_zeitgeist2" = "xyes" ; then
282 AC_MSG_ERROR([Not possible to build against both, zeitgeist-1.0 and zeitgeist-2.0.])
283fi
284if test "x$enable_zeitgeist" = "xyes" -a "x$enable_zeitgeist2" = "xno" ; then
285 PLANK_CORE_OPTIONAL_PKGS="$PLANK_CORE_OPTIONAL_PKGS $ZEITGEIST_PKGS"
286 PLANK_CORE_VALA_PKGS="$PLANK_CORE_VALA_PKGS --pkg zeitgeist-1.0"
287 VALAFLAGS="$VALAFLAGS --define HAVE_ZEITGEIST"
288fi
289if test "x$enable_zeitgeist" = "xno" -a "x$enable_zeitgeist2" = "xyes" ; then
290 PLANK_CORE_OPTIONAL_PKGS="$PLANK_CORE_OPTIONAL_PKGS $ZEITGEIST2_PKGS"
291 PLANK_CORE_VALA_PKGS="$PLANK_CORE_VALA_PKGS --pkg zeitgeist-2.0"
292 VALAFLAGS="$VALAFLAGS --define HAVE_ZEITGEIST2"
293 enable_zeitgeist=yes
294fi
295AM_CONDITIONAL([HAVE_ZEITGEIST], [test "x$enable_zeitgeist" = "xyes" -o "x$enable_zeitgeist2" = "xyes"])
268296
269297
270AC_SUBST(PLANK_CORE_OPTIONAL_PKGS)298AC_SUBST(PLANK_CORE_OPTIONAL_PKGS)
@@ -426,6 +454,7 @@
426 Use gee-0.8.................: ${enable_gee_0_8}454 Use gee-0.8.................: ${enable_gee_0_8}
427 Dbusmenu support............: ${enable_dbusmenu}455 Dbusmenu support............: ${enable_dbusmenu}
428 HiDPI support...............: ${enable_hidpi}456 HiDPI support...............: ${enable_hidpi}
457 Zeitgeist support...........: ${enable_zeitgeist}
429 XInput Barriers support.....: ${enable_barriers}458 XInput Barriers support.....: ${enable_barriers}
430459
431 Apport support..............: ${enable_apport}460 Apport support..............: ${enable_apport}
432461
=== modified file 'lib/Items/ApplicationDockItemProvider.vala'
--- lib/Items/ApplicationDockItemProvider.vala 2016-01-30 12:08:11 +0000
+++ lib/Items/ApplicationDockItemProvider.vala 2016-01-30 20:46:42 +0000
@@ -34,6 +34,11 @@
34 bool delay_items_monitor_handle = false;34 bool delay_items_monitor_handle = false;
35 Gee.ArrayList<GLib.File> queued_files;35 Gee.ArrayList<GLib.File> queued_files;
36 36
37#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
38 Zeitgeist.Log zglog = Zeitgeist.Log.get_default();
39 Gee.ArrayList<TransientDockItem> suggested_app_items = new Gee.ArrayList<TransientDockItem> ();
40#endif
41
37 /**42 /**
38 * Creates a new container for dock items.43 * Creates a new container for dock items.
39 *44 *
@@ -61,12 +66,32 @@
61 } catch (Error e) {66 } catch (Error e) {
62 critical ("Unable to watch the launchers directory. (%s)", e.message);67 critical ("Unable to watch the launchers directory. (%s)", e.message);
63 }68 }
69
70#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
71 // FIXME Workaround to have an initialized PositionManager
72 Idle.add (() => {
73 // FIXME
74 //controller.position_manager.notify["MaxItemCount"].connect (update_suggested_apps);
75 update_suggested_apps ();
76 return false;
77 });
78
79 // FIXME Update suggested apps in a "proper" interval
80 Timeout.add_seconds (3600, () => {
81 update_suggested_apps ();
82 return true;
83 });
84#endif
64 }85 }
65 86
66 ~ApplicationDockItemProvider ()87 ~ApplicationDockItemProvider ()
67 {88 {
68 queued_files = null;89 queued_files = null;
69 90
91#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
92 // FIXME
93 //controller.position_manager.notify["MaxItemCount"].disconnect (update_suggested_apps);
94#endif
70 Matcher.get_default ().application_opened.disconnect (app_opened);95 Matcher.get_default ().application_opened.disconnect (app_opened);
71 96
72 if (items_monitor != null) {97 if (items_monitor != null) {
@@ -198,6 +223,84 @@
198 return item_list.to_array ();223 return item_list.to_array ();
199 }224 }
200 225
226#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
227 public void update_suggested_apps ()
228 {
229 Logger.verbose ("ApplicationDockItemProvider.update_suggested_apps ()");
230
231 // FIXME
232 //var max_item_count = controller.position_manager.MaxItemCount;
233 var max_item_count = 15;
234 //var max_item_count = controller.position_manager.MaxItemCount;
235 var num_events = 3;
236 if (get_n_items (true, suggested_app_items) >= max_item_count - num_events)
237 return;
238
239 Logger.verbose ("ApplicationDockItemProvider.update_suggested_apps ().run (%i)", num_events);
240
241#if HAVE_ZEITGEIST
242 var templates = new PtrArray ();
243#else
244 var templates = new GenericArray<Zeitgeist.Event> ();
245#endif
246 // Consider used applications within the last 2 months
247 var now = new DateTime.now_local ().to_unix () * 1000;
248 var start = now - 60 * 86400000;
249 var time_range = new Zeitgeist.TimeRange (start, now);
250
251 var event = new Zeitgeist.Event ();
252#if HAVE_ZEITGEIST
253 var subject = new Zeitgeist.Subject ();
254 subject.set_uri ("application://*");
255#else
256 var subject = new Zeitgeist.Subject.full ("application://*");
257#endif
258 event.add_subject (subject);
259 templates.add (event);
260
261 zglog.find_events.begin (time_range, templates, Zeitgeist.StorageState.ANY, num_events,
262 Zeitgeist.ResultType.MOST_POPULAR_SUBJECTS, null, (obj, res) => {
263 Zeitgeist.ResultSet events = zglog.find_events.end (res);
264 var new_suggested_app_items = new Gee.ArrayList<TransientDockItem> ();
265 foreach (var e in events) {
266#if HAVE_ZEITGEIST
267 var app_uri = e.get_subject (0).get_uri ();
268#else
269 var app_uri = e.subjects[0].uri;
270#endif
271
272 // Find a matching desktop-file and create new TransientDockItem
273 var desktop_file = desktop_file_for_application_uri (app_uri);
274 if (desktop_file == null)
275 continue;
276
277 var launcher_uri = desktop_file.get_uri ();
278 DockItem? current_item = item_for_uri (launcher_uri);
279 if (current_item == null) {
280 current_item = new TransientDockItem.with_launcher (launcher_uri);
281 add (current_item);
282 Logger.verbose ("SuggestedApp added: %s[%s, %i]", current_item.Text, current_item.Launcher, (int)current_item);
283 new_suggested_app_items.add (current_item as TransientDockItem);
284 } else if (current_item is TransientDockItem) {
285 Logger.verbose ("SuggestedApp confirmed: %s[%s, %i]", current_item.Text, current_item.Launcher, (int)current_item);
286 new_suggested_app_items.add (current_item as TransientDockItem);
287 }
288 }
289
290 suggested_app_items.remove_all (new_suggested_app_items);
291 foreach (var item in suggested_app_items) {
292 if (!can_remove_transient_item (item))
293 return;
294
295 Logger.verbose ("SuggestedApp removed: %s[%s, %i]", item.Text, item.Launcher, (int)item);
296 remove (item);
297 }
298
299 suggested_app_items = new_suggested_app_items;
300 });
301 }
302#endif
303
201 protected virtual void app_opened (Bamf.Application app)304 protected virtual void app_opened (Bamf.Application app)
202 {305 {
203 // Make sure internal window-list of Wnck is most up to date306 // Make sure internal window-list of Wnck is most up to date
@@ -260,6 +363,12 @@
260 }363 }
261 364
262 queued_files.clear ();365 queued_files.clear ();
366
367#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
368 // Update suggested applications while it is possible the
369 // added application(s) were
370 update_suggested_apps ();
371#endif
263 }372 }
264 373
265 [CCode (instance_pos = -1)]374 [CCode (instance_pos = -1)]
@@ -291,6 +400,37 @@
291 process_queued_files ();400 process_queued_files ();
292 }401 }
293 402
403 public bool can_remove_transient_item (TransientDockItem item)
404 {
405 return (item != null
406 && item.App == null
407#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
408 && !suggested_app_items.contains (item)
409#endif
410 && !item.has_unity_info ());
411 }
412
413#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
414 int get_n_items (bool visible_only, Gee.List<DockElement>? ignore = null)
415 {
416 unowned Gee.List<DockElement> elements = (visible_only ? visible_elements : internal_elements);
417 var elements_count = elements.size;
418
419 //foreach (var item in items)
420 // if (item.is_virtual ());
421 // items_count--;
422
423 if (ignore == null)
424 return elements_count;
425
426 foreach (var element in ignore)
427 if (elements.contains (element))
428 elements_count--;
429
430 return elements_count;
431 }
432#endif
433
294 protected override void connect_element (DockElement element)434 protected override void connect_element (DockElement element)
295 {435 {
296 base.connect_element (element);436 base.connect_element (element);
@@ -332,7 +472,7 @@
332 // Remove item which only exists because of the presence of472 // Remove item which only exists because of the presence of
333 // this removed LauncherEntry interface473 // this removed LauncherEntry interface
334 unowned TransientDockItem? transient_item = item as TransientDockItem;474 unowned TransientDockItem? transient_item = item as TransientDockItem;
335 if (transient_item != null && transient_item.App == null)475 if (can_remove_transient_item (transient_item))
336 remove (transient_item);476 remove (transient_item);
337 477
338 break;478 break;
339479
=== modified file 'lib/Items/DefaultApplicationDockItemProvider.vala'
--- lib/Items/DefaultApplicationDockItemProvider.vala 2015-11-03 10:37:19 +0000
+++ lib/Items/DefaultApplicationDockItemProvider.vala 2016-01-30 20:46:42 +0000
@@ -1,5 +1,6 @@
1//1//
2// Copyright (C) 2013 Rico Tzschichholz2// Copyright (C) 2013 Rico Tzschichholz
3// Copyright (C) 2013 Seif Lotfy
3//4//
4// This file is part of Plank.5// This file is part of Plank.
5//6//
@@ -124,8 +125,9 @@
124 125
125 void app_closed (DockItem item)126 void app_closed (DockItem item)
126 {127 {
127 if (item is TransientDockItem128 unowned TransientDockItem transient_item = (item as TransientDockItem);
128 && !(((TransientDockItem) item).has_unity_info ()))129 transient_item.App = null;
130 if (can_remove_transient_item (transient_item))
129 remove (item);131 remove (item);
130 }132 }
131 133
@@ -222,7 +224,14 @@
222 app = ((ApplicationDockItem) item).App;224 app = ((ApplicationDockItem) item).App;
223 225
224 if (app == null || !app.is_running ()) {226 if (app == null || !app.is_running ()) {
227 // TODO Replace the item if it is a suggested appliction
225 remove (item);228 remove (item);
229
230#if HAVE_ZEITGEIST || HAVE_ZEITGEIST2
231 // Update suggested applications while it is possible the
232 // removed application is one
233 update_suggested_apps ();
234#endif
226 return;235 return;
227 }236 }
228 237
229238
=== modified file 'lib/Items/TransientDockItem.vala'
--- lib/Items/TransientDockItem.vala 2015-11-03 10:37:19 +0000
+++ lib/Items/TransientDockItem.vala 2016-01-30 20:46:42 +0000
@@ -95,6 +95,11 @@
95 return false;95 return false;
96 }96 }
97 97
98 public bool is_virtual ()
99 {
100 return (App == null);
101 }
102
98 /**103 /**
99 * {@inheritDoc}104 * {@inheritDoc}
100 */105 */
101106
=== modified file 'lib/libplank.symbols'
--- lib/libplank.symbols 2016-01-30 12:08:11 +0000
+++ lib/libplank.symbols 2016-01-30 20:46:42 +0000
@@ -49,6 +49,7 @@
49plank_application_dock_item_new_with_dockitem_filename49plank_application_dock_item_new_with_dockitem_filename
50plank_application_dock_item_parse_launcher50plank_application_dock_item_parse_launcher
51plank_application_dock_item_provider_app_opened51plank_application_dock_item_provider_app_opened
52plank_application_dock_item_provider_can_remove_transient_item
52plank_application_dock_item_provider_construct53plank_application_dock_item_provider_construct
53plank_application_dock_item_provider_delay_items_monitor54plank_application_dock_item_provider_delay_items_monitor
54plank_application_dock_item_provider_get_item_list_string55plank_application_dock_item_provider_get_item_list_string
@@ -57,6 +58,7 @@
57plank_application_dock_item_provider_item_for_application58plank_application_dock_item_provider_item_for_application
58plank_application_dock_item_provider_new59plank_application_dock_item_provider_new
59plank_application_dock_item_provider_resume_items_monitor60plank_application_dock_item_provider_resume_items_monitor
61plank_application_dock_item_provider_update_suggested_apps
60plank_application_dock_item_set_urgent62plank_application_dock_item_set_urgent
61plank_application_dock_item_unity_reset63plank_application_dock_item_unity_reset
62plank_application_dock_item_unity_update64plank_application_dock_item_unity_update
@@ -679,6 +681,7 @@
679plank_transient_dock_item_construct681plank_transient_dock_item_construct
680plank_transient_dock_item_construct_with_launcher682plank_transient_dock_item_construct_with_launcher
681plank_transient_dock_item_get_type683plank_transient_dock_item_get_type
684plank_transient_dock_item_is_virtual
682plank_transient_dock_item_new685plank_transient_dock_item_new
683plank_transient_dock_item_new_with_launcher686plank_transient_dock_item_new_with_launcher
684plank_unity_add_client687plank_unity_add_client

Subscribers

People subscribed via source and target branches

to status/vote changes: