summaryrefslogtreecommitdiffstats
path: root/swaybar/tray/tray.c
diff options
context:
space:
mode:
Diffstat (limited to 'swaybar/tray/tray.c')
-rw-r--r--swaybar/tray/tray.c128
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}
105static 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
164bail:
165 dbus_message_unref(reply);
166 dbus_pending_call_unref(pending);
167}
168
105static void get_items() { 169static 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
132static DBusHandlerResult signal_handler(DBusConnection *connection, 218static 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,