diff options
Diffstat (limited to 'swaybar/tray/tray.c')
-rw-r--r-- | swaybar/tray/tray.c | 128 |
1 files changed, 126 insertions, 2 deletions
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c index 91c3af06..01532e1c 100644 --- a/swaybar/tray/tray.c +++ b/swaybar/tray/tray.c | |||
@@ -102,6 +102,70 @@ bail: | |||
102 | dbus_pending_call_unref(pending); | 102 | dbus_pending_call_unref(pending); |
103 | return; | 103 | return; |
104 | } | 104 | } |
105 | static void get_obj_items_reply(DBusPendingCall *pending, void *_data) { | ||
106 | DBusMessage *reply = dbus_pending_call_steal_reply(pending); | ||
107 | |||
108 | if (!reply) { | ||
109 | sway_log(L_ERROR, "Got no object path items reply from sni watcher"); | ||
110 | goto bail; | ||
111 | } | ||
112 | |||
113 | int message_type = dbus_message_get_type(reply); | ||
114 | |||
115 | if (message_type == DBUS_MESSAGE_TYPE_ERROR) { | ||
116 | char *msg; | ||
117 | |||
118 | dbus_message_get_args(reply, NULL, | ||
119 | DBUS_TYPE_STRING, &msg, | ||
120 | DBUS_TYPE_INVALID); | ||
121 | |||
122 | sway_log(L_ERROR, "Message is error: %s", msg); | ||
123 | goto bail; | ||
124 | } | ||
125 | |||
126 | DBusMessageIter iter; | ||
127 | DBusMessageIter variant; | ||
128 | DBusMessageIter array; | ||
129 | DBusMessageIter dstruct; | ||
130 | |||
131 | dbus_message_iter_init(reply, &iter); | ||
132 | if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { | ||
133 | sway_log(L_ERROR, "Replyed with wrong type, not v(a(os))"); | ||
134 | goto bail; | ||
135 | } | ||
136 | dbus_message_iter_recurse(&iter, &variant); | ||
137 | if (strcmp(dbus_message_iter_get_signature(&variant), "a(os)") != 0) { | ||
138 | sway_log(L_ERROR, "Replyed with wrong type not a(os)"); | ||
139 | goto bail; | ||
140 | } | ||
141 | |||
142 | int len = dbus_message_iter_get_element_count(&variant); | ||
143 | |||
144 | dbus_message_iter_recurse(&variant, &array); | ||
145 | for (int i = 0; i < len; i++) { | ||
146 | const char *object_path; | ||
147 | const char *unique_name; | ||
148 | |||
149 | dbus_message_iter_recurse(&array, &dstruct); | ||
150 | |||
151 | dbus_message_iter_get_basic(&dstruct, &object_path); | ||
152 | dbus_message_iter_get_basic(&dstruct, &unique_name); | ||
153 | |||
154 | struct StatusNotifierItem *item = | ||
155 | sni_create_from_obj_path(unique_name, object_path); | ||
156 | |||
157 | if (item) { | ||
158 | sway_log(L_DEBUG, "Item registered with host: %s", unique_name); | ||
159 | list_add(tray->items, item); | ||
160 | dirty = true; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | bail: | ||
165 | dbus_message_unref(reply); | ||
166 | dbus_pending_call_unref(pending); | ||
167 | } | ||
168 | |||
105 | static void get_items() { | 169 | static void get_items() { |
106 | DBusPendingCall *pending; | 170 | DBusPendingCall *pending; |
107 | DBusMessage *message = dbus_message_new_method_call( | 171 | DBusMessage *message = dbus_message_new_method_call( |
@@ -127,6 +191,28 @@ static void get_items() { | |||
127 | } | 191 | } |
128 | 192 | ||
129 | dbus_pending_call_set_notify(pending, get_items_reply, NULL, NULL); | 193 | dbus_pending_call_set_notify(pending, get_items_reply, NULL, NULL); |
194 | |||
195 | message = dbus_message_new_method_call( | ||
196 | "org.freedesktop.StatusNotifierWatcher", | ||
197 | "/StatusNotifierWatcher", | ||
198 | "org.freedesktop.DBus.Properties", | ||
199 | "Get"); | ||
200 | |||
201 | iface = "org.swaywm.LessSuckyStatusNotifierWatcher"; | ||
202 | prop = "RegisteredObjectPathItems"; | ||
203 | dbus_message_append_args(message, | ||
204 | DBUS_TYPE_STRING, &iface, | ||
205 | DBUS_TYPE_STRING, &prop, | ||
206 | DBUS_TYPE_INVALID); | ||
207 | |||
208 | status = dbus_connection_send_with_reply(conn, message, &pending, -1); | ||
209 | dbus_message_unref(message); | ||
210 | |||
211 | if (!(pending || status)) { | ||
212 | sway_log(L_ERROR, "Could not get items"); | ||
213 | return; | ||
214 | } | ||
215 | dbus_pending_call_set_notify(pending, get_obj_items_reply, NULL, NULL); | ||
130 | } | 216 | } |
131 | 217 | ||
132 | static DBusHandlerResult signal_handler(DBusConnection *connection, | 218 | static DBusHandlerResult signal_handler(DBusConnection *connection, |
@@ -162,11 +248,14 @@ static DBusHandlerResult signal_handler(DBusConnection *connection, | |||
162 | } | 248 | } |
163 | 249 | ||
164 | int index; | 250 | int index; |
165 | if ((index = list_seq_find(tray->items, sni_str_cmp, name)) != -1) { | 251 | bool found_item = false; |
252 | while ((index = list_seq_find(tray->items, sni_str_cmp, name)) != -1) { | ||
253 | found_item = true; | ||
166 | sni_free(tray->items->items[index]); | 254 | sni_free(tray->items->items[index]); |
167 | list_del(tray->items, index); | 255 | list_del(tray->items, index); |
168 | dirty = true; | 256 | dirty = true; |
169 | } else { | 257 | } |
258 | if (found_item == false) { | ||
170 | // If it's not in our list, then our list is incorrect. | 259 | // If it's not in our list, then our list is incorrect. |
171 | // Fetch all items again | 260 | // Fetch all items again |
172 | sway_log(L_INFO, "Host item list incorrect, refreshing"); | 261 | sway_log(L_INFO, "Host item list incorrect, refreshing"); |
@@ -189,6 +278,32 @@ static DBusHandlerResult signal_handler(DBusConnection *connection, | |||
189 | } | 278 | } |
190 | 279 | ||
191 | return DBUS_HANDLER_RESULT_HANDLED; | 280 | return DBUS_HANDLER_RESULT_HANDLED; |
281 | } else if (dbus_message_is_signal(message, | ||
282 | "org.swaywm.LessSuckyStatusNotifierWatcher", | ||
283 | "ObjPathItemRegistered")) { | ||
284 | const char *object_path; | ||
285 | const char *unique_name; | ||
286 | if (!dbus_message_get_args(message, NULL, | ||
287 | DBUS_TYPE_OBJECT_PATH, &object_path, | ||
288 | DBUS_TYPE_STRING, &unique_name, | ||
289 | DBUS_TYPE_INVALID)) { | ||
290 | sway_log(L_ERROR, "Error getting ObjPathItemRegistered args"); | ||
291 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | ||
292 | } | ||
293 | |||
294 | // TODO allow one unique name to have multiple items | ||
295 | if (list_seq_find(tray->items, sni_str_cmp, unique_name) == -1) { | ||
296 | struct StatusNotifierItem *item = | ||
297 | sni_create_from_obj_path(unique_name, | ||
298 | object_path); | ||
299 | |||
300 | if (item) { | ||
301 | list_add(tray->items, item); | ||
302 | dirty = true; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | return DBUS_HANDLER_RESULT_HANDLED; | ||
192 | } | 307 | } |
193 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | 308 | return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
194 | } | 309 | } |
@@ -255,6 +370,15 @@ static int init_host() { | |||
255 | sway_log(L_ERROR, "dbus_err: %s", error.message); | 370 | sway_log(L_ERROR, "dbus_err: %s", error.message); |
256 | return -1; | 371 | return -1; |
257 | } | 372 | } |
373 | dbus_bus_add_match(conn, | ||
374 | "type='signal',\ | ||
375 | sender='org.freedesktop.StatusNotifierWatcher',\ | ||
376 | member='ObjPathItemRegistered'", | ||
377 | &error); | ||
378 | if (dbus_error_is_set(&error)) { | ||
379 | sway_log(L_ERROR, "dbus_err: %s", error.message); | ||
380 | return -1; | ||
381 | } | ||
258 | 382 | ||
259 | // SNI matches | 383 | // SNI matches |
260 | dbus_bus_add_match(conn, | 384 | dbus_bus_add_match(conn, |