diff options
-rw-r--r-- | include/swaybar/tray/dbus.h | 14 | ||||
-rw-r--r-- | swaybar/tray/dbus.c | 10 | ||||
-rw-r--r-- | swaybar/tray/sni.c | 30 | ||||
-rw-r--r-- | swaybar/tray/tray.c | 10 |
4 files changed, 47 insertions, 17 deletions
diff --git a/include/swaybar/tray/dbus.h b/include/swaybar/tray/dbus.h index 125ce96f..c693e6f7 100644 --- a/include/swaybar/tray/dbus.h +++ b/include/swaybar/tray/dbus.h | |||
@@ -5,6 +5,13 @@ | |||
5 | #include <dbus/dbus.h> | 5 | #include <dbus/dbus.h> |
6 | extern DBusConnection *conn; | 6 | extern DBusConnection *conn; |
7 | 7 | ||
8 | enum property_status { | ||
9 | PROP_EXISTS, /* Will give iter */ | ||
10 | PROP_ERROR, /* Will not give iter */ | ||
11 | PROP_BAD_DATA, /* Will not give iter */ | ||
12 | PROP_WRONG_SIG, /* Will give iter, please be careful */ | ||
13 | }; | ||
14 | |||
8 | /** | 15 | /** |
9 | * Checks the signature of the given iter against `sig`. Prefer to | 16 | * Checks the signature of the given iter against `sig`. Prefer to |
10 | * `dbus_message_iter_get_signature` as this one frees the intermediate string. | 17 | * `dbus_message_iter_get_signature` as this one frees the intermediate string. |
@@ -15,8 +22,9 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig); | |||
15 | * Fetches the property and calls `callback` with a message iter pointing it. | 22 | * Fetches the property and calls `callback` with a message iter pointing it. |
16 | * Performs error handling and signature checking. | 23 | * Performs error handling and signature checking. |
17 | * | 24 | * |
18 | * Returns: true if message is successfully sent (will not necessarily arrive) | 25 | * Returns: true if message is successfully sent and false otherwise. If there |
19 | * and false otherwise | 26 | * is an error getting a property, `callback` will still be run, but with |
27 | * `status` set to the error. | ||
20 | * | 28 | * |
21 | * NOTE: `expected_signature` must remain valid until the message reply is | 29 | * NOTE: `expected_signature` must remain valid until the message reply is |
22 | * received, please only use 'static signatures. | 30 | * received, please only use 'static signatures. |
@@ -26,7 +34,7 @@ bool dbus_get_prop_async(const char *destination, | |||
26 | const char *iface, | 34 | const char *iface, |
27 | const char *prop, | 35 | const char *prop, |
28 | const char *expected_signature, | 36 | const char *expected_signature, |
29 | void(*callback)(DBusMessageIter *iter, void *data), | 37 | void(*callback)(DBusMessageIter *iter, void *data, enum property_status status), |
30 | void *data); | 38 | void *data); |
31 | /** | 39 | /** |
32 | * Should be called in main loop to dispatch events | 40 | * Should be called in main loop to dispatch events |
diff --git a/swaybar/tray/dbus.c b/swaybar/tray/dbus.c index 4439fb83..08abf65c 100644 --- a/swaybar/tray/dbus.c +++ b/swaybar/tray/dbus.c | |||
@@ -138,7 +138,7 @@ static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_s | |||
138 | 138 | ||
139 | struct async_prop_data { | 139 | struct async_prop_data { |
140 | char const *sig; | 140 | char const *sig; |
141 | void(*callback)(DBusMessageIter *, void *); | 141 | void(*callback)(DBusMessageIter *, void *, enum property_status); |
142 | void *usr_data; | 142 | void *usr_data; |
143 | }; | 143 | }; |
144 | 144 | ||
@@ -160,6 +160,7 @@ static void get_prop_callback(DBusPendingCall *pending, void *_data) { | |||
160 | DBUS_TYPE_INVALID); | 160 | DBUS_TYPE_INVALID); |
161 | 161 | ||
162 | sway_log(L_INFO, "Failure to get property: %s", msg); | 162 | sway_log(L_INFO, "Failure to get property: %s", msg); |
163 | data->callback(NULL, data->usr_data, PROP_ERROR); | ||
163 | goto bail; | 164 | goto bail; |
164 | } | 165 | } |
165 | 166 | ||
@@ -169,16 +170,18 @@ static void get_prop_callback(DBusPendingCall *pending, void *_data) { | |||
169 | dbus_message_iter_init(reply, &iter); | 170 | dbus_message_iter_init(reply, &iter); |
170 | if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { | 171 | if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) { |
171 | sway_log(L_ERROR, "Property relpy type incorrect"); | 172 | sway_log(L_ERROR, "Property relpy type incorrect"); |
173 | data->callback(NULL, data->usr_data, PROP_BAD_DATA); | ||
172 | goto bail; | 174 | goto bail; |
173 | } | 175 | } |
174 | dbus_message_iter_recurse(&iter, &variant); | 176 | dbus_message_iter_recurse(&iter, &variant); |
175 | 177 | ||
176 | if (!dbus_message_iter_check_signature(&variant, data->sig)) { | 178 | if (!dbus_message_iter_check_signature(&variant, data->sig)) { |
177 | sway_log(L_INFO, "Property returned has incorrect signatue."); | 179 | sway_log(L_INFO, "Property returned has incorrect signatue."); |
180 | data->callback(&variant, data->usr_data, PROP_WRONG_SIG); | ||
178 | goto bail; | 181 | goto bail; |
179 | } | 182 | } |
180 | 183 | ||
181 | data->callback(&variant, data->usr_data); | 184 | data->callback(&variant, data->usr_data, PROP_EXISTS); |
182 | 185 | ||
183 | bail: | 186 | bail: |
184 | if (reply) { | 187 | if (reply) { |
@@ -199,7 +202,8 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { | |||
199 | bool dbus_get_prop_async(const char *destination, | 202 | bool dbus_get_prop_async(const char *destination, |
200 | const char *path, const char *iface, | 203 | const char *path, const char *iface, |
201 | const char *prop, const char *expected_signature, | 204 | const char *prop, const char *expected_signature, |
202 | void(*callback)(DBusMessageIter *, void *), void *usr_data) { | 205 | void(*callback)(DBusMessageIter *, void *, enum property_status), |
206 | void *usr_data) { | ||
203 | struct async_prop_data *data = malloc(sizeof(struct async_prop_data)); | 207 | struct async_prop_data *data = malloc(sizeof(struct async_prop_data)); |
204 | if (!data) { | 208 | if (!data) { |
205 | return false; | 209 | return false; |
diff --git a/swaybar/tray/sni.c b/swaybar/tray/sni.c index 200422da..98934e11 100644 --- a/swaybar/tray/sni.c +++ b/swaybar/tray/sni.c | |||
@@ -41,11 +41,15 @@ void sni_icon_ref_free(struct sni_icon_ref *sni_ref) { | |||
41 | } | 41 | } |
42 | 42 | ||
43 | /* Gets the pixmap of an icon */ | 43 | /* Gets the pixmap of an icon */ |
44 | static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) { | 44 | static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data, enum property_status status) { |
45 | if (status != PROP_EXISTS) { | ||
46 | return; | ||
47 | } | ||
45 | struct StatusNotifierItem *item = _data; | 48 | struct StatusNotifierItem *item = _data; |
46 | 49 | ||
47 | DBusMessageIter d_struct; /* (iiay) */ | 50 | DBusMessageIter d_struct; /* (iiay) */ |
48 | DBusMessageIter icon; /* ay */ | 51 | DBusMessageIter struct_items; |
52 | DBusMessageIter icon; | ||
49 | 53 | ||
50 | if (dbus_message_iter_get_element_count(iter) == 0) { | 54 | if (dbus_message_iter_get_element_count(iter) == 0) { |
51 | // Can't recurse if there are no items | 55 | // Can't recurse if there are no items |
@@ -54,16 +58,17 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) { | |||
54 | } | 58 | } |
55 | 59 | ||
56 | dbus_message_iter_recurse(iter, &d_struct); | 60 | dbus_message_iter_recurse(iter, &d_struct); |
61 | dbus_message_iter_recurse(&d_struct, &struct_items); | ||
57 | 62 | ||
58 | int width; | 63 | int width; |
59 | dbus_message_iter_get_basic(&d_struct, &width); | 64 | dbus_message_iter_get_basic(&struct_items, &width); |
60 | dbus_message_iter_next(&d_struct); | 65 | dbus_message_iter_next(&struct_items); |
61 | 66 | ||
62 | int height; | 67 | int height; |
63 | dbus_message_iter_get_basic(&d_struct, &height); | 68 | dbus_message_iter_get_basic(&struct_items, &height); |
64 | dbus_message_iter_next(&d_struct); | 69 | dbus_message_iter_next(&struct_items); |
65 | 70 | ||
66 | int len = dbus_message_iter_get_element_count(&d_struct); | 71 | int len = dbus_message_iter_get_element_count(&struct_items); |
67 | 72 | ||
68 | if (!len) { | 73 | if (!len) { |
69 | sway_log(L_ERROR, "No icon data"); | 74 | sway_log(L_ERROR, "No icon data"); |
@@ -76,7 +81,7 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) { | |||
76 | return; | 81 | return; |
77 | } | 82 | } |
78 | 83 | ||
79 | dbus_message_iter_recurse(&d_struct, &icon); | 84 | dbus_message_iter_recurse(&struct_items, &icon); |
80 | 85 | ||
81 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); | 86 | int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); |
82 | // FIXME support a variable stride | 87 | // FIXME support a variable stride |
@@ -131,9 +136,16 @@ static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) { | |||
131 | } | 136 | } |
132 | 137 | ||
133 | /* Get an icon by its name */ | 138 | /* Get an icon by its name */ |
134 | static void reply_icon_name(DBusMessageIter *iter, void *_data) { | 139 | static void reply_icon_name(DBusMessageIter *iter, void *_data, enum property_status status) { |
135 | struct StatusNotifierItem *item = _data; | 140 | struct StatusNotifierItem *item = _data; |
136 | 141 | ||
142 | if (status != PROP_EXISTS) { | ||
143 | dbus_get_prop_async(item->name, item->object_path, | ||
144 | (item->kde_special_snowflake ? KDE_IFACE : FD_IFACE), | ||
145 | "IconPixmap", "a(iiay)", reply_icon, item); | ||
146 | return; | ||
147 | } | ||
148 | |||
137 | char *icon_name; | 149 | char *icon_name; |
138 | dbus_message_iter_get_basic(iter, &icon_name); | 150 | dbus_message_iter_get_basic(iter, &icon_name); |
139 | 151 | ||
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c index 89e7c3e2..3c5492f7 100644 --- a/swaybar/tray/tray.c +++ b/swaybar/tray/tray.c | |||
@@ -38,7 +38,10 @@ static void register_host(char *name) { | |||
38 | dbus_message_unref(message); | 38 | dbus_message_unref(message); |
39 | } | 39 | } |
40 | 40 | ||
41 | static void get_items_reply(DBusMessageIter *iter, void *_data) { | 41 | static void get_items_reply(DBusMessageIter *iter, void *_data, enum property_status status) { |
42 | if (status != PROP_EXISTS) { | ||
43 | return; | ||
44 | } | ||
42 | DBusMessageIter array; | 45 | DBusMessageIter array; |
43 | 46 | ||
44 | // O(n) function, could be faster dynamically reading values | 47 | // O(n) function, could be faster dynamically reading values |
@@ -60,7 +63,10 @@ static void get_items_reply(DBusMessageIter *iter, void *_data) { | |||
60 | } | 63 | } |
61 | } | 64 | } |
62 | } | 65 | } |
63 | static void get_obj_items_reply(DBusMessageIter *iter, void *_data) { | 66 | static void get_obj_items_reply(DBusMessageIter *iter, void *_data, enum property_status status) { |
67 | if (status != PROP_EXISTS) { | ||
68 | return; | ||
69 | } | ||
64 | DBusMessageIter array; | 70 | DBusMessageIter array; |
65 | DBusMessageIter dstruct; | 71 | DBusMessageIter dstruct; |
66 | 72 | ||