Merge lp:~muktupavels/libappindicator/no-host into lp:libappindicator

Proposed by Alberts Muktupāvels
Status: Merged
Approved by: Dmitry Shachnev
Approved revision: 298
Merged at revision: 297
Proposed branch: lp:~muktupavels/libappindicator/no-host
Merge into: lp:libappindicator
Diff against target: 354 lines (+226/-88)
2 files modified
src/app-indicator.c (+38/-2)
tests/test-libappindicator-fallback-watcher.c (+188/-86)
To merge this branch: bzr merge lp:~muktupavels/libappindicator/no-host
Reviewer Review Type Date Requested Status
Khurshid Alam (community) Approve
Dmitry Shachnev Pending
Review via email: mp+386817@code.launchpad.net

Commit message

Fall back to tray icon when StatusNotifierHost is not available.

Description of the change

Fall back to tray icon when StatusNotifierHost is not available.

https://gitlab.gnome.org/GNOME/gnome-flashback/-/issues/64

To post a comment you must log in.
Revision history for this message
Alberts Muktupāvels (muktupavels) wrote :

indicator-application-service does not support RegisterStatusNotifierHost method, but it does return TRUE for IsStatusNotifierHostRegistered.

Revision history for this message
Khurshid Alam (khurshid-alam) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/app-indicator.c'
--- src/app-indicator.c 2020-04-08 18:39:30 +0000
+++ src/app-indicator.c 2020-07-06 13:03:40 +0000
@@ -213,6 +213,38 @@
213G_DEFINE_TYPE (AppIndicator, app_indicator, G_TYPE_OBJECT);213G_DEFINE_TYPE (AppIndicator, app_indicator, G_TYPE_OBJECT);
214214
215static void215static void
216check_is_host_registered (AppIndicator *self)
217{
218 GVariant *variant;
219 gboolean is_host_registered;
220
221 variant = g_dbus_proxy_get_cached_property (self->priv->watcher_proxy,
222 "IsStatusNotifierHostRegistered");
223
224 is_host_registered = FALSE;
225 if (variant != NULL) {
226 is_host_registered = g_variant_get_boolean (variant);
227 g_variant_unref (variant);
228 }
229
230 if (!is_host_registered) {
231 start_fallback_timer (self, FALSE);
232 return;
233 }
234
235 check_connect (self);
236}
237
238static void
239watcher_properties_changed_cb (GDBusProxy *proxy,
240 GVariant *changed_properties,
241 GStrv invalidated_properties,
242 AppIndicator *self)
243{
244 check_is_host_registered (self);
245}
246
247static void
216watcher_ready_cb (GObject *source_object,248watcher_ready_cb (GObject *source_object,
217 GAsyncResult *res,249 GAsyncResult *res,
218 gpointer user_data)250 gpointer user_data)
@@ -230,7 +262,12 @@
230 return;262 return;
231 }263 }
232264
233 check_connect (self);265 g_signal_connect (self->priv->watcher_proxy,
266 "g-properties-changed",
267 G_CALLBACK (watcher_properties_changed_cb),
268 self);
269
270 check_is_host_registered (self);
234 g_object_unref (self);271 g_object_unref (self);
235}272}
236273
@@ -243,7 +280,6 @@
243 AppIndicator *self = (AppIndicator *) user_data;280 AppIndicator *self = (AppIndicator *) user_data;
244281
245 g_dbus_proxy_new (self->priv->connection,282 g_dbus_proxy_new (self->priv->connection,
246 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
247 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,283 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
248 watcher_interface_info,284 watcher_interface_info,
249 NOTIFICATION_WATCHER_DBUS_ADDR,285 NOTIFICATION_WATCHER_DBUS_ADDR,
250286
=== modified file 'tests/test-libappindicator-fallback-watcher.c'
--- tests/test-libappindicator-fallback-watcher.c 2013-01-16 19:53:52 +0000
+++ tests/test-libappindicator-fallback-watcher.c 2020-07-06 13:03:40 +0000
@@ -20,97 +20,199 @@
20with this program. If not, see <http://www.gnu.org/licenses/>.20with this program. If not, see <http://www.gnu.org/licenses/>.
21*/21*/
2222
23#include <glib.h>23#include <gio/gio.h>
24#include <dbus/dbus-glib.h>
25#include <dbus/dbus-glib-bindings.h>
26#include <dbus/dbus-glib-lowlevel.h>
2724
28#include "../src/dbus-shared.h"25#include "../src/dbus-shared.h"
2926
30gboolean kill_func (gpointer userdata);27typedef struct
3128{
32static GMainLoop * mainloop = NULL;29 int status;
3330
34static DBusHandlerResult31 GMainLoop *loop;
35dbus_filter (DBusConnection * connection, DBusMessage * message, void * user_data)32} TestData;
36{33
37 if (dbus_message_is_method_call(message, NOTIFICATION_WATCHER_DBUS_ADDR, "RegisterStatusNotifierItem")) {34static const gchar introspection_xml[] =
38 DBusMessage * reply = dbus_message_new_method_return(message);35 "<node>"
39 dbus_connection_send(connection, reply, NULL);36 " <interface name='" NOTIFICATION_WATCHER_DBUS_IFACE "'>"
40 dbus_message_unref(reply);37 " <method name='RegisterStatusNotifierItem'>"
4138 " <arg type='s' name='service' direction='in'/>"
42 /* Let the messages get out, but we're done at this point */39 " </method>"
43 g_timeout_add(50, kill_func, NULL);40 " <property type='b' name='IsStatusNotifierHostRegistered' access='read'/>"
4441 " </interface>"
45 return DBUS_HANDLER_RESULT_HANDLED;42 "</node>";
46 }43
4744static gboolean
48 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;45kill_func (gpointer user_data)
49}46{
5047 TestData *data;
51gboolean48
52kill_func (gpointer userdata)49 data = user_data;
53{50 data->status = EXIT_FAILURE;
54 g_main_loop_quit(mainloop);51
55 return FALSE;52 g_main_loop_quit (data->loop);
53
54 return G_SOURCE_REMOVE;
55}
56
57static void
58handle_method_call (GDBusConnection *connection,
59 const gchar *sender,
60 const gchar *object_path,
61 const gchar *interface_name,
62 const gchar *method_name,
63 GVariant *parameters,
64 GDBusMethodInvocation *invocation,
65 gpointer user_data)
66{
67 TestData *data;
68
69 data = user_data;
70
71 if (g_strcmp0 (method_name, "RegisterStatusNotifierItem") == 0)
72 {
73 g_dbus_method_invocation_return_value (invocation, NULL);
74 g_main_loop_quit (data->loop);
75 }
76}
77
78static GVariant *
79handle_get_property (GDBusConnection *connection,
80 const gchar *sender,
81 const gchar *object_path,
82 const gchar *interface_name,
83 const gchar *property_name,
84 GError **error,
85 gpointer user_data)
86{
87 if (g_strcmp0 (property_name, "IsStatusNotifierHostRegistered") == 0)
88 return g_variant_new_boolean (TRUE);
89
90 return NULL;
91}
92
93static const GDBusInterfaceVTable interface_vtable =
94{
95 handle_method_call,
96 handle_get_property,
97 NULL
98};
99
100static void
101bus_acquired_cb (GDBusConnection *connection,
102 const gchar *name,
103 gpointer user_data)
104{
105
106 GDBusNodeInfo *introspection_info;
107
108 introspection_info = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
109
110 g_dbus_connection_register_object (connection,
111 NOTIFICATION_WATCHER_DBUS_OBJ,
112 introspection_info->interfaces[0],
113 &interface_vtable,
114 user_data,
115 NULL,
116 NULL);
117
118 g_dbus_node_info_unref (introspection_info);
119}
120
121static void
122name_lost_cb (GDBusConnection *connection,
123 const gchar *name,
124 gpointer user_data)
125{
126 TestData *data;
127
128 data = user_data;
129 data->status = EXIT_FAILURE;
130
131 g_main_loop_quit (data->loop);
56}132}
57133
58int134int
59main (int argv, char ** argc)135main (int argc,
136 char *argv[])
60{137{
61 g_debug("Waiting to init.");138 GDBusProxy *proxy;
62139 gboolean has_owner;
63140 gint owner_count;
64 GError * error = NULL;141 TestData data;
65 DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);142 guint owner_id;
66 if (error != NULL) {143
67 g_error("Unable to get session bus: %s", error->message);144 g_debug ("Waiting to init.");
68 return 1;145
69 }146 proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
70147 G_DBUS_PROXY_FLAGS_NONE,
71 DBusGProxy * bus_proxy = dbus_g_proxy_new_for_name(session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);148 NULL,
72149 "org.freedesktop.DBus",
73 gboolean has_owner = FALSE;150 "/org/freedesktop/DBus",
74 gint owner_count = 0;151 "org.freedesktop.DBus",
75 while (!has_owner && owner_count < 10000) {152 NULL,
76 org_freedesktop_DBus_name_has_owner(bus_proxy, "org.test", &has_owner, NULL);153 NULL);
77 owner_count++;154
78 g_usleep(500000);155 has_owner = FALSE;
79 }156 owner_count = 0;
80157
81 if (owner_count == 10000) {158 while (!has_owner && owner_count < 10000)
82 g_error("Unable to get name owner after 10000 tries");159 {
83 return 1;160 GVariant *variant;
84 }161
85162 variant = g_dbus_proxy_call_sync (proxy,
86 g_usleep(500000);163 "NameHasOwner",
87164 g_variant_new ("(s)", "org.test"),
88 g_debug("Initing");165 G_DBUS_CALL_FLAGS_NONE,
89166 -1,
90 guint nameret = 0;167 NULL,
91168 NULL);
92 if (!org_freedesktop_DBus_request_name(bus_proxy, NOTIFICATION_WATCHER_DBUS_ADDR, 0, &nameret, &error)) {169
93 g_error("Unable to call to request name");170 if (variant != NULL)
94 return 1;171 {
95 } 172 g_variant_get (variant, "(b)", &has_owner);
96173 g_variant_unref (variant);
97 if (nameret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {174 }
98 g_error("Unable to get name");175
99 return 1;176 g_usleep (500000);
100 }177 owner_count++;
101178 }
102 dbus_connection_add_filter(dbus_g_connection_get_connection(session_bus), dbus_filter, NULL, NULL);179
103180 g_object_unref (proxy);
104 /* This is the final kill function. It really shouldn't happen181
105 unless we get an error. */182 if (owner_count == 10000)
106 g_timeout_add_seconds(20, kill_func, NULL);183 {
107184 g_error ("Unable to get name owner after 10000 tries");
108 g_debug("Entering Mainloop");185 return EXIT_FAILURE;
109186 }
110 mainloop = g_main_loop_new(NULL, FALSE);187
111 g_main_loop_run(mainloop);188 g_usleep (500000);
112189 g_debug ("Initing");
113 g_debug("Exiting");190
114191 data.status = EXIT_SUCCESS;
115 return 0;192 data.loop = g_main_loop_new (NULL, FALSE);
193
194 owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
195 NOTIFICATION_WATCHER_DBUS_ADDR,
196 G_BUS_NAME_OWNER_FLAGS_NONE,
197 bus_acquired_cb,
198 NULL,
199 name_lost_cb,
200 &data,
201 NULL);
202
203 /* This is the final kill function. It really shouldn't happen
204 * unless we get an error.
205 */
206 g_timeout_add_seconds (20, kill_func, &data);
207
208 g_debug ("Entering Mainloop");
209
210 g_main_loop_run (data.loop);
211
212 g_main_loop_unref (data.loop);
213 g_bus_unown_name (owner_id);
214
215 g_debug ("Exiting");
216
217 return data.status;
116}218}

Subscribers

People subscribed via source and target branches