summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Calvin Lee <cyrus296@gmail.com>2017-11-09 12:58:32 -0700
committerLibravatar Calvin Lee <cyrus296@gmail.com>2017-12-29 12:11:51 -0700
commit87035380e33c7da10b53c6da713c56f3d89a1577 (patch)
tree4b31ad282fe07227f5720928b1ba07715bc7ea48
parentPlug memory `dbus_message_iter_get_signature` leak (diff)
downloadsway-87035380e33c7da10b53c6da713c56f3d89a1577.tar.gz
sway-87035380e33c7da10b53c6da713c56f3d89a1577.tar.zst
sway-87035380e33c7da10b53c6da713c56f3d89a1577.zip
Add `dbus_get_prop_async` utility
This drastically reduces the amount of boilerplate needed to get a property from a bus object.
-rw-r--r--include/swaybar/tray/dbus.h17
-rw-r--r--swaybar/tray/dbus.c90
-rw-r--r--swaybar/tray/sni.c184
-rw-r--r--swaybar/tray/tray.c139
4 files changed, 137 insertions, 293 deletions
diff --git a/include/swaybar/tray/dbus.h b/include/swaybar/tray/dbus.h
index 51754464..125ce96f 100644
--- a/include/swaybar/tray/dbus.h
+++ b/include/swaybar/tray/dbus.h
@@ -12,6 +12,23 @@ extern DBusConnection *conn;
12bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig); 12bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig);
13 13
14/** 14/**
15 * Fetches the property and calls `callback` with a message iter pointing it.
16 * Performs error handling and signature checking.
17 *
18 * Returns: true if message is successfully sent (will not necessarily arrive)
19 * and false otherwise
20 *
21 * NOTE: `expected_signature` must remain valid until the message reply is
22 * received, please only use 'static signatures.
23 */
24bool dbus_get_prop_async(const char *destination,
25 const char *path,
26 const char *iface,
27 const char *prop,
28 const char *expected_signature,
29 void(*callback)(DBusMessageIter *iter, void *data),
30 void *data);
31/**
15 * Should be called in main loop to dispatch events 32 * Should be called in main loop to dispatch events
16 */ 33 */
17void dispatch_dbus(); 34void dispatch_dbus();
diff --git a/swaybar/tray/dbus.c b/swaybar/tray/dbus.c
index 46a1c807..4439fb83 100644
--- a/swaybar/tray/dbus.c
+++ b/swaybar/tray/dbus.c
@@ -136,7 +136,58 @@ static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_s
136 } 136 }
137} 137}
138 138
139/* Public functions below */ 139struct async_prop_data {
140 char const *sig;
141 void(*callback)(DBusMessageIter *, void *);
142 void *usr_data;
143};
144
145static void get_prop_callback(DBusPendingCall *pending, void *_data) {
146 struct async_prop_data *data = _data;
147
148 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
149
150 if (!reply) {
151 sway_log(L_INFO, "Got no icon name reply from item");
152 goto bail;
153 }
154
155 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
156 char *msg;
157
158 dbus_message_get_args(reply, NULL,
159 DBUS_TYPE_STRING, &msg,
160 DBUS_TYPE_INVALID);
161
162 sway_log(L_INFO, "Failure to get property: %s", msg);
163 goto bail;
164 }
165
166 DBusMessageIter iter;
167 DBusMessageIter variant;
168
169 dbus_message_iter_init(reply, &iter);
170 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
171 sway_log(L_ERROR, "Property relpy type incorrect");
172 goto bail;
173 }
174 dbus_message_iter_recurse(&iter, &variant);
175
176 if (!dbus_message_iter_check_signature(&variant, data->sig)) {
177 sway_log(L_INFO, "Property returned has incorrect signatue.");
178 goto bail;
179 }
180
181 data->callback(&variant, data->usr_data);
182
183bail:
184 if (reply) {
185 dbus_message_unref(reply);
186 }
187 dbus_pending_call_unref(pending);
188}
189
190/* Public functions below -- see header for docs*/
140 191
141bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) { 192bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) {
142 char *msg_sig = dbus_message_iter_get_signature(iter); 193 char *msg_sig = dbus_message_iter_get_signature(iter);
@@ -145,6 +196,43 @@ bool dbus_message_iter_check_signature(DBusMessageIter *iter, const char *sig) {
145 return (result == 0); 196 return (result == 0);
146} 197}
147 198
199bool dbus_get_prop_async(const char *destination,
200 const char *path, const char *iface,
201 const char *prop, const char *expected_signature,
202 void(*callback)(DBusMessageIter *, void *), void *usr_data) {
203 struct async_prop_data *data = malloc(sizeof(struct async_prop_data));
204 if (!data) {
205 return false;
206 }
207 DBusPendingCall *pending;
208 DBusMessage *message = dbus_message_new_method_call(
209 destination, path,
210 "org.freedesktop.DBus.Properties",
211 "Get");
212
213 dbus_message_append_args(message,
214 DBUS_TYPE_STRING, &iface,
215 DBUS_TYPE_STRING, &prop,
216 DBUS_TYPE_INVALID);
217
218 bool status =
219 dbus_connection_send_with_reply(conn, message, &pending, -1);
220
221 dbus_message_unref(message);
222
223 if (!(pending || status)) {
224 sway_log(L_ERROR, "Could not get property");
225 return false;
226 }
227
228 data->sig = expected_signature;
229 data->callback = callback;
230 data->usr_data = usr_data;
231 dbus_pending_call_set_notify(pending, get_prop_callback, data, free);
232
233 return true;
234}
235
148void dispatch_dbus() { 236void dispatch_dbus() {
149 if (!should_dispatch || !conn) { 237 if (!should_dispatch || !conn) {
150 return; 238 return;
diff --git a/swaybar/tray/sni.c b/swaybar/tray/sni.c
index 401a0091..200422da 100644
--- a/swaybar/tray/sni.c
+++ b/swaybar/tray/sni.c
@@ -14,6 +14,9 @@
14#include "client/cairo.h" 14#include "client/cairo.h"
15#include "log.h" 15#include "log.h"
16 16
17static const char *KDE_IFACE = "org.kde.StatusNotifierItem";
18static const char *FD_IFACE = "org.freedesktop.StatusNotifierItem";
19
17// Not sure what this is but cairo needs it. 20// Not sure what this is but cairo needs it.
18static const cairo_user_data_key_t cairo_user_data_key; 21static const cairo_user_data_key_t cairo_user_data_key;
19 22
@@ -38,57 +41,19 @@ void sni_icon_ref_free(struct sni_icon_ref *sni_ref) {
38} 41}
39 42
40/* Gets the pixmap of an icon */ 43/* Gets the pixmap of an icon */
41static void reply_icon(DBusPendingCall *pending, void *_data) { 44static void reply_icon(DBusMessageIter *iter /* a(iiay) */, void *_data) {
42 struct StatusNotifierItem *item = _data; 45 struct StatusNotifierItem *item = _data;
43 46
44 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
45
46 if (!reply) {
47 sway_log(L_ERROR, "Did not get reply");
48 goto bail;
49 }
50
51 int message_type = dbus_message_get_type(reply);
52
53 if (message_type == DBUS_MESSAGE_TYPE_ERROR) {
54 char *msg;
55
56 dbus_message_get_args(reply, NULL,
57 DBUS_TYPE_STRING, &msg,
58 DBUS_TYPE_INVALID);
59
60 sway_log(L_ERROR, "Message is error: %s", msg);
61 goto bail;
62 }
63
64 DBusMessageIter iter;
65 DBusMessageIter variant; /* v[a(iiay)] */
66 DBusMessageIter array; /* a(iiay) */
67 DBusMessageIter d_struct; /* (iiay) */ 47 DBusMessageIter d_struct; /* (iiay) */
68 DBusMessageIter icon; /* ay */ 48 DBusMessageIter icon; /* ay */
69 49
70 dbus_message_iter_init(reply, &iter); 50 if (dbus_message_iter_get_element_count(iter) == 0) {
71
72 // Each if here checks the types above before recursing
73 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
74 sway_log(L_ERROR, "Icon relpy type incorrect");
75 goto bail;
76 }
77 dbus_message_iter_recurse(&iter, &variant);
78
79 if (dbus_message_iter_check_signature(&variant, "a(iiay)")) {
80 sway_log(L_ERROR, "Icon relpy type incorrect");
81 goto bail;
82 }
83
84 if (dbus_message_iter_get_element_count(&variant) == 0) {
85 // Can't recurse if there are no items 51 // Can't recurse if there are no items
86 sway_log(L_INFO, "Item has no icon"); 52 sway_log(L_INFO, "Item has no icon");
87 goto bail; 53 return;
88 } 54 }
89 dbus_message_iter_recurse(&variant, &array);
90 55
91 dbus_message_iter_recurse(&array, &d_struct); 56 dbus_message_iter_recurse(iter, &d_struct);
92 57
93 int width; 58 int width;
94 dbus_message_iter_get_basic(&d_struct, &width); 59 dbus_message_iter_get_basic(&d_struct, &width);
@@ -102,13 +67,13 @@ static void reply_icon(DBusPendingCall *pending, void *_data) {
102 67
103 if (!len) { 68 if (!len) {
104 sway_log(L_ERROR, "No icon data"); 69 sway_log(L_ERROR, "No icon data");
105 goto bail; 70 return;
106 } 71 }
107 72
108 // Also implies len % 4 == 0, useful below 73 // Also implies len % 4 == 0, useful below
109 if (len != width * height * 4) { 74 if (len != width * height * 4) {
110 sway_log(L_ERROR, "Incorrect array size passed"); 75 sway_log(L_ERROR, "Incorrect array size passed");
111 goto bail; 76 return;
112 } 77 }
113 78
114 dbus_message_iter_recurse(&d_struct, &icon); 79 dbus_message_iter_recurse(&d_struct, &icon);
@@ -117,7 +82,7 @@ static void reply_icon(DBusPendingCall *pending, void *_data) {
117 // FIXME support a variable stride 82 // FIXME support a variable stride
118 // (works on my machine though for all tested widths) 83 // (works on my machine though for all tested widths)
119 if (!sway_assert(stride == width * 4, "Stride must be equal to byte length")) { 84 if (!sway_assert(stride == width * 4, "Stride must be equal to byte length")) {
120 goto bail; 85 return;
121 } 86 }
122 87
123 // Data is by reference, no need to free 88 // Data is by reference, no need to free
@@ -127,7 +92,7 @@ static void reply_icon(DBusPendingCall *pending, void *_data) {
127 uint8_t *image_data = malloc(stride * height); 92 uint8_t *image_data = malloc(stride * height);
128 if (!image_data) { 93 if (!image_data) {
129 sway_log(L_ERROR, "Could not allocate memory for icon"); 94 sway_log(L_ERROR, "Could not allocate memory for icon");
130 goto bail; 95 return;
131 } 96 }
132 97
133 // Transform from network byte order to host byte order 98 // Transform from network byte order to host byte order
@@ -155,97 +120,22 @@ static void reply_icon(DBusPendingCall *pending, void *_data) {
155 item->dirty = true; 120 item->dirty = true;
156 dirty = true; 121 dirty = true;
157 122
158 dbus_message_unref(reply);
159 dbus_pending_call_unref(pending);
160 return; 123 return;
161 } else { 124 } else {
162 sway_log(L_ERROR, "Could not create image surface"); 125 sway_log(L_ERROR, "Could not create image surface");
163 free(image_data); 126 free(image_data);
164 } 127 }
165 128
166bail:
167 if (reply) {
168 dbus_message_unref(reply);
169 }
170 dbus_pending_call_unref(pending);
171 sway_log(L_ERROR, "Could not get icon from item"); 129 sway_log(L_ERROR, "Could not get icon from item");
172 return; 130 return;
173} 131}
174static void send_icon_msg(struct StatusNotifierItem *item) {
175 DBusPendingCall *pending;
176 DBusMessage *message = dbus_message_new_method_call(
177 item->name,
178 item->object_path,
179 "org.freedesktop.DBus.Properties",
180 "Get");
181 const char *iface;
182 if (item->kde_special_snowflake) {
183 iface = "org.kde.StatusNotifierItem";
184 } else {
185 iface = "org.freedesktop.StatusNotifierItem";
186 }
187 const char *prop = "IconPixmap";
188
189 dbus_message_append_args(message,
190 DBUS_TYPE_STRING, &iface,
191 DBUS_TYPE_STRING, &prop,
192 DBUS_TYPE_INVALID);
193
194 bool status =
195 dbus_connection_send_with_reply(conn, message, &pending, -1);
196
197 dbus_message_unref(message);
198
199 if (!(pending || status)) {
200 sway_log(L_ERROR, "Could not get item icon");
201 return;
202 }
203
204 dbus_pending_call_set_notify(pending, reply_icon, item, NULL);
205}
206 132
207/* Get an icon by its name */ 133/* Get an icon by its name */
208static void reply_icon_name(DBusPendingCall *pending, void *_data) { 134static void reply_icon_name(DBusMessageIter *iter, void *_data) {
209 struct StatusNotifierItem *item = _data; 135 struct StatusNotifierItem *item = _data;
210 136
211 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
212
213 if (!reply) {
214 sway_log(L_INFO, "Got no icon name reply from item");
215 goto bail;
216 }
217
218 int message_type = dbus_message_get_type(reply);
219
220 if (message_type == DBUS_MESSAGE_TYPE_ERROR) {
221 char *msg;
222
223 dbus_message_get_args(reply, NULL,
224 DBUS_TYPE_STRING, &msg,
225 DBUS_TYPE_INVALID);
226
227 sway_log(L_INFO, "Could not get icon name: %s", msg);
228 goto bail;
229 }
230
231 DBusMessageIter iter; /* v[s] */
232 DBusMessageIter variant; /* s */
233
234 dbus_message_iter_init(reply, &iter);
235 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
236 sway_log(L_ERROR, "Icon name relpy type incorrect");
237 goto bail;
238 }
239 dbus_message_iter_recurse(&iter, &variant);
240
241
242 if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_STRING) {
243 sway_log(L_ERROR, "Icon name relpy type incorrect");
244 goto bail;
245 }
246
247 char *icon_name; 137 char *icon_name;
248 dbus_message_iter_get_basic(&variant, &icon_name); 138 dbus_message_iter_get_basic(iter, &icon_name);
249 139
250 cairo_surface_t *image = find_icon(icon_name, 256); 140 cairo_surface_t *image = find_icon(icon_name, 256);
251 141
@@ -259,55 +149,19 @@ static void reply_icon_name(DBusPendingCall *pending, void *_data) {
259 item->dirty = true; 149 item->dirty = true;
260 dirty = true; 150 dirty = true;
261 151
262 dbus_message_unref(reply);
263 dbus_pending_call_unref(pending);
264 return; 152 return;
265 } 153 }
266 154
267bail:
268 if (reply) {
269 dbus_message_unref(reply);
270 }
271 dbus_pending_call_unref(pending);
272 // Now try the pixmap 155 // Now try the pixmap
273 send_icon_msg(item); 156 dbus_get_prop_async(item->name, item->object_path,
274 return; 157 (item->kde_special_snowflake ? KDE_IFACE : FD_IFACE),
275} 158 "IconPixmap", "a(iiay)", reply_icon, item);
276static void send_icon_name_msg(struct StatusNotifierItem *item) {
277 DBusPendingCall *pending;
278 DBusMessage *message = dbus_message_new_method_call(
279 item->name,
280 item->object_path,
281 "org.freedesktop.DBus.Properties",
282 "Get");
283 const char *iface;
284 if (item->kde_special_snowflake) {
285 iface = "org.kde.StatusNotifierItem";
286 } else {
287 iface = "org.freedesktop.StatusNotifierItem";
288 }
289 const char *prop = "IconName";
290
291 dbus_message_append_args(message,
292 DBUS_TYPE_STRING, &iface,
293 DBUS_TYPE_STRING, &prop,
294 DBUS_TYPE_INVALID);
295
296 bool status =
297 dbus_connection_send_with_reply(conn, message, &pending, -1);
298
299 dbus_message_unref(message);
300
301 if (!(pending || status)) {
302 sway_log(L_ERROR, "Could not get item icon name");
303 return;
304 }
305
306 dbus_pending_call_set_notify(pending, reply_icon_name, item, NULL);
307} 159}
308 160
309void get_icon(struct StatusNotifierItem *item) { 161void get_icon(struct StatusNotifierItem *item) {
310 send_icon_name_msg(item); 162 dbus_get_prop_async(item->name, item->object_path,
163 (item->kde_special_snowflake ? KDE_IFACE : FD_IFACE),
164 "IconName", "s", reply_icon_name, item);
311} 165}
312 166
313void sni_activate(struct StatusNotifierItem *item, uint32_t x, uint32_t y) { 167void sni_activate(struct StatusNotifierItem *item, uint32_t x, uint32_t y) {
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c
index f1ecb429..89e7c3e2 100644
--- a/swaybar/tray/tray.c
+++ b/swaybar/tray/tray.c
@@ -38,47 +38,13 @@ static void register_host(char *name) {
38 dbus_message_unref(message); 38 dbus_message_unref(message);
39} 39}
40 40
41static void get_items_reply(DBusPendingCall *pending, void *_data) { 41static void get_items_reply(DBusMessageIter *iter, void *_data) {
42 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
43
44 if (!reply) {
45 sway_log(L_ERROR, "Got no items reply from sni watcher");
46 goto bail;
47 }
48
49 int message_type = dbus_message_get_type(reply);
50
51 if (message_type == DBUS_MESSAGE_TYPE_ERROR) {
52 char *msg;
53
54 dbus_message_get_args(reply, NULL,
55 DBUS_TYPE_STRING, &msg,
56 DBUS_TYPE_INVALID);
57
58 sway_log(L_ERROR, "Message is error: %s", msg);
59 goto bail;
60 }
61
62 DBusMessageIter iter;
63 DBusMessageIter variant;
64 DBusMessageIter array; 42 DBusMessageIter array;
65 43
66 dbus_message_iter_init(reply, &iter);
67 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
68 sway_log(L_ERROR, "Replyed with wrong type, not v(as)");
69 goto bail;
70 }
71 dbus_message_iter_recurse(&iter, &variant);
72 if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_ARRAY ||
73 dbus_message_iter_get_element_type(&variant) != DBUS_TYPE_STRING) {
74 sway_log(L_ERROR, "Replyed with wrong type, not v(as)");
75 goto bail;
76 }
77
78 // O(n) function, could be faster dynamically reading values 44 // O(n) function, could be faster dynamically reading values
79 int len = dbus_message_iter_get_element_count(&variant); 45 int len = dbus_message_iter_get_element_count(iter);
80 46
81 dbus_message_iter_recurse(&variant, &array); 47 dbus_message_iter_recurse(iter, &array);
82 for (int i = 0; i < len; i++) { 48 for (int i = 0; i < len; i++) {
83 const char *name; 49 const char *name;
84 dbus_message_iter_get_basic(&array, &name); 50 dbus_message_iter_get_basic(&array, &name);
@@ -93,52 +59,14 @@ static void get_items_reply(DBusPendingCall *pending, void *_data) {
93 } 59 }
94 } 60 }
95 } 61 }
96
97bail:
98 dbus_message_unref(reply);
99 dbus_pending_call_unref(pending);
100 return;
101} 62}
102static void get_obj_items_reply(DBusPendingCall *pending, void *_data) { 63static void get_obj_items_reply(DBusMessageIter *iter, void *_data) {
103 DBusMessage *reply = dbus_pending_call_steal_reply(pending);
104
105 if (!reply) {
106 sway_log(L_ERROR, "Got no object path items reply from sni watcher");
107 goto bail;
108 }
109
110 int message_type = dbus_message_get_type(reply);
111
112 if (message_type == DBUS_MESSAGE_TYPE_ERROR) {
113 char *msg;
114
115 dbus_message_get_args(reply, NULL,
116 DBUS_TYPE_STRING, &msg,
117 DBUS_TYPE_INVALID);
118
119 sway_log(L_ERROR, "Message is error: %s", msg);
120 goto bail;
121 }
122
123 DBusMessageIter iter;
124 DBusMessageIter variant;
125 DBusMessageIter array; 64 DBusMessageIter array;
126 DBusMessageIter dstruct; 65 DBusMessageIter dstruct;
127 66
128 dbus_message_iter_init(reply, &iter); 67 int len = dbus_message_iter_get_element_count(iter);
129 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) {
130 sway_log(L_ERROR, "Replyed with wrong type, not v(a(os))");
131 goto bail;
132 }
133 dbus_message_iter_recurse(&iter, &variant);
134 if (dbus_message_iter_check_signature(&iter, "a(os)")) {
135 sway_log(L_ERROR, "Replyed with wrong type not a(os)");
136 goto bail;
137 }
138
139 int len = dbus_message_iter_get_element_count(&variant);
140 68
141 dbus_message_iter_recurse(&variant, &array); 69 dbus_message_iter_recurse(iter, &array);
142 for (int i = 0; i < len; i++) { 70 for (int i = 0; i < len; i++) {
143 const char *object_path; 71 const char *object_path;
144 const char *unique_name; 72 const char *unique_name;
@@ -164,10 +92,6 @@ static void get_obj_items_reply(DBusPendingCall *pending, void *_data) {
164 } 92 }
165 } 93 }
166 } 94 }
167
168bail:
169 dbus_message_unref(reply);
170 dbus_pending_call_unref(pending);
171} 95}
172 96
173static void get_items() { 97static void get_items() {
@@ -176,52 +100,13 @@ static void get_items() {
176 list_free(tray->items); 100 list_free(tray->items);
177 tray->items = create_list(); 101 tray->items = create_list();
178 102
179 DBusPendingCall *pending; 103 dbus_get_prop_async("org.freedesktop.StatusNotifierWatcher",
180 DBusMessage *message = dbus_message_new_method_call( 104 "/StatusNotifierWatcher","org.freedesktop.StatusNotifierWatcher",
181 "org.freedesktop.StatusNotifierWatcher", 105 "RegisteredStatusNotifierItems", "as", get_items_reply, NULL);
182 "/StatusNotifierWatcher",
183 "org.freedesktop.DBus.Properties",
184 "Get");
185
186 const char *iface = "org.freedesktop.StatusNotifierWatcher";
187 const char *prop = "RegisteredStatusNotifierItems";
188 dbus_message_append_args(message,
189 DBUS_TYPE_STRING, &iface,
190 DBUS_TYPE_STRING, &prop,
191 DBUS_TYPE_INVALID);
192
193 bool status =
194 dbus_connection_send_with_reply(conn, message, &pending, -1);
195 dbus_message_unref(message);
196
197 if (!(pending || status)) {
198 sway_log(L_ERROR, "Could not get items");
199 return;
200 }
201
202 dbus_pending_call_set_notify(pending, get_items_reply, NULL, NULL);
203 106
204 message = dbus_message_new_method_call( 107 dbus_get_prop_async("org.freedesktop.StatusNotifierWatcher",
205 "org.freedesktop.StatusNotifierWatcher", 108 "/StatusNotifierWatcher","org.swaywm.LessSuckyStatusNotifierWatcher",
206 "/StatusNotifierWatcher", 109 "RegisteredObjectPathItems", "a(os)", get_obj_items_reply, NULL);
207 "org.freedesktop.DBus.Properties",
208 "Get");
209
210 iface = "org.swaywm.LessSuckyStatusNotifierWatcher";
211 prop = "RegisteredObjectPathItems";
212 dbus_message_append_args(message,
213 DBUS_TYPE_STRING, &iface,
214 DBUS_TYPE_STRING, &prop,
215 DBUS_TYPE_INVALID);
216
217 status = dbus_connection_send_with_reply(conn, message, &pending, -1);
218 dbus_message_unref(message);
219
220 if (!(pending || status)) {
221 sway_log(L_ERROR, "Could not get items");
222 return;
223 }
224 dbus_pending_call_set_notify(pending, get_obj_items_reply, NULL, NULL);
225} 110}
226 111
227static DBusHandlerResult signal_handler(DBusConnection *connection, 112static DBusHandlerResult signal_handler(DBusConnection *connection,