Merge lp:~muktupavels/libappindicator/watch-status-notifier-watcher-dbus-name into lp:libappindicator/16.10

Proposed by Alberts Muktupāvels
Status: Merged
Merged at revision: 275
Proposed branch: lp:~muktupavels/libappindicator/watch-status-notifier-watcher-dbus-name
Merge into: lp:libappindicator/16.10
Diff against target: 260 lines (+84/-114)
1 file modified
src/app-indicator.c (+84/-114)
To merge this branch: bzr merge lp:~muktupavels/libappindicator/watch-status-notifier-watcher-dbus-name
Reviewer Review Type Date Requested Status
Dmitry Shachnev Approve
Ted Gould Pending
Indicator Applet Developers Pending
Review via email: mp+298533@code.launchpad.net

Commit message

Handle watcher service appearing and disappearing.

Description of the change

Handle watcher service appearing and disappearing.

To post a comment you must log in.
Revision history for this message
Dmitry Shachnev (mitya57) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/app-indicator.c'
2--- src/app-indicator.c 2014-11-10 09:14:07 +0000
3+++ src/app-indicator.c 2016-06-28 14:07:38 +0000
4@@ -89,11 +89,14 @@
5 gint fallback_timer;
6
7 /* Fun stuff */
8- GDBusProxy *watcher_proxy;
9 GDBusConnection *connection;
10 guint dbus_registration;
11 gchar * path;
12
13+ /* StatusNotifierWatcher */
14+ GDBusProxy *watcher_proxy;
15+ guint watcher_id;
16+
17 /* Might be used */
18 IndicatorDesktopShortcuts * shorties;
19 };
20@@ -187,13 +190,11 @@
21 static void status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data);
22 static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);
23 static gchar * append_panel_icon_suffix (const gchar * icon_name);
24-static void watcher_owner_changed (GObject * obj, GParamSpec * pspec, gpointer user_data);
25 static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);
26 static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);
27 static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);
28 static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data);
29 static void bus_creation (GObject * obj, GAsyncResult * res, gpointer user_data);
30-static void bus_watcher_ready (GObject * obj, GAsyncResult * res, gpointer user_data);
31
32 static const GDBusInterfaceVTable item_interface_table = {
33 method_call: bus_method_call,
34@@ -205,6 +206,63 @@
35 G_DEFINE_TYPE (AppIndicator, app_indicator, G_TYPE_OBJECT);
36
37 static void
38+watcher_ready_cb (GObject *source_object,
39+ GAsyncResult *res,
40+ gpointer user_data)
41+{
42+ AppIndicator *self = (AppIndicator *) user_data;
43+ GError *error = NULL;
44+
45+ self->priv->watcher_proxy = g_dbus_proxy_new_finish (res, &error);
46+
47+ if (error) {
48+ start_fallback_timer (self, FALSE);
49+ g_object_unref (self);
50+
51+ g_error_free (error);
52+ return;
53+ }
54+
55+ check_connect (self);
56+ g_object_unref (self);
57+}
58+
59+static void
60+name_appeared_handler (GDBusConnection *connection,
61+ const gchar *name,
62+ const gchar *name_owner,
63+ gpointer user_data)
64+{
65+ AppIndicator *self = (AppIndicator *) user_data;
66+
67+ g_dbus_proxy_new (self->priv->connection,
68+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
69+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
70+ watcher_interface_info,
71+ NOTIFICATION_WATCHER_DBUS_ADDR,
72+ NOTIFICATION_WATCHER_DBUS_OBJ,
73+ NOTIFICATION_WATCHER_DBUS_IFACE,
74+ NULL,
75+ (GAsyncReadyCallback) watcher_ready_cb,
76+ g_object_ref (self));
77+}
78+
79+static void
80+name_vanished_handler (GDBusConnection *connection,
81+ const gchar *name,
82+ gpointer user_data)
83+{
84+ AppIndicator *self = (AppIndicator *) user_data;
85+
86+ g_clear_object (&self->priv->watcher_proxy);
87+
88+ /* Emit the AppIndicator::connection-changed signal*/
89+ g_signal_emit (self, signals[CONNECTION_CHANGED], 0, FALSE);
90+
91+ start_fallback_timer (self, FALSE);
92+}
93+
94+static void
95 app_indicator_class_init (AppIndicatorClass *klass)
96 {
97 GObjectClass *object_class = G_OBJECT_CLASS (klass);
98@@ -598,7 +656,6 @@
99 priv->label_guide = NULL;
100 priv->label_change_idle = 0;
101
102- priv->watcher_proxy = NULL;
103 priv->connection = NULL;
104 priv->dbus_registration = 0;
105 priv->path = NULL;
106@@ -611,6 +668,14 @@
107 priv->sec_activate_target = NULL;
108 priv->sec_activate_enabled = FALSE;
109
110+ priv->watcher_proxy = NULL;
111+ priv->watcher_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
112+ NOTIFICATION_WATCHER_DBUS_ADDR,
113+ G_BUS_NAME_WATCHER_FLAGS_NONE,
114+ (GBusNameAppearedCallback) name_appeared_handler,
115+ (GBusNameVanishedCallback) name_vanished_handler,
116+ self, NULL);
117+
118 self->priv = priv;
119
120 /* Start getting the session bus */
121@@ -667,8 +732,12 @@
122 g_object_unref (priv->menuservice);
123 }
124
125+ if (priv->watcher_id != 0) {
126+ g_bus_unwatch_name (priv->watcher_id);
127+ priv->watcher_id = 0;
128+ }
129+
130 if (priv->watcher_proxy != NULL) {
131- g_signal_handlers_disconnect_by_func(G_OBJECT(priv->watcher_proxy), watcher_owner_changed, self);
132 g_object_unref(G_OBJECT(priv->watcher_proxy));
133 priv->watcher_proxy = NULL;
134
135@@ -1266,115 +1335,16 @@
136 want to ensure all the filters are setup before talking to the watcher
137 and that's where the order is important. */
138
139- g_object_ref(G_OBJECT(self)); /* Unref in watcher_ready() */
140- if (priv->watcher_proxy == NULL) {
141- /* Build Watcher Proxy */
142- g_dbus_proxy_new(priv->connection,
143- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES|
144- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, /* We don't use these, don't bother with them */
145- watcher_interface_info,
146- NOTIFICATION_WATCHER_DBUS_ADDR,
147- NOTIFICATION_WATCHER_DBUS_OBJ,
148- NOTIFICATION_WATCHER_DBUS_IFACE,
149- NULL, /* cancellable */
150- bus_watcher_ready,
151- self);
152- } else {
153- bus_watcher_ready(NULL, NULL, self);
154- }
155-
156- return;
157-}
158-
159-/* Callback for when the watcher proxy has been created, or not
160- but we got called none-the-less. */
161-static void
162-bus_watcher_ready (GObject * obj, GAsyncResult * res, gpointer user_data)
163-{
164- GError * error = NULL;
165-
166- GDBusProxy * proxy = NULL;
167- if (res != NULL) {
168- proxy = g_dbus_proxy_new_finish(res, &error);
169- }
170-
171- if (error != NULL) {
172- /* Unable to get proxy, but we're handling that now so
173- it's not a warning anymore. */
174- g_error_free(error);
175-
176- if (IS_APP_INDICATOR(user_data)) {
177- start_fallback_timer(APP_INDICATOR(user_data), FALSE);
178- }
179-
180- g_object_unref(G_OBJECT(user_data));
181- return;
182- }
183-
184- AppIndicator * app = APP_INDICATOR(user_data);
185-
186- if (res != NULL) {
187- app->priv->watcher_proxy = proxy;
188-
189- /* Setting up a signal to watch when the unique name
190- changes */
191- g_signal_connect(G_OBJECT(app->priv->watcher_proxy), "notify::g-name-owner", G_CALLBACK(watcher_owner_changed), user_data);
192- }
193-
194- /* Let's insure that someone is on the other side, else we're
195- still in a fallback scenario. */
196- gchar * name = g_dbus_proxy_get_name_owner(app->priv->watcher_proxy);
197- if (name == NULL) {
198- start_fallback_timer(APP_INDICATOR(user_data), FALSE);
199- g_object_unref(G_OBJECT(user_data));
200- return;
201- }
202- g_free(name);
203-
204- /* g_object_unref(G_OBJECT(user_data)); */
205- /* Why is this commented out? Oh, wait, we don't want to
206- unref in this case because we need to ref again to do the
207- register callback. Let's not unref to ref again. */
208-
209- g_dbus_proxy_call(app->priv->watcher_proxy,
210- "RegisterStatusNotifierItem",
211- g_variant_new("(s)", app->priv->path),
212- G_DBUS_CALL_FLAGS_NONE,
213- -1,
214- NULL, /* cancelable */
215- register_service_cb,
216- user_data);
217-
218- return;
219-}
220-
221-/* Watching for when the name owner changes on the interface
222- to know whether we should be connected or not. */
223-static void
224-watcher_owner_changed (GObject * obj, GParamSpec * pspec, gpointer user_data)
225-{
226- AppIndicator * self = APP_INDICATOR(user_data);
227- g_return_if_fail(self != NULL);
228- g_return_if_fail(self->priv->watcher_proxy != NULL);
229-
230- gchar * name = g_dbus_proxy_get_name_owner(self->priv->watcher_proxy);
231-
232- if (name == NULL) {
233- /* Emit the AppIndicator::connection-changed signal*/
234- g_signal_emit (self, signals[CONNECTION_CHANGED], 0, FALSE);
235-
236- start_fallback_timer(self, FALSE);
237- } else {
238- if (self->priv->fallback_timer != 0) {
239- /* Stop the timer */
240- g_source_remove(self->priv->fallback_timer);
241- self->priv->fallback_timer = 0;
242- }
243-
244- check_connect(self);
245- }
246-
247- return;
248+ if (priv->watcher_proxy == NULL)
249+ return;
250+
251+ g_dbus_proxy_call (priv->watcher_proxy,
252+ "RegisterStatusNotifierItem",
253+ g_variant_new ("(s)", priv->path),
254+ G_DBUS_CALL_FLAGS_NONE,
255+ -1, NULL,
256+ (GAsyncReadyCallback) register_service_cb,
257+ g_object_ref (self));
258 }
259
260 /* Responce from the DBus command to register a service

Subscribers

People subscribed via source and target branches