Merge lp:~ricotz/plank/dbus into lp:plank

Proposed by Rico Tzschichholz
Status: Merged
Merged at revision: 1197
Proposed branch: lp:~ricotz/plank/dbus
Merge into: lp:plank
Diff against target: 906 lines (+747/-4)
12 files modified
.bzrignore (+4/-0)
Makefile.am (+1/-0)
configure.ac (+1/-0)
docs/Makefile.am (+3/-0)
examples/Makefile.am (+48/-0)
examples/RemoteClient.vala (+65/-0)
lib/DBus/Client.vala (+307/-0)
lib/DBus/Interfaces.vala (+73/-0)
lib/DBusManager.vala (+220/-0)
lib/DockController.vala (+10/-4)
lib/Makefile.am (+3/-0)
lib/libplank.symbols (+12/-0)
To merge this branch: bzr merge lp:~ricotz/plank/dbus
Reviewer Review Type Date Requested Status
Docky Core Pending
Review via email: mp+249177@code.launchpad.net

Description of the change

Provide Client class which discovers and connect to a running dock which provides certain inferfaces to control and manipulate it.

Provide a simple example using the Client class.

To post a comment you must log in.
lp:~ricotz/plank/dbus updated
1182. By Rico Tzschichholz

items: Add boolean return-value to public DockContainer/-Provider methods

This will indicate the success or failure of the corresponding operation.

1183. By Rico Tzschichholz

items: Avoid removal-delay when unpinning an application

Remove an AppDockItem if it doesn't represent a running application and
doesn't have visible remote-info coming via LauncherEntry.

1184. By Rico Tzschichholz

po: Update translations

1185. By Rico Tzschichholz

items: It is an ApplicationDockItem, no need to use "as"

1186. By Rico Tzschichholz

renderer: Draw final internal dock-buffer on window-context at (0,0)

1187. By Rico Tzschichholz

build: Make "distcheck" work independent from originally passed confflags

1188. By Rico Tzschichholz

dockwindow: Drop hack for menu-position with gtk+ 3.15+

Reverts r1158

1189. By Rico Tzschichholz

hidemanager: Add window-dodge hide-mode

1190. By Rico Tzschichholz

po: Update translations

1191. By Rico Tzschichholz

item: Rename protected arraylist-fields *_items to *_elements

1192. By Rico Tzschichholz

dockcontainer: Rename property Elements to VisibleElements

1193. By Rico Tzschichholz

controller: Rename property Items to VisibleItems

1194. By Rico Tzschichholz

controller: Add Items property

Which actually returns a list of all items regardless their visibility.

1195. By Rico Tzschichholz

controller: Call update_items while replacing default_provider

1196. By Rico Tzschichholz

Update symbols

1197. By Rico Tzschichholz

Add DBusManager to provide some useful remotely accessible actions

Provide "net.launchpad.plank.Items" interface with "Add", "Remove",
"GetCount", "GetPersistentApplications" and "GetTransientApplications"
methods.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2014-06-02 14:18:48 +0000
3+++ .bzrignore 2015-03-16 17:58:40 +0000
4@@ -33,6 +33,9 @@
5 docs/c-doc
6 docs/vala-doc
7 docs/web-doc
8+examples/remote-client
9+examples/*.c
10+examples/*.stamp
11 lib/abi*
12 lib/*-abi
13 lib/*.c
14@@ -41,6 +44,7 @@
15 lib/*.vapi
16 lib/*.pc
17 lib/*.stamp
18+lib/DBus/*.c
19 lib/Drawing/*.c
20 lib/Factories/*.c
21 lib/Services/*.c
22
23=== modified file 'Makefile.am'
24--- Makefile.am 2015-03-11 16:25:25 +0000
25+++ Makefile.am 2015-03-16 17:58:40 +0000
26@@ -9,6 +9,7 @@
27 vapi \
28 src \
29 tests \
30+ examples \
31 $(NULL)
32
33 if HAVE_VALADOC
34
35=== modified file 'configure.ac'
36--- configure.ac 2015-01-25 19:35:00 +0000
37+++ configure.ac 2015-03-16 17:58:40 +0000
38@@ -356,6 +356,7 @@
39 docs/Makefile
40 po/Makefile.in
41 tests/Makefile
42+examples/Makefile
43 vapi/Makefile
44 ])
45
46
47=== modified file 'docs/Makefile.am'
48--- docs/Makefile.am 2015-03-11 16:25:25 +0000
49+++ docs/Makefile.am 2015-03-16 17:58:40 +0000
50@@ -17,6 +17,7 @@
51 $(NULL)
52
53 plank_doc_files = \
54+ $(top_srcdir)/lib/DBusManager.vala \
55 $(top_srcdir)/lib/DockController.vala \
56 $(top_srcdir)/lib/DockPreferences.vala \
57 $(top_srcdir)/lib/DockRenderer.vala \
58@@ -24,6 +25,8 @@
59 $(top_srcdir)/lib/HideManager.vala \
60 $(top_srcdir)/lib/PositionManager.vala \
61 $(top_builddir)/lib/Version.vala \
62+ $(top_srcdir)/lib/DBus/Client.vala \
63+ $(top_srcdir)/lib/DBus/Interfaces.vala \
64 $(top_srcdir)/lib/Drawing/AnimatedRenderer.vala \
65 $(top_srcdir)/lib/Drawing/Color.vala \
66 $(top_srcdir)/lib/Drawing/DrawingService.vala \
67
68=== added directory 'examples'
69=== added file 'examples/Makefile.am'
70--- examples/Makefile.am 1970-01-01 00:00:00 +0000
71+++ examples/Makefile.am 2015-03-16 17:58:40 +0000
72@@ -0,0 +1,48 @@
73+include $(top_srcdir)/Makefile.common
74+
75+remote_client_VALAFLAGS = \
76+ $(PLANK_CORE_VALAFLAGS) \
77+ $(top_builddir)/lib/plank.vapi \
78+ --vapidir $(top_srcdir)/vapi \
79+ -C \
80+ $(NULL)
81+
82+BUILT_SOURCES = remote_client_vala.stamp
83+
84+noinst_PROGRAMS = remote-client
85+
86+remote_client_CFLAGS = \
87+ $(PLANK_CORE_CFLAGS) \
88+ -include config.h \
89+ -w \
90+ -I$(top_builddir)/lib \
91+ $(NULL)
92+
93+remote_client_LDADD = \
94+ $(PLANK_CORE_LIBS) \
95+ $(top_builddir)/lib/libplank.la \
96+ $(NULL)
97+
98+remote_client_VALASOURCES = \
99+ RemoteClient.vala \
100+ $(NULL)
101+
102+nodist_remote_client_SOURCES = \
103+ remote_client_vala.stamp \
104+ $(remote_client_VALASOURCES:.vala=.c) \
105+ $(NULL)
106+
107+remote_client_vala.stamp: $(remote_client_VALASOURCES) $(top_builddir)/lib/plank.vapi Makefile
108+ $(AM_V_VALA)$(VALAC) \
109+ $(remote_client_VALAFLAGS) \
110+ $(filter %.vala %.c,$^)
111+ $(AM_V_at)touch $@
112+
113+CLEANFILES = \
114+ $(nodist_remote_client_SOURCES) \
115+ $(NULL)
116+
117+EXTRA_DIST = \
118+ $(remote_client_VALASOURCES) \
119+ $(NULL)
120+
121
122=== added file 'examples/RemoteClient.vala'
123--- examples/RemoteClient.vala 1970-01-01 00:00:00 +0000
124+++ examples/RemoteClient.vala 2015-03-16 17:58:40 +0000
125@@ -0,0 +1,65 @@
126+//
127+// Copyright (C) 2015 Rico Tzschichholz
128+//
129+// This program is free software: you can redistribute it and/or modify
130+// it under the terms of the GNU General Public License as published by
131+// the Free Software Foundation, either version 3 of the License, or
132+// (at your option) any later version.
133+//
134+// This program is distributed in the hope that it will be useful,
135+// but WITHOUT ANY WARRANTY; without even the implied warranty of
136+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
137+// GNU General Public License for more details.
138+//
139+// You should have received a copy of the GNU General Public License
140+// along with this program. If not, see <http://www.gnu.org/licenses/>.
141+//
142+
143+using Plank.DBus;
144+using Plank.Services;
145+
146+namespace Plank.Examples
147+{
148+ public class RemoteClient : GLib.Application
149+ {
150+ construct
151+ {
152+ application_id = "net.launchpad.plank.remote-client";
153+ flags = ApplicationFlags.FLAGS_NONE;
154+
155+ Logger.initialize ("remote-client");
156+ Logger.DisplayLevel = LogLevel.DEBUG;
157+ }
158+
159+ public override void activate ()
160+ {
161+ hold ();
162+
163+ var client = Client.get_instance ();
164+ client.proxy_changed.connect (handle_proxy_changed);
165+ }
166+
167+ void handle_proxy_changed (Client client)
168+ {
169+ if (!client.is_connected)
170+ return;
171+
172+ print ("List all persistent applications:\n");
173+ foreach (unowned string s in client.get_persistent_applications ())
174+ print (" + %s\n", s);
175+
176+ print ("List all transient applications:\n");
177+ foreach (unowned string s in client.get_transient_applications ())
178+ print (" + %s\n", s);
179+
180+ print ("\n");
181+ }
182+
183+ public static int main (string[] args)
184+ {
185+ var application = new RemoteClient ();
186+ return application.run (args);
187+ }
188+
189+ }
190+}
191
192=== added directory 'lib/DBus'
193=== added file 'lib/DBus/Client.vala'
194--- lib/DBus/Client.vala 1970-01-01 00:00:00 +0000
195+++ lib/DBus/Client.vala 2015-03-16 17:58:40 +0000
196@@ -0,0 +1,307 @@
197+//
198+// Copyright (C) 2015 Rico Tzschichholz
199+//
200+// This program is free software: you can redistribute it and/or modify
201+// it under the terms of the GNU General Public License as published by
202+// the Free Software Foundation, either version 3 of the License, or
203+// (at your option) any later version.
204+//
205+// This program is distributed in the hope that it will be useful,
206+// but WITHOUT ANY WARRANTY; without even the implied warranty of
207+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
208+// GNU General Public License for more details.
209+//
210+// You should have received a copy of the GNU General Public License
211+// along with this program. If not, see <http://www.gnu.org/licenses/>.
212+//
213+
214+namespace Plank.DBus
215+{
216+ /**
217+ * Connects to a running instance of plank via DBus and
218+ * provides remote interface to a currently runnning dock.
219+ */
220+ public class Client : GLib.Object
221+ {
222+ static Client? instance;
223+
224+ /**
225+ * Get the singleton instance of {@link Plank.DBus.Client}
226+ */
227+ public static unowned Client get_instance ()
228+ {
229+ if (instance == null)
230+ instance = new Client ();
231+
232+ return instance;
233+ }
234+
235+ /**
236+ * If the proxy interfaces for the dock are ready to be used
237+ * or were changed on runtime this signal will be emitted.
238+ */
239+ public signal void proxy_changed ();
240+
241+ /**
242+ * Whether the client is in an operatable state and connected to
243+ * a running dock
244+ */
245+ public bool is_connected {
246+ get {
247+ return (items_proxy != null);
248+ }
249+ }
250+
251+ DBusConnection? connection = null;
252+ string? client_object_path;
253+
254+ string? dock_bus_owner;
255+ string? dock_bus_name;
256+ string? dock_object_path;
257+
258+ uint dbus_dock_ping_id = 0;
259+ uint dbus_name_owner_changed_signal_id = 0;
260+
261+ ItemsIface? items_proxy = null;
262+ int items_count = int.MIN;
263+ string[]? persistent_apps_list = null;
264+ string[]? transient_apps_list = null;
265+
266+ Client ()
267+ {
268+ Object ();
269+ }
270+
271+ construct
272+ {
273+ unowned Application? application = GLib.Application.get_default ();
274+ unowned string? object_path = null;
275+
276+ if (application != null) {
277+ connection = application.get_dbus_connection ();
278+ object_path = application.get_dbus_object_path ();
279+ }
280+
281+ if (connection == null || object_path == null) {
282+ critical ("Initializing client failed");
283+ return;
284+ }
285+
286+ try {
287+ // Listen for "Ping" signals coming from docks
288+ dbus_dock_ping_id = connection.signal_subscribe (null, Plank.DBus.DOCK_INTERFACE_NAME,
289+ Plank.DBus.PING_NAME, null, null, DBusSignalFlags.NONE, handle_dock_ping);
290+ } catch (IOError e) {
291+ warning ("Could not subscribe for dock signal (%s)", e.message);
292+ }
293+
294+ dbus_name_owner_changed_signal_id = connection.signal_subscribe ("org.freedesktop.DBus", "org.freedesktop.DBus",
295+ "NameOwnerChanged", "/org/freedesktop/DBus", null, DBusSignalFlags.NONE, handle_name_owner_changed);
296+
297+ client_object_path = object_path;
298+
299+ try {
300+ // Broadcast to inform running docks
301+ connection.emit_signal (null, client_object_path, Plank.DBus.CLIENT_INTERFACE_NAME, Plank.DBus.PING_NAME, null);
302+ } catch (Error e) {
303+ warning ("Could not ping running docks (%s)", e.message);
304+ }
305+ }
306+
307+ ~Client ()
308+ {
309+ if (connection != null) {
310+ if (dbus_dock_ping_id > 0)
311+ connection.signal_unsubscribe (dbus_dock_ping_id);
312+ if (dbus_name_owner_changed_signal_id > 0)
313+ connection.signal_unsubscribe (dbus_name_owner_changed_signal_id);
314+ }
315+ }
316+
317+ void handle_dock_ping (DBusConnection connection, string sender_name, string object_path,
318+ string interface_name, string signal_name, Variant parameters)
319+ {
320+ if (dock_bus_name == null && dock_bus_name != sender_name)
321+ connect_proxies (connection, sender_name, object_path);
322+ }
323+
324+ void handle_name_owner_changed (DBusConnection connection, string sender_name, string object_path,
325+ string interface_name, string signal_name, Variant parameters)
326+ {
327+ string name, before, after;
328+ parameters.get ("(sss)", out name, out before, out after);
329+
330+ if (dock_bus_owner != null && dock_bus_owner == after)
331+ return;
332+
333+ if (name != null && name != "" && name != dock_bus_name)
334+ return;
335+
336+ if (after == null || after == "") {
337+ disconnect_proxies ();
338+ return;
339+ }
340+
341+ connect_proxies (connection, name, object_path);
342+ }
343+
344+ void connect_proxies (DBusConnection connection, string sender_name, string object_path)
345+ {
346+ debug ("Connecting and create proxies for '%s' (%s)", sender_name, object_path);
347+
348+ try {
349+ items_proxy = connection.get_proxy_sync<Plank.DBus.ItemsIface> (sender_name, object_path, DBusProxyFlags.NONE);
350+ items_proxy.changed.connect (invalidate_items_cache);
351+ dock_bus_owner = ((DBusProxy) items_proxy).get_name_owner ();
352+ dock_bus_name = sender_name;
353+ dock_object_path = object_path;
354+ } catch (Error e) {
355+ dock_bus_owner = null;
356+ dock_bus_name = null;
357+ dock_object_path = null;
358+
359+ items_proxy = null;
360+ critical ("Failed to create items proxy for '%s' (%s)", sender_name, object_path);
361+ }
362+
363+ proxy_changed ();
364+ }
365+
366+ void disconnect_proxies ()
367+ {
368+ debug ("Disconnecting from '%s' (%s)", dock_bus_name, dock_object_path);
369+
370+ dock_bus_owner = null;
371+ dock_bus_name = null;
372+ dock_object_path = null;
373+
374+ items_proxy.changed.disconnect (invalidate_items_cache);
375+ items_proxy = null;
376+ }
377+
378+
379+ void invalidate_items_cache ()
380+ {
381+ items_count = int.MIN;
382+ persistent_apps_list = null;
383+ transient_apps_list = null;
384+ }
385+
386+ /**
387+ * Add a new item for the given uri to the dock
388+ *
389+ * @param uri an URI
390+ * @return whether it was successfully added
391+ */
392+ public bool add_item (string uri)
393+ {
394+ if (items_proxy == null) {
395+ warning ("No proxy connected");
396+ return false;
397+ }
398+
399+ try {
400+ return items_proxy.add (uri);
401+ } catch (IOError e) {
402+ warning (e.message);
403+ return false;
404+ }
405+ }
406+
407+ /**
408+ * Remove an existing item for the given uri from the dock
409+ *
410+ * @param uri an URI
411+ * @return whether it was successfully removed
412+ */
413+ public bool remove_item (string uri)
414+ {
415+ if (items_proxy == null) {
416+ warning ("No proxy connected");
417+ return false;
418+ }
419+
420+ try {
421+ return items_proxy.remove (uri);
422+ } catch (IOError e) {
423+ warning (e.message);
424+ return false;
425+ }
426+ }
427+
428+ /**
429+ * Returns the number of currently visible items on the dock
430+ *
431+ * @return the item-count
432+ */
433+ public int get_items_count ()
434+ {
435+ if (items_proxy == null) {
436+ warning ("No proxy connected");
437+ return -1;
438+ }
439+
440+ try {
441+ if (items_count == int.MIN)
442+ items_count = items_proxy.get_count ();
443+ } catch (IOError e) {
444+ warning (e.message);
445+ return -1;
446+ }
447+
448+ return items_count;
449+ }
450+
451+ /**
452+ * Returns an array of uris of the persistent applications on the dock
453+ *
454+ * @return the array of uris
455+ */
456+ public unowned string[]? get_persistent_applications ()
457+ {
458+ if (items_proxy == null) {
459+ warning ("No proxy connected");
460+ return null;
461+ }
462+
463+ if (persistent_apps_list != null)
464+ return persistent_apps_list;
465+
466+ try {
467+ if (persistent_apps_list == null)
468+ persistent_apps_list = items_proxy.get_persistent_applications ();
469+ return persistent_apps_list;
470+ } catch (IOError e) {
471+ warning (e.message);
472+ }
473+
474+ return null;
475+ }
476+
477+ /**
478+ * Returns an array of uris of the transient applications on the dock
479+ *
480+ * @return the array of uris
481+ */
482+ public unowned string[]? get_transient_applications ()
483+ {
484+ if (items_proxy == null) {
485+ warning ("No proxy connected");
486+ return null;
487+ }
488+
489+ if (transient_apps_list != null)
490+ return transient_apps_list;
491+
492+ try {
493+ if (transient_apps_list == null)
494+ transient_apps_list = items_proxy.get_transient_applications ();
495+ return transient_apps_list;
496+ } catch (IOError e) {
497+ warning (e.message);
498+ }
499+
500+ return null;
501+ }
502+ }
503+}
504
505=== added file 'lib/DBus/Interfaces.vala'
506--- lib/DBus/Interfaces.vala 1970-01-01 00:00:00 +0000
507+++ lib/DBus/Interfaces.vala 2015-03-16 17:58:40 +0000
508@@ -0,0 +1,73 @@
509+//
510+// Copyright (C) 2015 Rico Tzschichholz
511+//
512+// This program is free software: you can redistribute it and/or modify
513+// it under the terms of the GNU General Public License as published by
514+// the Free Software Foundation, either version 3 of the License, or
515+// (at your option) any later version.
516+//
517+// This program is distributed in the hope that it will be useful,
518+// but WITHOUT ANY WARRANTY; without even the implied warranty of
519+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
520+// GNU General Public License for more details.
521+//
522+// You should have received a copy of the GNU General Public License
523+// along with this program. If not, see <http://www.gnu.org/licenses/>.
524+//
525+
526+namespace Plank.DBus
527+{
528+ const string PING_NAME = "Ping";
529+
530+ const string DOCK_INTERFACE_NAME = "net.launchpad.plank";
531+ const string CLIENT_INTERFACE_NAME = "net.launchpad.plank.Client";
532+
533+ /**
534+ * Provide an interface to manage items of the dock
535+ */
536+ [DBus (name = "net.launchpad.plank.Items")]
537+ interface ItemsIface : GLib.Object
538+ {
539+ /**
540+ * Emmited when items are changed
541+ */
542+ public signal void changed ();
543+
544+ /**
545+ * Add a new item for the given uri to the dock
546+ *
547+ * @param uri an URI
548+ * @return whether it was successfully added
549+ */
550+ public abstract bool add (string uri) throws GLib.IOError;
551+
552+ /**
553+ * Remove an existing item for the given uri from the dock
554+ *
555+ * @param uri an URI
556+ * @return whether it was successfully removed
557+ */
558+ public abstract bool remove (string uri) throws GLib.IOError;
559+
560+ /**
561+ * Returns the number of currently visible items on the dock
562+ *
563+ * @return the item-count
564+ */
565+ public abstract int get_count () throws GLib.IOError;
566+
567+ /**
568+ * Returns an array of uris of the persistent applications on the dock
569+ *
570+ * @return the array of uris
571+ */
572+ public abstract string[] get_persistent_applications () throws GLib.IOError;
573+
574+ /**
575+ * Returns an array of uris of the transient applications on the dock
576+ *
577+ * @return the array of uris
578+ */
579+ public abstract string[] get_transient_applications () throws GLib.IOError;
580+ }
581+}
582
583=== added file 'lib/DBusManager.vala'
584--- lib/DBusManager.vala 1970-01-01 00:00:00 +0000
585+++ lib/DBusManager.vala 2015-03-16 17:58:40 +0000
586@@ -0,0 +1,220 @@
587+//
588+// Copyright (C) 2015 Rico Tzschichholz
589+//
590+// This program is free software: you can redistribute it and/or modify
591+// it under the terms of the GNU General Public License as published by
592+// the Free Software Foundation, either version 3 of the License, or
593+// (at your option) any later version.
594+//
595+// This program is distributed in the hope that it will be useful,
596+// but WITHOUT ANY WARRANTY; without even the implied warranty of
597+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
598+// GNU General Public License for more details.
599+//
600+// You should have received a copy of the GNU General Public License
601+// along with this program. If not, see <http://www.gnu.org/licenses/>.
602+//
603+
604+using Plank.Factories;
605+using Plank.Items;
606+using Plank.Services;
607+
608+namespace Plank
609+{
610+ /**
611+ * Provide an interface to manage items of the dock
612+ */
613+ class DBusItems : GLib.Object, Plank.DBus.ItemsIface
614+ {
615+ DockController controller;
616+ uint changed_timer = 0;
617+
618+ public DBusItems (DockController _controller)
619+ {
620+ controller = _controller;
621+ controller.items_changed.connect (handle_items_changed);
622+ }
623+
624+ ~DBusItems ()
625+ {
626+ controller.items_changed.disconnect (handle_items_changed);
627+
628+ if (changed_timer > 0) {
629+ GLib.Source.remove (changed_timer);
630+ changed_timer = 0;
631+ }
632+ }
633+
634+ void handle_items_changed ()
635+ {
636+ if (changed_timer > 0)
637+ return;
638+
639+ // Fire updates with a reasonable rate
640+ changed_timer = Timeout.add (500, () => {
641+ changed_timer = 0;
642+ changed ();
643+ return false;
644+ });
645+ }
646+
647+ public bool add (string uri)
648+ {
649+ debug ("Try to remotely add '%s'", uri);
650+
651+ unowned ApplicationDockItemProvider? provider = controller.default_provider;
652+ if (provider == null)
653+ return false;
654+
655+ unowned DockItem? item = provider.item_for_uri (uri);
656+ if (item != null && item is TransientDockItem) {
657+ ((TransientDockItem) item).pin_launcher ();
658+ return true;
659+ }
660+
661+ return provider.add_item_with_uri (uri);
662+ }
663+
664+ public bool remove (string uri)
665+ {
666+ debug ("Try to remotely remove '%s'", uri);
667+
668+ unowned ApplicationDockItemProvider? provider = controller.default_provider;
669+ if (provider == null)
670+ return false;
671+
672+ unowned DockItem? item = provider.item_for_uri (uri);
673+ if (item == null)
674+ return false;
675+
676+ if (item is ApplicationDockItem) {
677+ if (!(item is TransientDockItem))
678+ ((ApplicationDockItem) item).pin_launcher ();
679+ return true;
680+ }
681+
682+ return provider.remove_item (item);
683+ }
684+
685+ public int get_count ()
686+ {
687+ return controller.VisibleItems.size;
688+ }
689+
690+ public string[] get_persistent_applications ()
691+ {
692+ Logger.verbose ("Remotely list persistent items");
693+
694+ var items = controller.Items;
695+
696+ string[] result = {};
697+ unowned string launcher;
698+ foreach (unowned DockItem item in items) {
699+ if (item is ApplicationDockItem && !(item is TransientDockItem)) {
700+ launcher = item.Launcher;
701+ if (launcher != null && launcher != "")
702+ result += launcher;
703+ }
704+ }
705+
706+ return result;
707+ }
708+
709+ public string[] get_transient_applications ()
710+ {
711+ Logger.verbose ("Remotely list transient items");
712+
713+ var items = controller.Items;
714+
715+ string[] result = {};
716+ unowned string launcher;
717+ foreach (unowned DockItem item in items) {
718+ if (item is TransientDockItem) {
719+ launcher = item.Launcher;
720+ if (launcher != null && launcher != "")
721+ result += launcher;
722+ }
723+ }
724+
725+ return result;
726+ }
727+ }
728+
729+ /**
730+ * Handles all the exported DBus functions of the dock
731+ */
732+ public class DBusManager : GLib.Object
733+ {
734+ public DockController controller { private get; construct; }
735+
736+ string? dock_object_path;
737+
738+ uint dbus_items_id = 0;
739+ uint dbus_client_ping_id = 0;
740+
741+ public DBusManager (DockController controller)
742+ {
743+ Object (controller: controller);
744+ }
745+
746+ construct
747+ {
748+ unowned Application application = Application.get_default ();
749+ unowned DBusConnection connection = application.get_dbus_connection ();
750+ unowned string? object_path = application.get_dbus_object_path ();
751+
752+ if (connection == null || object_path == null) {
753+ critical ("Not able to register our interfaces");
754+ return;
755+ }
756+
757+ // Listen for "Ping" signals coming from clients
758+ try {
759+ dbus_client_ping_id = connection.signal_subscribe (null, Plank.DBus.CLIENT_INTERFACE_NAME,
760+ Plank.DBus.PING_NAME, null, null, DBusSignalFlags.NONE, handle_client_ping);
761+ } catch (IOError e) {
762+ warning ("Could not subscribe for client signal (%s)", e.message);
763+ }
764+
765+ try {
766+ var dbus_items = new DBusItems (controller);
767+ dbus_items_id = connection.register_object<Plank.DBus.ItemsIface> (object_path, dbus_items);
768+ } catch (IOError e) {
769+ warning ("Could not register service (%s)", e.message);
770+ }
771+
772+ dock_object_path = object_path;
773+
774+ try {
775+ // Broadcast to inform running clients
776+ connection.emit_signal (null, dock_object_path, Plank.DBus.DOCK_INTERFACE_NAME, Plank.DBus.PING_NAME, null);
777+ } catch (Error e) {
778+ warning ("Could not ping running clients (%s)", e.message);
779+ }
780+ }
781+
782+ ~DBusManager ()
783+ {
784+ unowned Application application = Application.get_default ();
785+ unowned DBusConnection connection = application.get_dbus_connection ();
786+
787+ if (connection != null) {
788+ if (dbus_items_id > 0)
789+ connection.unregister_object (dbus_items_id);
790+ if (dbus_client_ping_id > 0)
791+ connection.signal_unsubscribe (dbus_client_ping_id);
792+ }
793+ }
794+
795+ void handle_client_ping (DBusConnection connection, string sender_name, string object_path,
796+ string interface_name, string signal_name, Variant parameters)
797+ {
798+ try {
799+ // Broadcast to inform running clients
800+ connection.emit_signal (null, dock_object_path, Plank.DBus.DOCK_INTERFACE_NAME, Plank.DBus.PING_NAME, null);
801+ } catch (Error e) {
802+ warning ("Could not ping running clients (%s)", e.message);
803+ }
804+ }
805+ }
806+}
807
808=== modified file 'lib/DockController.vala'
809--- lib/DockController.vala 2015-03-16 17:44:57 +0000
810+++ lib/DockController.vala 2015-03-16 17:58:40 +0000
811@@ -42,7 +42,9 @@
812 public DockRenderer renderer { get; protected set; }
813 public DockWindow window { get; protected set; }
814
815- ApplicationDockItemProvider? default_provider;
816+ public ApplicationDockItemProvider? default_provider { get; private set; }
817+
818+ DBusManager dbus_manager;
819 Gee.ArrayList<unowned DockItem> visible_items;
820 Gee.ArrayList<unowned DockItem> items;
821
822@@ -90,6 +92,8 @@
823
824 prefs.notify["PinnedOnly"].connect (update_default_provider);
825
826+ dbus_manager = new DBusManager (this);
827+
828 position_manager = new PositionManager (this);
829 drag_manager = new DragManager (this);
830 hide_manager = new HideManager (this);
831@@ -135,12 +139,12 @@
832 return;
833
834 Logger.verbose ("DockController.add_default_provider ()");
835- default_provider = get_default_provider ();
836+ default_provider = create_default_provider ();
837
838 add_item (default_provider);
839 }
840
841- ApplicationDockItemProvider get_default_provider ()
842+ ApplicationDockItemProvider create_default_provider ()
843 {
844 ApplicationDockItemProvider provider;
845
846@@ -169,7 +173,7 @@
847 return;
848
849 var old_default_provider = default_provider;
850- default_provider = get_default_provider ();
851+ default_provider = create_default_provider ();
852 default_provider.prepare ();
853 replace_item (default_provider, old_default_provider);
854
855@@ -275,6 +279,8 @@
856 position_manager.update_regions ();
857 }
858 window.update_icon_regions ();
859+
860+ items_changed (added, removed);
861 }
862
863 void handle_item_positions_changed (DockContainer provider, Gee.List<unowned DockElement> moved_items)
864
865=== modified file 'lib/Makefile.am'
866--- lib/Makefile.am 2015-01-22 10:24:51 +0000
867+++ lib/Makefile.am 2015-03-16 17:58:40 +0000
868@@ -61,12 +61,15 @@
869 $(NULL)
870
871 libplank_la_VALASOURCES = \
872+ DBusManager.vala \
873 DockController.vala \
874 DockPreferences.vala \
875 DockRenderer.vala \
876 DragManager.vala \
877 HideManager.vala \
878 PositionManager.vala \
879+ DBus/Client.vala \
880+ DBus/Interfaces.vala \
881 Drawing/AnimatedRenderer.vala \
882 Drawing/Color.vala \
883 Drawing/DrawingService.vala \
884
885=== modified file 'lib/libplank.symbols'
886--- lib/libplank.symbols 2015-03-16 17:47:28 +0000
887+++ lib/libplank.symbols 2015-03-16 17:58:40 +0000
888@@ -1,6 +1,18 @@
889+plank_dbus_client_add_item
890+plank_dbus_client_get_instance
891+plank_dbus_client_get_is_connected
892+plank_dbus_client_get_items_count
893+plank_dbus_client_get_persistent_applications
894+plank_dbus_client_get_transient_applications
895+plank_dbus_client_get_type
896+plank_dbus_client_remove_item
897+plank_dbus_manager_construct
898+plank_dbus_manager_get_type
899+plank_dbus_manager_new
900 plank_dock_controller_add_default_provider
901 plank_dock_controller_construct
902 plank_dock_controller_get_config_folder
903+plank_dock_controller_get_default_provider
904 plank_dock_controller_get_drag_manager
905 plank_dock_controller_get_hide_manager
906 plank_dock_controller_get_Items

Subscribers

People subscribed via source and target branches

to status/vote changes: