diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-03-28 23:04:20 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2018-03-29 22:11:08 -0400 |
commit | cab1352801b62d1b8a12ca1c995cb24445ce4bc9 (patch) | |
tree | bc67373916c06d48700c4f69b8c2470a2f86887f /swaybar/tray/sni_watcher.c | |
parent | Allow sway IPC clients to fall back to i3 socket (diff) | |
download | sway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.tar.gz sway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.tar.zst sway-cab1352801b62d1b8a12ca1c995cb24445ce4bc9.zip |
Start port of swaybar to layer shell
This starts up the event loop and wayland display and shims out the
basic top level rendering concepts. Also includes some changes to
incorporate pango into the 1.x codebase properly.
Diffstat (limited to 'swaybar/tray/sni_watcher.c')
-rw-r--r-- | swaybar/tray/sni_watcher.c | 497 |
1 files changed, 0 insertions, 497 deletions
diff --git a/swaybar/tray/sni_watcher.c b/swaybar/tray/sni_watcher.c deleted file mode 100644 index 86453e70..00000000 --- a/swaybar/tray/sni_watcher.c +++ /dev/null | |||
@@ -1,497 +0,0 @@ | |||
1 | #define _XOPEN_SOURCE 500 | ||
2 | #include <unistd.h> | ||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <string.h> | ||
6 | #include <stdbool.h> | ||
7 | #include <dbus/dbus.h> | ||
8 | #include "swaybar/tray/dbus.h" | ||
9 | #include "list.h" | ||
10 | #include "log.h" | ||
11 | |||
12 | static list_t *items = NULL; | ||
13 | static list_t *hosts = NULL; | ||
14 | |||
15 | /** | ||
16 | * Describes the function of the StatusNotifierWatcher | ||
17 | * See https://freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierWatcher/ | ||
18 | * | ||
19 | * We also implement KDE's special snowflake protocol, it's like this but with | ||
20 | * all occurrences 'freedesktop' replaced with 'kde'. There is no KDE introspect. | ||
21 | */ | ||
22 | static const char *interface_xml = | ||
23 | "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'" | ||
24 | "'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>" | ||
25 | "<node>" | ||
26 | " <interface name='org.freedesktop.DBus.Introspectable'>" | ||
27 | " <method name='Introspect'>" | ||
28 | " <arg name='xml_data' direction='out' type='s'/>" | ||
29 | " </method>" | ||
30 | " </interface>" | ||
31 | " <interface name='org.freedesktop.DBus.Properties'>" | ||
32 | " <method name='Get'>" | ||
33 | " <arg name='interface' direction='in' type='s'/>" | ||
34 | " <arg name='propname' direction='in' type='s'/>" | ||
35 | " <arg name='value' direction='out' type='v'/>" | ||
36 | " </method>" | ||
37 | " <method name='Set'>" | ||
38 | " <arg name='interface' direction='in' type='s'/>" | ||
39 | " <arg name='propname' direction='in' type='s'/>" | ||
40 | " <arg name='value' direction='in' type='v'/>" | ||
41 | " </method>" | ||
42 | " <method name='GetAll'>" | ||
43 | " <arg name='interface' direction='in' type='s'/>" | ||
44 | " <arg name='props' direction='out' type='a{sv}'/>" | ||
45 | " </method>" | ||
46 | " </interface>" | ||
47 | " <interface name='org.freedesktop.StatusNotifierWatcher'>" | ||
48 | " <method name='RegisterStatusNotifierItem'>" | ||
49 | " <arg type='s' name='service' direction='in'/>" | ||
50 | " </method>" | ||
51 | " <method name='RegisterStatusNotifierHost'>" | ||
52 | " <arg type='s' name='service' direction='in'/>" | ||
53 | " </method>" | ||
54 | " <property name='RegisteredStatusNotifierItems' type='as' access='read'/>" | ||
55 | " <property name='IsStatusNotifierHostRegistered' type='b' access='read'/>" | ||
56 | " <property name='ProtocolVersion' type='i' access='read'/>" | ||
57 | " <signal name='StatusNotifierItemRegistered'>" | ||
58 | " <arg type='s' name='service' direction='out'/>" | ||
59 | " </signal>" | ||
60 | " <signal name='StatusNotifierItemUnregistered'>" | ||
61 | " <arg type='s' name='service' direction='out'/>" | ||
62 | " </signal>" | ||
63 | " <signal name='StatusNotifierHostRegistered'>" | ||
64 | " <arg type='' name='service' direction='out'/>" | ||
65 | " </signal>" | ||
66 | " </interface>" | ||
67 | "</node>"; | ||
68 | |||
69 | static void host_registered_signal(DBusConnection *connection) { | ||
70 | // Send one signal for each protocol | ||
71 | DBusMessage *signal = dbus_message_new_signal( | ||
72 | "/StatusNotifierWatcher", | ||
73 | "org.freedesktop.StatusNotifierWatcher", | ||
74 | "StatusNotifierHostRegistered"); | ||
75 | |||
76 | dbus_connection_send(connection, signal, NULL); | ||
77 | dbus_message_unref(signal); | ||
78 | |||
79 | |||
80 | signal = dbus_message_new_signal( | ||
81 | "/StatusNotifierWatcher", | ||
82 | "org.kde.StatusNotifierWatcher", | ||
83 | "StatusNotifierHostRegistered"); | ||
84 | |||
85 | dbus_connection_send(connection, signal, NULL); | ||
86 | dbus_message_unref(signal); | ||
87 | } | ||
88 | static void item_registered_signal(DBusConnection *connection, const char *name) { | ||
89 | DBusMessage *signal = dbus_message_new_signal( | ||
90 | "/StatusNotifierWatcher", | ||
91 | "org.freedesktop.StatusNotifierWatcher", | ||
92 | "StatusNotifierItemRegistered"); | ||
93 | dbus_message_append_args(signal, | ||
94 | DBUS_TYPE_STRING, &name, | ||
95 | DBUS_TYPE_INVALID); | ||
96 | dbus_connection_send(connection, signal, NULL); | ||
97 | dbus_message_unref(signal); | ||
98 | |||
99 | signal = dbus_message_new_signal( | ||
100 | "/StatusNotifierWatcher", | ||
101 | "org.kde.StatusNotifierWatcher", | ||
102 | "StatusNotifierItemRegistered"); | ||
103 | dbus_message_append_args(signal, | ||
104 | DBUS_TYPE_STRING, &name, | ||
105 | DBUS_TYPE_INVALID); | ||
106 | dbus_connection_send(connection, signal, NULL); | ||
107 | dbus_message_unref(signal); | ||
108 | } | ||
109 | static void item_unregistered_signal(DBusConnection *connection, const char *name) { | ||
110 | DBusMessage *signal = dbus_message_new_signal( | ||
111 | "/StatusNotifierWatcher", | ||
112 | "org.freedesktop.StatusNotifierWatcher", | ||
113 | "StatusNotifierItemUnregistered"); | ||
114 | dbus_message_append_args(signal, | ||
115 | DBUS_TYPE_STRING, &name, | ||
116 | DBUS_TYPE_INVALID); | ||
117 | dbus_connection_send(connection, signal, NULL); | ||
118 | dbus_message_unref(signal); | ||
119 | |||
120 | signal = dbus_message_new_signal( | ||
121 | "/StatusNotifierWatcher", | ||
122 | "org.kde.StatusNotifierWatcher", | ||
123 | "StatusNotifierItemUnregistered"); | ||
124 | dbus_message_append_args(signal, | ||
125 | DBUS_TYPE_STRING, &name, | ||
126 | DBUS_TYPE_INVALID); | ||
127 | dbus_connection_send(connection, signal, NULL); | ||
128 | dbus_message_unref(signal); | ||
129 | } | ||
130 | |||
131 | static void respond_to_introspect(DBusConnection *connection, DBusMessage *request) { | ||
132 | DBusMessage *reply; | ||
133 | |||
134 | reply = dbus_message_new_method_return(request); | ||
135 | dbus_message_append_args(reply, | ||
136 | DBUS_TYPE_STRING, &interface_xml, | ||
137 | DBUS_TYPE_INVALID); | ||
138 | dbus_connection_send(connection, reply, NULL); | ||
139 | dbus_message_unref(reply); | ||
140 | } | ||
141 | |||
142 | static void register_item(DBusConnection *connection, DBusMessage *message) { | ||
143 | DBusError error; | ||
144 | char *name; | ||
145 | |||
146 | dbus_error_init(&error); | ||
147 | if (!dbus_message_get_args(message, &error, | ||
148 | DBUS_TYPE_STRING, &name, | ||
149 | DBUS_TYPE_INVALID)) { | ||
150 | sway_log(L_ERROR, "Error parsing method args: %s\n", error.message); | ||
151 | } | ||
152 | |||
153 | sway_log(L_INFO, "RegisterStatusNotifierItem called with \"%s\"\n", name); | ||
154 | |||
155 | // Don't add duplicate or not real item | ||
156 | if (!dbus_validate_bus_name(name, NULL)) { | ||
157 | sway_log(L_INFO, "This item is not valid, we cannot keep track of it."); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | if (list_seq_find(items, (int (*)(const void *, const void *))strcmp, name) != -1) { | ||
162 | return; | ||
163 | } | ||
164 | if (!dbus_bus_name_has_owner(connection, name, &error)) { | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | list_add(items, strdup(name)); | ||
169 | item_registered_signal(connection, name); | ||
170 | |||
171 | // It's silly, but xembedsniproxy wants a reply for this function | ||
172 | DBusMessage *reply = dbus_message_new_method_return(message); | ||
173 | dbus_connection_send(connection, reply, NULL); | ||
174 | dbus_message_unref(reply); | ||
175 | } | ||
176 | |||
177 | static void register_host(DBusConnection *connection, DBusMessage *message) { | ||
178 | DBusError error; | ||
179 | char *name; | ||
180 | |||
181 | dbus_error_init(&error); | ||
182 | if (!dbus_message_get_args(message, &error, | ||
183 | DBUS_TYPE_STRING, &name, | ||
184 | DBUS_TYPE_INVALID)) { | ||
185 | sway_log(L_ERROR, "Error parsing method args: %s\n", error.message); | ||
186 | } | ||
187 | |||
188 | sway_log(L_INFO, "RegisterStatusNotifierHost called with \"%s\"\n", name); | ||
189 | |||
190 | // Don't add duplicate or not real host | ||
191 | if (!dbus_validate_bus_name(name, NULL)) { | ||
192 | sway_log(L_INFO, "This item is not valid, we cannot keep track of it."); | ||
193 | return; | ||
194 | } | ||
195 | |||
196 | |||
197 | if (list_seq_find(hosts, (int (*)(const void *, const void *))strcmp, name) != -1) { | ||
198 | return; | ||
199 | } | ||
200 | if (!dbus_bus_name_has_owner(connection, name, &error)) { | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | list_add(hosts, strdup(name)); | ||
205 | host_registered_signal(connection); | ||
206 | } | ||
207 | |||
208 | static void get_property(DBusConnection *connection, DBusMessage *message) { | ||
209 | DBusError error; | ||
210 | char *interface; | ||
211 | char *property; | ||
212 | |||
213 | dbus_error_init(&error); | ||
214 | if (!dbus_message_get_args(message, &error, | ||
215 | DBUS_TYPE_STRING, &interface, | ||
216 | DBUS_TYPE_STRING, &property, | ||
217 | DBUS_TYPE_INVALID)) { | ||
218 | sway_log(L_ERROR, "Error parsing prop args: %s\n", error.message); | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | if (strcmp(property, "RegisteredStatusNotifierItems") == 0) { | ||
223 | sway_log(L_INFO, "Replying with items\n"); | ||
224 | DBusMessage *reply; | ||
225 | reply = dbus_message_new_method_return(message); | ||
226 | DBusMessageIter iter; | ||
227 | DBusMessageIter sub; | ||
228 | DBusMessageIter subsub; | ||
229 | |||
230 | dbus_message_iter_init_append(reply, &iter); | ||
231 | |||
232 | dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, | ||
233 | "as", &sub); | ||
234 | dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, | ||
235 | "s", &subsub); | ||
236 | |||
237 | for (int i = 0; i < items->length; ++i) { | ||
238 | dbus_message_iter_append_basic(&subsub, | ||
239 | DBUS_TYPE_STRING, &items->items[i]); | ||
240 | } | ||
241 | |||
242 | dbus_message_iter_close_container(&sub, &subsub); | ||
243 | dbus_message_iter_close_container(&iter, &sub); | ||
244 | |||
245 | dbus_connection_send(connection, reply, NULL); | ||
246 | dbus_message_unref(reply); | ||
247 | } else if (strcmp(property, "IsStatusNotifierHostRegistered") == 0) { | ||
248 | DBusMessage *reply; | ||
249 | DBusMessageIter iter; | ||
250 | DBusMessageIter sub; | ||
251 | int registered = (hosts == NULL || hosts->length == 0) ? 0 : 1; | ||
252 | |||
253 | reply = dbus_message_new_method_return(message); | ||
254 | |||
255 | dbus_message_iter_init_append(reply, &iter); | ||
256 | |||
257 | dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, | ||
258 | "b", &sub); | ||
259 | dbus_message_iter_append_basic(&sub, | ||
260 | DBUS_TYPE_BOOLEAN, ®istered); | ||
261 | |||
262 | dbus_message_iter_close_container(&iter, &sub); | ||
263 | |||
264 | dbus_connection_send(connection, reply, NULL); | ||
265 | dbus_message_unref(reply); | ||
266 | } else if (strcmp(property, "ProtocolVersion") == 0) { | ||
267 | DBusMessage *reply; | ||
268 | DBusMessageIter iter; | ||
269 | DBusMessageIter sub; | ||
270 | const int version = 0; | ||
271 | |||
272 | reply = dbus_message_new_method_return(message); | ||
273 | |||
274 | dbus_message_iter_init_append(reply, &iter); | ||
275 | |||
276 | dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, | ||
277 | "i", &sub); | ||
278 | dbus_message_iter_append_basic(&sub, | ||
279 | DBUS_TYPE_INT32, &version); | ||
280 | |||
281 | dbus_message_iter_close_container(&iter, &sub); | ||
282 | dbus_connection_send(connection, reply, NULL); | ||
283 | dbus_message_unref(reply); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | static void set_property(DBusConnection *connection, DBusMessage *message) { | ||
288 | // All properties are read only and we don't allow new properties | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | static void get_all(DBusConnection *connection, DBusMessage *message) { | ||
293 | DBusMessage *reply; | ||
294 | reply = dbus_message_new_method_return(message); | ||
295 | DBusMessageIter iter; /* a{v} */ | ||
296 | DBusMessageIter arr; | ||
297 | DBusMessageIter dict; | ||
298 | DBusMessageIter sub; | ||
299 | DBusMessageIter subsub; | ||
300 | int registered = (hosts == NULL || hosts->length == 0) ? 0 : 1; | ||
301 | const int version = 0; | ||
302 | const char *prop; | ||
303 | |||
304 | // Could clean this up with a function for each prop | ||
305 | dbus_message_iter_init_append(reply, &iter); | ||
306 | dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, | ||
307 | "{sv}", &arr); | ||
308 | |||
309 | prop = "RegisteredStatusNotifierItems"; | ||
310 | dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, | ||
311 | NULL, &dict); | ||
312 | dbus_message_iter_append_basic(&dict, | ||
313 | DBUS_TYPE_STRING, &prop); | ||
314 | dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, | ||
315 | "as", &sub); | ||
316 | dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, | ||
317 | "s", &subsub); | ||
318 | for (int i = 0; i < items->length; ++i) { | ||
319 | dbus_message_iter_append_basic(&subsub, | ||
320 | DBUS_TYPE_STRING, &items->items[i]); | ||
321 | } | ||
322 | dbus_message_iter_close_container(&sub, &subsub); | ||
323 | dbus_message_iter_close_container(&dict, &sub); | ||
324 | dbus_message_iter_close_container(&arr, &dict); | ||
325 | |||
326 | prop = "IsStatusNotifierHostRegistered"; | ||
327 | dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, | ||
328 | NULL, &dict); | ||
329 | dbus_message_iter_append_basic(&dict, | ||
330 | DBUS_TYPE_STRING, &prop); | ||
331 | dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, | ||
332 | "b", &sub); | ||
333 | dbus_message_iter_append_basic(&sub, | ||
334 | DBUS_TYPE_BOOLEAN, ®istered); | ||
335 | dbus_message_iter_close_container(&dict, &sub); | ||
336 | dbus_message_iter_close_container(&arr, &dict); | ||
337 | |||
338 | prop = "ProtocolVersion"; | ||
339 | dbus_message_iter_open_container(&arr, DBUS_TYPE_DICT_ENTRY, | ||
340 | NULL, &dict); | ||
341 | dbus_message_iter_append_basic(&dict, | ||
342 | DBUS_TYPE_STRING, &prop); | ||
343 | dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, | ||
344 | "i", &sub); | ||
345 | dbus_message_iter_append_basic(&sub, | ||
346 | DBUS_TYPE_INT32, &version); | ||
347 | dbus_message_iter_close_container(&dict, &sub); | ||
348 | dbus_message_iter_close_container(&arr, &dict); | ||
349 | |||
350 | dbus_message_iter_close_container(&iter, &arr); | ||
351 | |||
352 | dbus_connection_send(connection, reply, NULL); | ||
353 | dbus_message_unref(reply); | ||
354 | } | ||
355 | |||
356 | static DBusHandlerResult message_handler(DBusConnection *connection, | ||
357 | DBusMessage *message, void *data) { | ||
358 | const char *interface_name = dbus_message_get_interface(message); | ||
359 | const char *member_name = dbus_message_get_member(message); | ||
360 | |||
361 | // In order of the xml above | ||
362 | if (strcmp(interface_name, "org.freedesktop.DBus.Introspectable") == 0 && | ||
363 | strcmp(member_name, "Introspect") == 0) { | ||
364 | // We don't have an introspect for KDE | ||
365 | respond_to_introspect(connection, message); | ||
366 | return DBUS_HANDLER_RESULT_HANDLED; | ||
367 | } else if (strcmp(interface_name, "org.freedesktop.DBus.Properties") == 0) { | ||
368 | if (strcmp(member_name, "Get") == 0) { | ||
369 | get_property(connection, message); | ||
370 | return DBUS_HANDLER_RESULT_HANDLED; | ||
371 | } else if (strcmp(member_name, "Set") == 0) { | ||
372 | set_property(connection, message); | ||
373 | return DBUS_HANDLER_RESULT_HANDLED; | ||
374 | } else if (strcmp(member_name, "GetAll") == 0) { | ||
375 | get_all(connection, message); | ||
376 | return DBUS_HANDLER_RESULT_HANDLED; | ||
377 | } else { | ||
378 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
379 | } | ||
380 | } else if (strcmp(interface_name, "org.freedesktop.StatusNotifierWatcher") == 0 || | ||
381 | strcmp(interface_name, "org.kde.StatusNotifierWatcher") == 0) { | ||
382 | if (strcmp(member_name, "RegisterStatusNotifierItem") == 0) { | ||
383 | register_item(connection, message); | ||
384 | return DBUS_HANDLER_RESULT_HANDLED; | ||
385 | } else if (strcmp(member_name, "RegisterStatusNotifierHost") == 0) { | ||
386 | register_host(connection, message); | ||
387 | return DBUS_HANDLER_RESULT_HANDLED; | ||
388 | } else { | ||
389 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
390 | } | ||
391 | } | ||
392 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
393 | } | ||
394 | |||
395 | static DBusHandlerResult signal_handler(DBusConnection *connection, | ||
396 | DBusMessage *message, void *_data) { | ||
397 | if (dbus_message_is_signal(message, "org.freedesktop.DBus", "NameOwnerChanged")) { | ||
398 | // Only eat the message if it is name that we are watching | ||
399 | const char *name; | ||
400 | const char *old_owner; | ||
401 | const char *new_owner; | ||
402 | int index; | ||
403 | if (!dbus_message_get_args(message, NULL, | ||
404 | DBUS_TYPE_STRING, &name, | ||
405 | DBUS_TYPE_STRING, &old_owner, | ||
406 | DBUS_TYPE_STRING, &new_owner, | ||
407 | DBUS_TYPE_INVALID)) { | ||
408 | sway_log(L_ERROR, "Error getting LostName args"); | ||
409 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
410 | } | ||
411 | if (strcmp(new_owner, "") != 0) { | ||
412 | // Name is not lost | ||
413 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
414 | } | ||
415 | if ((index = list_seq_find(items, (int (*)(const void *, const void *))strcmp, name)) != -1) { | ||
416 | sway_log(L_INFO, "Status Notifier Item lost %s", name); | ||
417 | free(items->items[index]); | ||
418 | list_del(items, index); | ||
419 | item_unregistered_signal(connection, name); | ||
420 | |||
421 | return DBUS_HANDLER_RESULT_HANDLED; | ||
422 | } | ||
423 | if ((index = list_seq_find(hosts, (int (*)(const void *, const void *))strcmp, name)) != -1) { | ||
424 | sway_log(L_INFO, "Status Notifier Host lost %s", name); | ||
425 | free(hosts->items[index]); | ||
426 | list_del(hosts, index); | ||
427 | |||
428 | return DBUS_HANDLER_RESULT_HANDLED; | ||
429 | } | ||
430 | } | ||
431 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
432 | } | ||
433 | |||
434 | static const DBusObjectPathVTable vtable = { | ||
435 | .message_function = message_handler, | ||
436 | .unregister_function = NULL, | ||
437 | }; | ||
438 | |||
439 | int init_sni_watcher() { | ||
440 | DBusError error; | ||
441 | dbus_error_init(&error); | ||
442 | if (!conn) { | ||
443 | sway_log(L_ERROR, "Connection is null, cannot initiate StatusNotifierWatcher"); | ||
444 | return -1; | ||
445 | } | ||
446 | |||
447 | items = create_list(); | ||
448 | hosts = create_list(); | ||
449 | |||
450 | int status = dbus_bus_request_name(conn, "org.freedesktop.StatusNotifierWatcher", | ||
451 | DBUS_NAME_FLAG_REPLACE_EXISTING, | ||
452 | &error); | ||
453 | if (status == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { | ||
454 | sway_log(L_DEBUG, "Got watcher name"); | ||
455 | } else if (status == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { | ||
456 | sway_log(L_INFO, "Could not get watcher name, it may start later"); | ||
457 | } | ||
458 | if (dbus_error_is_set(&error)) { | ||
459 | sway_log(L_ERROR, "dbus err getting watcher name: %s\n", error.message); | ||
460 | return -1; | ||
461 | } | ||
462 | |||
463 | status = dbus_bus_request_name(conn, "org.kde.StatusNotifierWatcher", | ||
464 | DBUS_NAME_FLAG_REPLACE_EXISTING, | ||
465 | &error); | ||
466 | if (status == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { | ||
467 | sway_log(L_DEBUG, "Got kde watcher name"); | ||
468 | } else if (status == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { | ||
469 | sway_log(L_INFO, "Could not get kde watcher name, it may start later"); | ||
470 | } | ||
471 | if (dbus_error_is_set(&error)) { | ||
472 | sway_log(L_ERROR, "dbus err getting kde watcher name: %s\n", error.message); | ||
473 | return -1; | ||
474 | } | ||
475 | |||
476 | dbus_connection_try_register_object_path(conn, | ||
477 | "/StatusNotifierWatcher", | ||
478 | &vtable, NULL, &error); | ||
479 | if (dbus_error_is_set(&error)) { | ||
480 | sway_log(L_ERROR, "dbus_err: %s\n", error.message); | ||
481 | return -1; | ||
482 | } | ||
483 | |||
484 | dbus_bus_add_match(conn, | ||
485 | "type='signal',\ | ||
486 | sender='org.freedesktop.DBus',\ | ||
487 | interface='org.freedesktop.DBus',\ | ||
488 | member='NameOwnerChanged'", | ||
489 | &error); | ||
490 | |||
491 | if (dbus_error_is_set(&error)) { | ||
492 | sway_log(L_ERROR, "DBus error getting match args: %s", error.message); | ||
493 | } | ||
494 | |||
495 | dbus_connection_add_filter(conn, signal_handler, NULL, NULL); | ||
496 | return 0; | ||
497 | } | ||