Merge lp:~3v1n0/unity/dbus-indicators-proxy into lp:unity
- dbus-indicators-proxy
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Marco Trevisan (Treviño) |
Approved revision: | no longer in the source branch. |
Merged at revision: | 2133 |
Proposed branch: | lp:~3v1n0/unity/dbus-indicators-proxy |
Merge into: | lp:unity |
Prerequisite: | lp:~3v1n0/unity/indicators-p |
Diff against target: |
1049 lines (+260/-524) 7 files modified
UnityCore/DBusIndicators.cpp (+202/-450) UnityCore/DBusIndicators.h (+2/-8) UnityCore/GLibDBusProxy.cpp (+51/-55) UnityCore/GLibDBusProxy.h (+2/-2) UnityCore/Indicators.cpp (+2/-5) UnityCore/Indicators.h (+1/-1) plugins/unityshell/src/PanelView.cpp (+0/-3) |
To merge this branch: | bzr merge lp:~3v1n0/unity/dbus-indicators-proxy |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michal Hruby (community) | Approve | ||
Review via email: mp+97328@code.launchpad.net |
Commit message
DBusIndicators code rewritten to use glib::DBusProxy instead of raw gdbus calls
Description of the change
DBusIndicators code rewritten to use glib::DBusProxy instead of raw gdbus calls.
The code now is more simple, clean and C++ conformant. Also, now we always make sure that the panel is launched when it is not available (before this was not happening in some corner cases).
Tests are covered by lp:~3v1n0/unity/indicators-tests
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> 787 + bool auto_reconnect)
>
> What are you actually trying to achieve with this? GDBusProxy automatically
> reconnects itself if you construct it using a known service name (as opposed
> to unique bus address). Therefore it seems redundant to me.
Yeah, I know, but it doesn't work here for the reason we discovered...
> If you want to make sure that a service is alive, all you need to do is watch
> changes to the connected state and if it disconnects, just call any method
> from given interface and that will dbus-activate the service again.
That's what I've tried to do, but it doesn't work here because glib::DBusProxy notify us about the disconnection event when actually the name has vanished, but the proxy is not disconnected yet.
Adding a timeout fixes it, but we should handle that in a better way.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> 787 + bool auto_reconnect)
>
> What are you actually trying to achieve with this? GDBusProxy automatically
> reconnects itself if you construct it using a known service name (as opposed
> to unique bus address). Therefore it seems redundant to me.
Ok this is now fixed into lp:~3v1n0/unity/dbus-indicators-proxy that will merge in this one as you know ;)
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> Ok this is now fixed into lp:~3v1n0/unity/dbus-indicators-proxy that will
> merge in this one as you know ;)
Ops, I meant lp:~3v1n0/unity/dbus-proxy-name-owner-watch
Unity Merger (unity-merger) wrote : | # |
The prerequisite lp:~3v1n0/unity/indicators-p has not yet been merged into lp:unity.
Michal Hruby (mhr3) wrote : | # |
Overall I'm liking this a lot - mostly because of "(+234/-516)" :) I have some concerns though:
269 + RequestSyncAll();
270 +
271 + reconnect_
272 + auto self = static_
273 +
274 + if (!self-
275 + {
276 + self->RequestSy
277 + return TRUE;
278 + }
279 +
280 + self->reconnect
281 + return FALSE;
282 + }, this);
Are you sure you want to call RequestSyncAll also outside of the lambda expression? Plus you should be checking if reconnect_
146 + struct CallData
147 + {
148 + Impl* self;
149 + GVariant *parameters;
150 + };
I'm not really liking this, it's unclear who owns the variant (or rather why isn't it unreffed) - using our Variant wrapper should fix this. What's worse is that the CallData can be alive even after the Impl instance is destroyed which can lead to a crash.
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> Overall I'm liking this a lot - mostly because of "(+234/-516)" :)
Ehehe ;)
> Are you sure you want to call RequestSyncAll also outside of the lambda
> expression?
Yes. Because after we get a disconnection event we can try immediately to restore the service, it that fails we retry every 1 second. This assures that if we have a valid u-p-s running or in the system as well, we use it!
> Plus you should be checking if reconnect_
> calling g_timeout_add...
Yes, sure.
> 146 + struct CallData
> 147 + {
> 148 + Impl* self;
> 149 + GVariant *parameters;
> 150 + };
>
> I'm not really liking this, it's unclear who owns the variant (or rather why
> isn't it unreffed) - using our Variant wrapper should fix this.
Well, as you know the proxy handles it, so I didn't ref/unreff'ed it... But I'll move to glib::Variant.
> What's worse
> is that the CallData can be alive even after the Impl instance is destroyed
> which can lead to a crash.
This should be very unlikely using an idle, but I'll make that more safe as well.
Unity Merger (unity-merger) wrote : | # |
No proposals found for merge of lp:~3v1n0/unity/indicators-p into lp:unity.
Preview Diff
1 | === modified file 'UnityCore/DBusIndicators.cpp' |
2 | --- UnityCore/DBusIndicators.cpp 2012-03-20 10:16:27 +0000 |
3 | +++ UnityCore/DBusIndicators.cpp 2012-03-20 10:16:27 +0000 |
4 | @@ -1,6 +1,6 @@ |
5 | // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- |
6 | /* |
7 | - * Copyright (C) 2010, 2011 Canonical Ltd |
8 | + * Copyright (C) 2010-2012 Canonical Ltd |
9 | * |
10 | * This program is free software: you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 3 as |
12 | @@ -18,18 +18,11 @@ |
13 | * Marco Trevisan (Treviño) <3v1n0@ubuntu.com> |
14 | */ |
15 | |
16 | +#include "config.h" |
17 | #include "DBusIndicators.h" |
18 | |
19 | -#include <algorithm> |
20 | -#include <iostream> |
21 | - |
22 | -#include <gio/gio.h> |
23 | - |
24 | -#include <X11/Xlib.h> |
25 | - |
26 | -#include "config.h" |
27 | -#include "GLibSignal.h" |
28 | #include "GLibWrapper.h" |
29 | +#include "GLibDBusProxy.h" |
30 | #include "Variant.h" |
31 | |
32 | namespace unity |
33 | @@ -39,87 +32,33 @@ |
34 | |
35 | namespace |
36 | { |
37 | -// This anonymous namespace holds the DBus callback methods. |
38 | - |
39 | -struct SyncData |
40 | -{ |
41 | - SyncData(DBusIndicators::Impl* self_) |
42 | - : self(self_) |
43 | - , cancel(g_cancellable_new()) |
44 | - { |
45 | - } |
46 | - |
47 | - ~SyncData() |
48 | - { |
49 | - if (cancel) |
50 | - { |
51 | - g_cancellable_cancel(cancel); |
52 | - g_object_unref(cancel); |
53 | - } |
54 | - } |
55 | - |
56 | - void SyncComplete() |
57 | - { |
58 | - if (cancel) |
59 | - { |
60 | - g_object_unref(cancel); |
61 | - } |
62 | - cancel = NULL; |
63 | - } |
64 | - |
65 | - DBusIndicators::Impl* self; |
66 | - GCancellable* cancel; |
67 | -}; |
68 | - |
69 | -typedef boost::shared_ptr<SyncData> SyncDataPtr; |
70 | - |
71 | -const char* const S_NAME = "com.canonical.Unity.Panel.Service"; |
72 | -const char* const S_PATH = "/com/canonical/Unity/Panel/Service"; |
73 | -const char* const S_IFACE = "com.canonical.Unity.Panel.Service"; |
74 | - |
75 | -struct ShowEntryData |
76 | -{ |
77 | - glib::Object<GDBusProxy> proxy; |
78 | - std::string entry_id; |
79 | - guint xid; |
80 | - int x; |
81 | - int y; |
82 | - guint button; |
83 | - guint timestamp; |
84 | -}; |
85 | - |
86 | -bool run_local_panel_service(); |
87 | -gboolean reconnect_to_service(gpointer data); |
88 | -void on_proxy_ready_cb(GObject* source, GAsyncResult* res, gpointer data); |
89 | -void request_sync(GDBusProxy* proxy, const char* method, GVariant* name, |
90 | - SyncData* data); |
91 | -void on_sync_ready_cb(GObject* source, GAsyncResult* res, gpointer data); |
92 | - |
93 | -bool send_show_entry(ShowEntryData* data); |
94 | -bool send_show_appmenu(ShowEntryData* data); |
95 | - |
96 | +const std::string SERVICE_NAME("com.canonical.Unity.Panel.Service"); |
97 | +const std::string SERVICE_PATH("/com/canonical/Unity/Panel/Service"); |
98 | +const std::string SERVICE_IFACE("com.canonical.Unity.Panel.Service"); |
99 | } // anonymous namespace |
100 | |
101 | |
102 | -// Connects to the remote panel service (unity-panel-service) and translates |
103 | -// that into something that the panel can show |
104 | +/* Connects to the remote panel service (unity-panel-service) and translates |
105 | + * that into something that the panel can show */ |
106 | class DBusIndicators::Impl |
107 | { |
108 | public: |
109 | Impl(DBusIndicators* owner); |
110 | + ~Impl(); |
111 | |
112 | - void OnRemoteProxyReady(GDBusProxy* proxy); |
113 | - void Reconnect(); |
114 | + void CheckLocalService(); |
115 | void RequestSyncAll(); |
116 | void RequestSyncIndicator(std::string const& name); |
117 | - void Sync(GVariant* args, SyncData* data); |
118 | - void SyncGeometries(std::string const& name, |
119 | - EntryLocationMap const& locations); |
120 | - void OnProxyNameOwnerChanged(GDBusProxy* proxy, GParamSpec* pspec); |
121 | - void OnProxySignalReceived(GDBusProxy* proxy, |
122 | - char* sender_name, |
123 | - char* signal_name_, |
124 | - GVariant* parameters); |
125 | + void Sync(GVariant* args); |
126 | + void SyncGeometries(std::string const& name, EntryLocationMap const& locations); |
127 | + |
128 | + void OnConnected(); |
129 | + void OnDisconnected(); |
130 | + |
131 | + void OnReSync(GVariant* parameters); |
132 | + void OnEntryActivated(GVariant* parameters); |
133 | + void OnEntryActivatedRequest(GVariant* parameters); |
134 | + void OnEntryShowNowChanged(GVariant* parameters); |
135 | |
136 | virtual void OnEntryScroll(std::string const& entry_id, int delta); |
137 | virtual void OnEntryShowMenu(std::string const& entry_id, unsigned int xid, |
138 | @@ -130,16 +69,17 @@ |
139 | virtual void OnShowAppMenu(unsigned int xid, int x, int y, |
140 | unsigned int timestamp); |
141 | |
142 | - std::string name() const; |
143 | - std::string owner_name() const; |
144 | - bool using_local_service() const; |
145 | + struct CallData |
146 | + { |
147 | + Impl* self; |
148 | + glib::Variant parameters; |
149 | + }; |
150 | |
151 | DBusIndicators* owner_; |
152 | - glib::Object<GDBusProxy> proxy_; |
153 | - typedef std::vector<SyncDataPtr> PendingSyncs; |
154 | - PendingSyncs pending_syncs_; |
155 | - |
156 | - glib::SignalManager signal_manager_; |
157 | + guint reconnect_timeout_id_; |
158 | + guint show_entry_idle_id_; |
159 | + guint show_appmenu_idle_id_; |
160 | + glib::DBusProxy gproxy_; |
161 | std::map<std::string, EntryLocationMap> cached_locations_; |
162 | }; |
163 | |
164 | @@ -147,62 +87,149 @@ |
165 | // Public Methods |
166 | DBusIndicators::Impl::Impl(DBusIndicators* owner) |
167 | : owner_(owner) |
168 | -{ |
169 | - Reconnect(); |
170 | -} |
171 | - |
172 | -void DBusIndicators::Impl::Reconnect() |
173 | -{ |
174 | - g_spawn_command_line_sync("killall -9 unity-panel-service", |
175 | - NULL, NULL, NULL, NULL); |
176 | - |
177 | + , reconnect_timeout_id_(0) |
178 | + , show_entry_idle_id_(0) |
179 | + , show_appmenu_idle_id_(0) |
180 | + , gproxy_(SERVICE_NAME, SERVICE_PATH, SERVICE_IFACE, |
181 | + G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) |
182 | +{ |
183 | + gproxy_.Connect("ReSync", sigc::mem_fun(this, &DBusIndicators::Impl::OnReSync)); |
184 | + gproxy_.Connect("EntryActivated", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryActivated)); |
185 | + gproxy_.Connect("EntryActivateRequest", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryActivatedRequest)); |
186 | + gproxy_.Connect("EntryShowNowChanged", sigc::mem_fun(this, &DBusIndicators::Impl::OnEntryShowNowChanged)); |
187 | + |
188 | + gproxy_.connected.connect(sigc::mem_fun(this, &DBusIndicators::Impl::OnConnected)); |
189 | + gproxy_.disconnected.connect(sigc::mem_fun(this, &DBusIndicators::Impl::OnDisconnected)); |
190 | + |
191 | + CheckLocalService(); |
192 | +} |
193 | + |
194 | +DBusIndicators::Impl::~Impl() |
195 | +{ |
196 | + if (reconnect_timeout_id_) |
197 | + g_source_remove(reconnect_timeout_id_); |
198 | + |
199 | + if (show_entry_idle_id_) |
200 | + g_source_remove(show_entry_idle_id_); |
201 | + |
202 | + if (show_appmenu_idle_id_) |
203 | + g_source_remove(show_appmenu_idle_id_); |
204 | +} |
205 | + |
206 | +void DBusIndicators::Impl::CheckLocalService() |
207 | +{ |
208 | if (g_getenv("PANEL_USE_LOCAL_SERVICE")) |
209 | { |
210 | - run_local_panel_service(); |
211 | - g_timeout_add_seconds(1, reconnect_to_service, this); |
212 | - } |
213 | - else |
214 | - { |
215 | - // We want to grab the Panel Service object. This is async, which is fine |
216 | - reconnect_to_service(this); |
217 | - } |
218 | -} |
219 | - |
220 | -void DBusIndicators::Impl::OnRemoteProxyReady(GDBusProxy* proxy) |
221 | -{ |
222 | - if (proxy_) |
223 | - { |
224 | - // We've been connected before; We don't need new proxy, just continue |
225 | - // rocking with the old one. |
226 | - g_object_unref(proxy); |
227 | - } |
228 | - else |
229 | - { |
230 | - proxy_ = proxy; |
231 | - // Connect to interesting signals |
232 | - signal_manager_.Add(new glib::Signal<void, GDBusProxy*, char*, char*, GVariant*> |
233 | - (proxy_, "g-signal", sigc::mem_fun(this, &Impl::OnProxySignalReceived))); |
234 | - |
235 | - signal_manager_.Add(new glib::Signal<void, GDBusProxy*, GParamSpec*> |
236 | - (proxy_, "notify::g-name-owner", sigc::mem_fun(this, &Impl::OnProxyNameOwnerChanged))); |
237 | - } |
238 | - RequestSyncAll(); |
239 | + glib::Error error; |
240 | + |
241 | + g_spawn_command_line_sync("killall -9 unity-panel-service", |
242 | + nullptr, nullptr, nullptr, nullptr); |
243 | + |
244 | + // This is obviously hackish, but this part of the code is mostly hackish... |
245 | + // Let's attempt to run it from where we expect it to be |
246 | + std::string cmd = PREFIXDIR + std::string("/lib/unity/unity-panel-service"); |
247 | + std::cerr << "\nWARNING: Couldn't load panel from installed services, " |
248 | + << "so trying to load panel from known location: " |
249 | + << cmd << "\n"; |
250 | + |
251 | + g_spawn_command_line_async(cmd.c_str(), &error); |
252 | + |
253 | + if (error) |
254 | + { |
255 | + std::cerr << "\nWARNING: Unable to launch remote service manually: " |
256 | + << error.Message() << "\n"; |
257 | + } |
258 | + } |
259 | +} |
260 | + |
261 | +void DBusIndicators::Impl::OnConnected() |
262 | +{ |
263 | + RequestSyncAll(); |
264 | +} |
265 | + |
266 | +void DBusIndicators::Impl::OnDisconnected() |
267 | +{ |
268 | + for (auto indicator : owner_->GetIndicators()) |
269 | + { |
270 | + owner_->RemoveIndicator(indicator->name()); |
271 | + } |
272 | + |
273 | + cached_locations_.clear(); |
274 | + |
275 | + CheckLocalService(); |
276 | + RequestSyncAll(); |
277 | + |
278 | + if (reconnect_timeout_id_) |
279 | + g_source_remove(reconnect_timeout_id_); |
280 | + |
281 | + reconnect_timeout_id_ = g_timeout_add_seconds(1, [](gpointer data) -> gboolean { |
282 | + auto self = static_cast<DBusIndicators::Impl*>(data); |
283 | + |
284 | + if (!self->gproxy_.IsConnected()) |
285 | + { |
286 | + self->RequestSyncAll(); |
287 | + return TRUE; |
288 | + } |
289 | + |
290 | + self->reconnect_timeout_id_ = 0; |
291 | + return FALSE; |
292 | + }, this); |
293 | +} |
294 | + |
295 | +void DBusIndicators::Impl::OnReSync(GVariant* parameters) |
296 | +{ |
297 | + glib::String indicator_name; |
298 | + g_variant_get(parameters, "(s)", &indicator_name); |
299 | + |
300 | + if (indicator_name && !indicator_name.Str().empty()) |
301 | + { |
302 | + RequestSyncIndicator(indicator_name); |
303 | + } |
304 | + else |
305 | + { |
306 | + RequestSyncAll(); |
307 | + } |
308 | +} |
309 | + |
310 | +void DBusIndicators::Impl::OnEntryActivated(GVariant* parameters) |
311 | +{ |
312 | + glib::String entry_name; |
313 | + nux::Rect geo; |
314 | + g_variant_get(parameters, "(s(iiuu))", &entry_name, &geo.x, &geo.y, &geo.width, &geo.height); |
315 | + |
316 | + if (entry_name) |
317 | + owner_->ActivateEntry(entry_name, geo); |
318 | +} |
319 | + |
320 | +void DBusIndicators::Impl::OnEntryActivatedRequest(GVariant* parameters) |
321 | +{ |
322 | + glib::String entry_name; |
323 | + g_variant_get(parameters, "(s)", &entry_name); |
324 | + |
325 | + if (entry_name) |
326 | + owner_->on_entry_activate_request.emit(entry_name); |
327 | +} |
328 | + |
329 | +void DBusIndicators::Impl::OnEntryShowNowChanged(GVariant* parameters) |
330 | +{ |
331 | + glib::String entry_name; |
332 | + gboolean show_now; |
333 | + g_variant_get(parameters, "(sb)", &entry_name, &show_now); |
334 | + |
335 | + if (entry_name) |
336 | + owner_->SetEntryShowNow(entry_name, show_now); |
337 | } |
338 | |
339 | void DBusIndicators::Impl::RequestSyncAll() |
340 | { |
341 | - SyncDataPtr data(new SyncData(this)); |
342 | - pending_syncs_.push_back(data); |
343 | - request_sync(proxy_, "Sync", NULL, data.get()); |
344 | + gproxy_.Call("Sync", nullptr, sigc::mem_fun(this, &DBusIndicators::Impl::Sync)); |
345 | } |
346 | |
347 | void DBusIndicators::Impl::RequestSyncIndicator(std::string const& name) |
348 | { |
349 | - SyncDataPtr data(new SyncData(this)); |
350 | - pending_syncs_.push_back(data); |
351 | - // The ownership of this variant is taken by the g_dbus_proxy_call. |
352 | - GVariant* v_name = g_variant_new("(s)", name.c_str()); |
353 | - request_sync(proxy_, "SyncOne", v_name, data.get()); |
354 | + GVariant* parameter = g_variant_new("(s)", name.c_str()); |
355 | + |
356 | + gproxy_.Call("SyncOne", parameter, sigc::mem_fun(this, &DBusIndicators::Impl::Sync)); |
357 | } |
358 | |
359 | |
360 | @@ -216,16 +243,20 @@ |
361 | // We have to do this because on certain systems X won't have time to |
362 | // respond to our request for XUngrabPointer and this will cause the |
363 | // menu not to show |
364 | - auto data = new ShowEntryData(); |
365 | - data->proxy = proxy_; |
366 | - data->entry_id = entry_id; |
367 | - data->xid = xid; |
368 | - data->x = x; |
369 | - data->y = y; |
370 | - data->button = button; |
371 | - data->timestamp = timestamp; |
372 | - |
373 | - g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc) send_show_entry, data, NULL); |
374 | + auto data = new CallData(); |
375 | + data->self = this; |
376 | + data->parameters = g_variant_new("(suiiuu)", entry_id.c_str(), xid, x, y, |
377 | + button, timestamp); |
378 | + |
379 | + if (show_entry_idle_id_) |
380 | + g_source_remove(show_entry_idle_id_); |
381 | + |
382 | + show_entry_idle_id_ = g_idle_add_full (G_PRIORITY_DEFAULT, [] (gpointer data) -> gboolean { |
383 | + auto call_data = static_cast<CallData*>(data); |
384 | + call_data->self->gproxy_.Call("ShowEntry", call_data->parameters); |
385 | + |
386 | + return FALSE; |
387 | + }, data, [] (gpointer data) { delete static_cast<CallData*>(data); }); |
388 | } |
389 | |
390 | void DBusIndicators::Impl::OnShowAppMenu(unsigned int xid, int x, int y, |
391 | @@ -236,43 +267,43 @@ |
392 | // We have to do this because on certain systems X won't have time to |
393 | // respond to our request for XUngrabPointer and this will cause the |
394 | // menu not to show |
395 | - auto data = new ShowEntryData(); |
396 | - data->proxy = proxy_; |
397 | - data->xid = xid; |
398 | - data->x = x; |
399 | - data->y = y; |
400 | - data->timestamp = timestamp; |
401 | - |
402 | - g_idle_add_full (G_PRIORITY_DEFAULT, (GSourceFunc) send_show_appmenu, data, NULL); |
403 | + auto data = new CallData(); |
404 | + data->self = this; |
405 | + data->parameters = g_variant_new("(uiiu)", xid, x, y, timestamp); |
406 | + |
407 | + if (show_appmenu_idle_id_) |
408 | + g_source_remove(show_appmenu_idle_id_); |
409 | + |
410 | + show_appmenu_idle_id_ = g_idle_add_full (G_PRIORITY_DEFAULT, [] (gpointer data) -> gboolean { |
411 | + auto call_data = static_cast<CallData*>(data); |
412 | + call_data->self->gproxy_.Call("ShowAppMenu", call_data->parameters); |
413 | + |
414 | + return FALSE; |
415 | + }, data, [] (gpointer data) { delete static_cast<CallData*>(data); }); |
416 | } |
417 | |
418 | void DBusIndicators::Impl::OnEntrySecondaryActivate(std::string const& entry_id, |
419 | unsigned int timestamp) |
420 | { |
421 | - g_dbus_proxy_call(proxy_, "SecondaryActivateEntry", |
422 | - g_variant_new("(su)", entry_id.c_str(), timestamp), |
423 | - G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); |
424 | + gproxy_.Call("SecondaryActivateEntry", g_variant_new("(su)", entry_id.c_str(), timestamp)); |
425 | } |
426 | |
427 | void DBusIndicators::Impl::OnEntryScroll(std::string const& entry_id, int delta) |
428 | { |
429 | - g_dbus_proxy_call(proxy_, "ScrollEntry", |
430 | - g_variant_new("(si)", entry_id.c_str(), delta), |
431 | - G_DBUS_CALL_FLAGS_NONE, |
432 | - -1, NULL, NULL, NULL); |
433 | + gproxy_.Call("ScrollEntry", g_variant_new("(si)", entry_id.c_str(), delta)); |
434 | } |
435 | |
436 | -void DBusIndicators::Impl::Sync(GVariant* args, SyncData* data) |
437 | +void DBusIndicators::Impl::Sync(GVariant* args) |
438 | { |
439 | - GVariantIter* iter = NULL; |
440 | - gchar* name_hint = NULL; |
441 | - gchar* indicator_id = NULL; |
442 | - gchar* entry_id = NULL; |
443 | - gchar* label = NULL; |
444 | + GVariantIter* iter = nullptr; |
445 | + gchar* name_hint = nullptr; |
446 | + gchar* indicator_id = nullptr; |
447 | + gchar* entry_id = nullptr; |
448 | + gchar* label = nullptr; |
449 | gboolean label_sensitive = false; |
450 | gboolean label_visible = false; |
451 | guint32 image_type = 0; |
452 | - gchar* image_data = NULL; |
453 | + gchar* image_data = nullptr; |
454 | gboolean image_sensitive = false; |
455 | gboolean image_visible = false; |
456 | gint32 priority = -1; |
457 | @@ -308,7 +339,7 @@ |
458 | |
459 | Indicator::Entries& entries = indicators[indicator]; |
460 | |
461 | - // NULL entries (entry_id == "") are empty indicators. |
462 | + // Null entries (entry_id == "") are empty indicators. |
463 | if (entry != "") |
464 | { |
465 | Entry::Ptr e = indicator->GetEntry(entry_id); |
466 | @@ -343,20 +374,6 @@ |
467 | i->first->Sync(indicators[i->first]); |
468 | } |
469 | |
470 | - // Clean up the SyncData. NOTE: don't use find when passing in a raw |
471 | - // pointer due to explicit construction of the shared pointer. Could write |
472 | - // a predicate, but often a for loop is easier to understand. |
473 | - data->SyncComplete(); |
474 | - for (PendingSyncs::iterator i = pending_syncs_.begin(), end = pending_syncs_.end(); |
475 | - i != end; ++i) |
476 | - { |
477 | - if (i->get() == data) |
478 | - { |
479 | - pending_syncs_.erase(i); |
480 | - break; |
481 | - } |
482 | - } |
483 | - |
484 | // Notify listeners we have new data |
485 | owner_->on_synced.emit(); |
486 | } |
487 | @@ -364,7 +381,7 @@ |
488 | void DBusIndicators::Impl::SyncGeometries(std::string const& name, |
489 | EntryLocationMap const& locations) |
490 | { |
491 | - if (!proxy_) |
492 | + if (!gproxy_.IsConnected()) |
493 | return; |
494 | |
495 | GVariantBuilder b; |
496 | @@ -414,116 +431,17 @@ |
497 | } |
498 | |
499 | g_variant_builder_close(&b); |
500 | - g_dbus_proxy_call(proxy_, "SyncGeometries", |
501 | - g_variant_builder_end(&b), |
502 | - G_DBUS_CALL_FLAGS_NONE, |
503 | - -1, |
504 | - NULL, |
505 | - NULL, |
506 | - NULL); |
507 | |
508 | + gproxy_.Call("SyncGeometries", g_variant_builder_end(&b)); |
509 | cached_loc = locations; |
510 | } |
511 | |
512 | -std::string DBusIndicators::Impl::name() const |
513 | -{ |
514 | - glib::String name; |
515 | - g_object_get(proxy_, "g-name", &name, NULL); |
516 | - return name.Str(); |
517 | -} |
518 | - |
519 | -std::string DBusIndicators::Impl::owner_name() const |
520 | -{ |
521 | - glib::String owner_name; |
522 | - g_object_get(proxy_, "g-name-owner", &owner_name, NULL); |
523 | - return owner_name.Str(); |
524 | -} |
525 | - |
526 | -bool DBusIndicators::Impl::using_local_service() const |
527 | -{ |
528 | - return g_getenv("PANEL_USE_LOCAL_SERVICE") != NULL; |
529 | -} |
530 | - |
531 | -void DBusIndicators::Impl::OnProxyNameOwnerChanged(GDBusProxy* proxy, |
532 | - GParamSpec* pspec) |
533 | -{ |
534 | - char* name_owner = g_dbus_proxy_get_name_owner(proxy); |
535 | - |
536 | - if (name_owner == NULL) |
537 | - { |
538 | - for (auto indicator : owner_->GetIndicators()) |
539 | - { |
540 | - owner_->RemoveIndicator(indicator->name()); |
541 | - } |
542 | - |
543 | - // The panel service has stopped for some reason. Restart it if not in |
544 | - // dev mode |
545 | - if (!g_getenv("UNITY_DEV_MODE")) |
546 | - Reconnect(); |
547 | - } |
548 | - |
549 | - g_free(name_owner); |
550 | -} |
551 | - |
552 | -void DBusIndicators::Impl::OnProxySignalReceived(GDBusProxy* proxy, |
553 | - char* sender_name, |
554 | - char* signal_name_, |
555 | - GVariant* parameters) |
556 | -{ |
557 | - std::string signal_name(signal_name_); |
558 | - if (signal_name == "EntryActivated") |
559 | - { |
560 | - glib::String entry_name; |
561 | - nux::Rect geo; |
562 | - g_variant_get(parameters, "(s(iiuu))", &entry_name, &geo.x, &geo.y, &geo.width, &geo.height); |
563 | - |
564 | - if (entry_name) |
565 | - { |
566 | - owner_->ActivateEntry(entry_name.Str(), geo); |
567 | - } |
568 | - } |
569 | - else if (signal_name == "EntryActivateRequest") |
570 | - { |
571 | - const char* entry_name = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); |
572 | - if (entry_name) |
573 | - { |
574 | - owner_->on_entry_activate_request.emit(entry_name); |
575 | - } |
576 | - } |
577 | - else if (signal_name == "ReSync") |
578 | - { |
579 | - const char* id = g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL); |
580 | - bool sync_one = !g_strcmp0(id, "") == 0; |
581 | - |
582 | - if (sync_one) |
583 | - { |
584 | - RequestSyncIndicator(id); |
585 | - } |
586 | - else |
587 | - { |
588 | - RequestSyncAll(); |
589 | - } |
590 | - } |
591 | - else if (signal_name == "EntryShowNowChanged") |
592 | - { |
593 | - gchar* id = NULL; |
594 | - gboolean show_now; |
595 | - |
596 | - g_variant_get(parameters, "(sb)", &id, &show_now); |
597 | - owner_->SetEntryShowNow(id, show_now); |
598 | - |
599 | - g_free(id); |
600 | - } |
601 | -} |
602 | - |
603 | DBusIndicators::DBusIndicators() |
604 | : pimpl(new Impl(this)) |
605 | {} |
606 | |
607 | DBusIndicators::~DBusIndicators() |
608 | -{ |
609 | - delete pimpl; |
610 | -} |
611 | +{} |
612 | |
613 | void DBusIndicators::SyncGeometries(std::string const& name, |
614 | EntryLocationMap const& locations) |
615 | @@ -555,171 +473,5 @@ |
616 | pimpl->OnShowAppMenu(xid, x, y, timestamp); |
617 | } |
618 | |
619 | -std::string DBusIndicators::name() const |
620 | -{ |
621 | - return pimpl->name(); |
622 | -} |
623 | - |
624 | -std::string DBusIndicators::owner_name() const |
625 | -{ |
626 | - return pimpl->owner_name(); |
627 | -} |
628 | - |
629 | -bool DBusIndicators::using_local_service() const |
630 | -{ |
631 | - return pimpl->using_local_service(); |
632 | -} |
633 | - |
634 | - |
635 | -namespace |
636 | -{ |
637 | - |
638 | -// Initialise DBus for the panel service, and let us know when it is |
639 | -// ready. The unused bool return is to fit with the GSourceFunc. |
640 | -gboolean reconnect_to_service(gpointer data) |
641 | -{ |
642 | - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, |
643 | - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, |
644 | - NULL, |
645 | - S_NAME, |
646 | - S_PATH, |
647 | - S_IFACE, |
648 | - NULL, |
649 | - on_proxy_ready_cb, |
650 | - data); |
651 | - return false; |
652 | -} |
653 | - |
654 | -// Make sure the proxy object exists and has a name, and if so, pass |
655 | -// that on to the DBusIndicators. |
656 | -void on_proxy_ready_cb(GObject* source, GAsyncResult* res, gpointer data) |
657 | -{ |
658 | - DBusIndicators::Impl* remote = reinterpret_cast<DBusIndicators::Impl*>(data); |
659 | - GError* error = NULL; |
660 | - GDBusProxy* proxy = g_dbus_proxy_new_for_bus_finish(res, &error); |
661 | - |
662 | - static bool force_tried = false; |
663 | - |
664 | - char* name_owner; |
665 | - if (G_IS_DBUS_PROXY(proxy) && (name_owner = g_dbus_proxy_get_name_owner(proxy))) |
666 | - { |
667 | - remote->OnRemoteProxyReady(G_DBUS_PROXY(proxy)); |
668 | - g_free(name_owner); |
669 | - return; |
670 | - } |
671 | - else |
672 | - { |
673 | - if (force_tried) |
674 | - { |
675 | - g_warning("WARNING: Unable to connect to the unity-panel-service %s", |
676 | - error ? error->message : "Unknown"); |
677 | - if (error) |
678 | - g_error_free(error); |
679 | - } |
680 | - else |
681 | - { |
682 | - force_tried = true; |
683 | - run_local_panel_service(); |
684 | - g_timeout_add_seconds(2, reconnect_to_service, remote); |
685 | - } |
686 | - } |
687 | - |
688 | - g_object_unref(proxy); |
689 | -} |
690 | - |
691 | - |
692 | -bool run_local_panel_service() |
693 | -{ |
694 | - GError* error = NULL; |
695 | - |
696 | - // This is obviously hackish, but this part of the code is mostly hackish... |
697 | - // Let's attempt to run it from where we expect it to be |
698 | - std::string cmd = PREFIXDIR + std::string("/lib/unity/unity-panel-service"); |
699 | - std::cerr << "\nWARNING: Couldn't load panel from installed services, " |
700 | - << "so trying to load panel from known location: " |
701 | - << cmd << "\n"; |
702 | - |
703 | - g_spawn_command_line_async(cmd.c_str(), &error); |
704 | - if (error) |
705 | - { |
706 | - std::cerr << "\nWARNING: Unable to launch remote service manually: " |
707 | - << error->message << "\n"; |
708 | - g_error_free(error); |
709 | - return false; |
710 | - } |
711 | - return true; |
712 | -} |
713 | - |
714 | -void request_sync(GDBusProxy* proxy, const char* method, GVariant* name, SyncData* data) |
715 | -{ |
716 | - g_dbus_proxy_call(proxy, method, name, G_DBUS_CALL_FLAGS_NONE, |
717 | - -1, data->cancel, on_sync_ready_cb, data); |
718 | -} |
719 | - |
720 | -void on_sync_ready_cb(GObject* source, GAsyncResult* res, gpointer data) |
721 | -{ |
722 | - SyncData* sync_data = reinterpret_cast<SyncData*>(data); |
723 | - GError* error = NULL; |
724 | - GVariant* args = g_dbus_proxy_call_finish((GDBusProxy*)source, res, &error); |
725 | - |
726 | - if (args == NULL) |
727 | - { |
728 | - g_warning("Unable to perform Sync() on panel service: %s", error->message); |
729 | - g_error_free(error); |
730 | - return; |
731 | - } |
732 | - |
733 | - sync_data->self->Sync(args, sync_data); |
734 | - g_variant_unref(args); |
735 | -} |
736 | - |
737 | -bool send_show_entry(ShowEntryData* data) |
738 | -{ |
739 | - g_return_val_if_fail(data != NULL, FALSE); |
740 | - g_return_val_if_fail(G_IS_DBUS_PROXY(data->proxy.RawPtr()), FALSE); |
741 | - |
742 | - g_dbus_proxy_call(data->proxy, |
743 | - "ShowEntry", |
744 | - g_variant_new("(suiiuu)", |
745 | - data->entry_id.c_str(), |
746 | - data->xid, |
747 | - data->x, |
748 | - data->y, |
749 | - data->button, |
750 | - data->timestamp), |
751 | - G_DBUS_CALL_FLAGS_NONE, |
752 | - -1, |
753 | - NULL, |
754 | - NULL, |
755 | - NULL); |
756 | - |
757 | - delete data; |
758 | - return FALSE; |
759 | -} |
760 | - |
761 | -bool send_show_appmenu(ShowEntryData* data) |
762 | -{ |
763 | - g_return_val_if_fail(data != NULL, FALSE); |
764 | - g_return_val_if_fail(G_IS_DBUS_PROXY(data->proxy.RawPtr()), FALSE); |
765 | - |
766 | - g_dbus_proxy_call(data->proxy, |
767 | - "ShowAppMenu", |
768 | - g_variant_new("(uiiu)", |
769 | - data->xid, |
770 | - data->x, |
771 | - data->y, |
772 | - data->timestamp), |
773 | - G_DBUS_CALL_FLAGS_NONE, |
774 | - -1, |
775 | - NULL, |
776 | - NULL, |
777 | - NULL); |
778 | - |
779 | - delete data; |
780 | - return FALSE; |
781 | -} |
782 | - |
783 | -} // anonymous namespace |
784 | - |
785 | } // namespace indicator |
786 | } // namespace unity |
787 | |
788 | === modified file 'UnityCore/DBusIndicators.h' |
789 | --- UnityCore/DBusIndicators.h 2012-03-20 10:16:27 +0000 |
790 | +++ UnityCore/DBusIndicators.h 2012-03-20 10:16:27 +0000 |
791 | @@ -50,15 +50,9 @@ |
792 | virtual void OnShowAppMenu(unsigned int xid, int x, int y, |
793 | unsigned int timestamp); |
794 | |
795 | - std::string name() const; |
796 | - std::string owner_name() const; |
797 | - bool using_local_service() const; |
798 | - |
799 | - // Due to the callback nature, the Impl class must be declared public, but |
800 | - // it is not available to anyone except the internal implementation. |
801 | +private: |
802 | class Impl; |
803 | -private: |
804 | - Impl* pimpl; |
805 | + std::unique_ptr<Impl> pimpl; |
806 | }; |
807 | |
808 | } |
809 | |
810 | === modified file 'UnityCore/GLibDBusProxy.cpp' |
811 | --- UnityCore/GLibDBusProxy.cpp 2012-02-20 09:29:55 +0000 |
812 | +++ UnityCore/GLibDBusProxy.cpp 2012-03-20 10:16:27 +0000 |
813 | @@ -39,13 +39,6 @@ |
814 | |
815 | using std::string; |
816 | |
817 | -struct CallData |
818 | -{ |
819 | - DBusProxy::ReplyCallback callback; |
820 | - DBusProxy::Impl* impl; |
821 | - std::string method_name; |
822 | -}; |
823 | - |
824 | class DBusProxy::Impl |
825 | { |
826 | public: |
827 | @@ -62,8 +55,7 @@ |
828 | |
829 | void StartReconnectionTimeout(); |
830 | void Connect(); |
831 | - void OnProxySignal(GDBusProxy* proxy, char* sender_name, char* signal_name, |
832 | - GVariant* parameters); |
833 | + |
834 | void Call(string const& method_name, |
835 | GVariant* parameters, |
836 | ReplyCallback callback, |
837 | @@ -74,12 +66,20 @@ |
838 | void Connect(string const& signal_name, ReplyCallback callback); |
839 | bool IsConnected(); |
840 | |
841 | - static void OnNameAppeared(GDBusConnection* connection, const char* name, |
842 | - const char* name_owner, gpointer impl); |
843 | - static void OnNameVanished(GDBusConnection* connection, const char* name, gpointer impl); |
844 | + void OnProxyNameOwnerChanged(GDBusProxy*, GParamSpec*); |
845 | + void OnProxySignal(GDBusProxy* proxy, char* sender_name, char* signal_name, |
846 | + GVariant* parameters); |
847 | + |
848 | static void OnProxyConnectCallback(GObject* source, GAsyncResult* res, gpointer impl); |
849 | static void OnCallCallback(GObject* source, GAsyncResult* res, gpointer call_data); |
850 | - |
851 | + |
852 | + struct CallData |
853 | + { |
854 | + DBusProxy::ReplyCallback callback; |
855 | + DBusProxy::Impl* impl; |
856 | + std::string method_name; |
857 | + }; |
858 | + |
859 | DBusProxy* owner_; |
860 | string name_; |
861 | string object_path_; |
862 | @@ -94,6 +94,7 @@ |
863 | bool connected_; |
864 | |
865 | glib::Signal<void, GDBusProxy*, char*, char*, GVariant*> g_signal_connection_; |
866 | + glib::Signal<void, GDBusProxy*, GParamSpec*> name_owner_signal_; |
867 | |
868 | SignalHandlers handlers_; |
869 | }; |
870 | @@ -115,14 +116,6 @@ |
871 | , reconnect_timeout_id_(0) |
872 | , connected_(false) |
873 | { |
874 | - LOG_DEBUG(logger) << "Watching name " << name_; |
875 | - watcher_id_ = g_bus_watch_name(bus_type_, |
876 | - name.c_str(), |
877 | - G_BUS_NAME_WATCHER_FLAGS_AUTO_START, |
878 | - DBusProxy::Impl::OnNameAppeared, |
879 | - DBusProxy::Impl::OnNameVanished, |
880 | - this, |
881 | - NULL); |
882 | StartReconnectionTimeout(); |
883 | } |
884 | |
885 | @@ -135,33 +128,6 @@ |
886 | g_source_remove(reconnect_timeout_id_); |
887 | } |
888 | |
889 | -void DBusProxy::Impl::OnNameAppeared(GDBusConnection* connection, |
890 | - const char* name, |
891 | - const char* name_owner, |
892 | - gpointer impl) |
893 | -{ |
894 | - DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl); |
895 | - LOG_DEBUG(logger) << self->name_ << " appeared"; |
896 | - |
897 | - if (self->proxy_) |
898 | - { |
899 | - self->connected_ = true; |
900 | - self->owner_->connected.emit(); |
901 | - } |
902 | -} |
903 | - |
904 | -void DBusProxy::Impl::OnNameVanished(GDBusConnection* connection, |
905 | - const char* name, |
906 | - gpointer impl) |
907 | -{ |
908 | - DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl); |
909 | - |
910 | - LOG_DEBUG(logger) << self->name_ << " vanished"; |
911 | - |
912 | - self->connected_ = false; |
913 | - self->owner_->disconnected.emit(); |
914 | -} |
915 | - |
916 | void DBusProxy::Impl::StartReconnectionTimeout() |
917 | { |
918 | LOG_DEBUG(logger) << "Starting reconnection timeout for " << name_; |
919 | @@ -204,6 +170,8 @@ |
920 | GAsyncResult* res, |
921 | gpointer impl) |
922 | { |
923 | + DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl); |
924 | + |
925 | glib::Error error; |
926 | glib::Object<GDBusProxy> proxy(g_dbus_proxy_new_for_bus_finish(res, &error)); |
927 | |
928 | @@ -215,14 +183,44 @@ |
929 | return; |
930 | } |
931 | |
932 | - DBusProxy::Impl* self = static_cast<DBusProxy::Impl*>(impl); |
933 | LOG_DEBUG(logger) << "Sucessfully created proxy: " << self->object_path_; |
934 | |
935 | self->proxy_ = proxy; |
936 | self->g_signal_connection_.Connect(self->proxy_, "g-signal", |
937 | - sigc::mem_fun(self, &DBusProxy::Impl::OnProxySignal)); |
938 | - self->connected_ = true; |
939 | - self->owner_->connected.emit(); |
940 | + sigc::mem_fun(self, &Impl::OnProxySignal)); |
941 | + self->name_owner_signal_.Connect(self->proxy_, "notify::g-name-owner", |
942 | + sigc::mem_fun(self, &Impl::OnProxyNameOwnerChanged)); |
943 | + |
944 | + // If a proxy cannot autostart a service, it doesn't throw an error, but |
945 | + // sets name_owner to NULL |
946 | + if (glib::String(g_dbus_proxy_get_name_owner(proxy))) |
947 | + { |
948 | + self->connected_ = true; |
949 | + self->owner_->connected.emit(); |
950 | + } |
951 | +} |
952 | + |
953 | +void DBusProxy::Impl::OnProxyNameOwnerChanged(GDBusProxy* proxy, GParamSpec* param) |
954 | +{ |
955 | + glib::String name_owner(g_dbus_proxy_get_name_owner(proxy)); |
956 | + |
957 | + if (name_owner) |
958 | + { |
959 | + if (!connected_) |
960 | + { |
961 | + LOG_DEBUG(logger) << name_ << " appeared"; |
962 | + |
963 | + connected_ = true; |
964 | + owner_->connected.emit(); |
965 | + } |
966 | + } |
967 | + else if (connected_) |
968 | + { |
969 | + LOG_DEBUG(logger) << name_ << " vanished"; |
970 | + |
971 | + connected_ = false; |
972 | + owner_->disconnected.emit(); |
973 | + } |
974 | } |
975 | |
976 | void DBusProxy::Impl::OnProxySignal(GDBusProxy* proxy, |
977 | @@ -308,9 +306,7 @@ |
978 | {} |
979 | |
980 | DBusProxy::~DBusProxy() |
981 | -{ |
982 | - delete pimpl; |
983 | -} |
984 | +{} |
985 | |
986 | void DBusProxy::Call(string const& method_name, |
987 | GVariant* parameters, |
988 | |
989 | === modified file 'UnityCore/GLibDBusProxy.h' |
990 | --- UnityCore/GLibDBusProxy.h 2012-02-04 05:28:23 +0000 |
991 | +++ UnityCore/GLibDBusProxy.h 2012-03-20 10:16:27 +0000 |
992 | @@ -62,9 +62,9 @@ |
993 | static void NoReplyCallback(GVariant* v) {}; |
994 | |
995 | // Public due to use in some callbacks |
996 | +private: |
997 | class Impl; |
998 | -private: |
999 | - Impl* pimpl; |
1000 | + std::unique_ptr<Impl> pimpl; |
1001 | }; |
1002 | |
1003 | } |
1004 | |
1005 | === modified file 'UnityCore/Indicators.cpp' |
1006 | --- UnityCore/Indicators.cpp 2012-03-20 10:16:27 +0000 |
1007 | +++ UnityCore/Indicators.cpp 2012-03-20 10:16:27 +0000 |
1008 | @@ -58,13 +58,10 @@ |
1009 | |
1010 | Indicators::Indicators() |
1011 | : pimpl(new Impl(this)) |
1012 | -{ |
1013 | -} |
1014 | +{} |
1015 | |
1016 | Indicators::~Indicators() |
1017 | -{ |
1018 | - delete pimpl; |
1019 | -} |
1020 | +{} |
1021 | |
1022 | void Indicators::ActivateEntry(std::string const& entry_id, nux::Rect const& geometry) |
1023 | { |
1024 | |
1025 | === modified file 'UnityCore/Indicators.h' |
1026 | --- UnityCore/Indicators.h 2012-03-20 10:16:27 +0000 |
1027 | +++ UnityCore/Indicators.h 2012-03-20 10:16:27 +0000 |
1028 | @@ -124,7 +124,7 @@ |
1029 | |
1030 | private: |
1031 | class Impl; |
1032 | - Impl* pimpl; |
1033 | + std::unique_ptr<Impl> pimpl; |
1034 | }; |
1035 | |
1036 | } |
1037 | |
1038 | === modified file 'plugins/unityshell/src/PanelView.cpp' |
1039 | --- plugins/unityshell/src/PanelView.cpp 2012-03-20 10:16:27 +0000 |
1040 | +++ plugins/unityshell/src/PanelView.cpp 2012-03-20 10:16:27 +0000 |
1041 | @@ -215,9 +215,6 @@ |
1042 | { |
1043 | variant::BuilderWrapper(builder) |
1044 | .add("backend", "remote") |
1045 | - .add("service-name", _remote->name()) |
1046 | - .add("service-unique-name", _remote->owner_name()) |
1047 | - .add("using-local-service", _remote->using_local_service()) |
1048 | .add(GetGeometry()); |
1049 | } |
1050 |
787 + bool auto_reconnect)
What are you actually trying to achieve with this? GDBusProxy automatically reconnects itself if you construct it using a known service name (as opposed to unique bus address). Therefore it seems redundant to me.
If you want to make sure that a service is alive, all you need to do is watch changes to the connected state and if it disconnects, just call any method from given interface and that will dbus-activate the service again.