Feature: send complete config on barconfig_update
Patch status: merged
Patch by Tony Crisci
Long description:
Send all the options in the bar block on the barconfig_update event. This will eventually allow for dynamically updating bar colors with the `reload` command.
To apply this patch, use:
curl http://cr.i3wm.org/patch/513/raw.patch | git am
b/docs/ipc
21 |
@@ -637,7 +637,7 @@ window (3):: |
22 |
focus or when a window title has been updated. |
23 |
barconfig_update (4):: |
24 |
Sent when the hidden_state or mode field in the barconfig of any bar |
25 |
- instance was updated. |
26 |
+ instance was updated and when the config is reloaded. |
27 |
|
28 |
*Example:* |
29 |
-------------------------------------------------------------------- |
30 |
@@ -738,20 +738,8 @@ this point get the window title as "urxvt"). |
31 |
=== barconfig_update event |
32 |
|
33 |
This event consists of a single serialized map reporting on options from the |
34 |
-barconfig of the specified bar_id that were updated in i3. The map always |
35 |
-consists of a property +id (string)+, which specifies to which bar instance the |
36 |
-sent config update belongs, a property +hidden_state (string)+, which indicates |
37 |
-the hidden_state of an i3bar instance, and a property +mode (string)+, which |
38 |
-corresponds to the current mode. |
39 |
- |
40 |
-*Example:* |
41 |
---------------------------- |
42 |
-{ |
43 |
- "id": "bar-0", |
44 |
- "hidden_state": "hide" |
45 |
- "mode": "hide" |
46 |
-} |
47 |
---------------------------- |
48 |
+barconfig of the specified bar_id that were updated in i3. This event is the |
49 |
+same as a +GET_BAR_CONFIG+ reply for the bar with the given id. |
50 |
|
51 |
== See also (existing libraries) |
52 |
|
b/include/config.h
57 |
@@ -317,9 +317,9 @@ void ungrab_all_keys(xcb_connection_t *conn); |
58 |
|
59 |
/** |
60 |
* Sends the current bar configuration as an event to all barconfig_update listeners. |
61 |
- * This update mechnism currently only includes the hidden_state and the mode in the config. |
62 |
* |
63 |
- */void update_barconfig(); |
64 |
+ */ |
65 |
+void update_barconfig(); |
66 |
|
67 |
/** |
68 |
* Kills the configerror i3-nagbar process, if any. |
b/include/ipc.h
73 |
@@ -16,6 +16,7 @@ |
74 |
|
75 |
#include "data.h" |
76 |
#include "tree.h" |
77 |
+#include "config.h" |
78 |
|
79 |
#include "i3/ipc.h" |
80 |
|
81 |
@@ -93,3 +94,8 @@ void ipc_send_workspace_focus_event(Con *current, Con *old); |
82 |
* also the window container, in "container". |
83 |
*/ |
84 |
void ipc_send_window_event(const char *property, Con *con); |
85 |
+ |
86 |
+/** |
87 |
+ * For the barconfig update events, we send the serialized barconfig. |
88 |
+ */ |
89 |
+void ipc_send_barconfig_update_event(Barconfig *barconfig); |
b/src/config.c
94 |
@@ -32,44 +32,12 @@ void ungrab_all_keys(xcb_connection_t *conn) { |
95 |
|
96 |
/* |
97 |
* Sends the current bar configuration as an event to all barconfig_update listeners. |
98 |
- * This update mechnism currently only includes the hidden_state and the mode in the config. |
99 |
* |
100 |
*/ |
101 |
void update_barconfig() { |
102 |
Barconfig *current; |
103 |
TAILQ_FOREACH(current, &barconfigs, configs) { |
104 |
- /* Build json message */ |
105 |
- char *hidden_state; |
106 |
- switch (current->hidden_state) { |
107 |
- case S_SHOW: |
108 |
- hidden_state ="show"; |
109 |
- break; |
110 |
- case S_HIDE: |
111 |
- default: |
112 |
- hidden_state = "hide"; |
113 |
- break; |
114 |
- } |
115 |
- |
116 |
- char *mode; |
117 |
- switch (current->mode) { |
118 |
- case M_HIDE: |
119 |
- mode ="hide"; |
120 |
- break; |
121 |
- case M_INVISIBLE: |
122 |
- mode ="invisible"; |
123 |
- break; |
124 |
- case M_DOCK: |
125 |
- default: |
126 |
- mode = "dock"; |
127 |
- break; |
128 |
- } |
129 |
- |
130 |
- /* Send an event to all barconfig listeners*/ |
131 |
- char *event_msg; |
132 |
- sasprintf(&event_msg, "{ \"id\":\"%s\", \"hidden_state\":\"%s\", \"mode\":\"%s\" }", current->id, hidden_state, mode); |
133 |
- |
134 |
- ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, event_msg); |
135 |
- FREE(event_msg); |
136 |
+ ipc_send_barconfig_update_event(current); |
137 |
} |
138 |
} |
139 |
|
b/src/ipc.c
144 |
@@ -423,6 +423,135 @@ void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) { |
145 |
y(map_close); |
146 |
} |
147 |
|
148 |
+static void dump_bar_config(yajl_gen gen, Barconfig *config) { |
149 |
+ y(map_open); |
150 |
+ |
151 |
+ ystr("id"); |
152 |
+ ystr(config->id); |
153 |
+ |
154 |
+ if (config->num_outputs > 0) { |
155 |
+ ystr("outputs"); |
156 |
+ y(array_open); |
157 |
+ for (int c = 0; c < config->num_outputs; c++) |
158 |
+ ystr(config->outputs[c]); |
159 |
+ y(array_close); |
160 |
+ } |
161 |
+ |
162 |
+#define YSTR_IF_SET(name) \ |
163 |
+ do { \ |
164 |
+ if (config->name) { \ |
165 |
+ ystr( # name); \ |
166 |
+ ystr(config->name); \ |
167 |
+ } \ |
168 |
+ } while (0) |
169 |
+ |
170 |
+ YSTR_IF_SET(tray_output); |
171 |
+ YSTR_IF_SET(socket_path); |
172 |
+ |
173 |
+ ystr("mode"); |
174 |
+ switch (config->mode) { |
175 |
+ case M_HIDE: |
176 |
+ ystr("hide"); |
177 |
+ break; |
178 |
+ case M_INVISIBLE: |
179 |
+ ystr("invisible"); |
180 |
+ break; |
181 |
+ case M_DOCK: |
182 |
+ default: |
183 |
+ ystr("dock"); |
184 |
+ break; |
185 |
+ } |
186 |
+ |
187 |
+ ystr("hidden_state"); |
188 |
+ switch (config->hidden_state) { |
189 |
+ case S_SHOW: |
190 |
+ ystr("show"); |
191 |
+ break; |
192 |
+ case S_HIDE: |
193 |
+ default: |
194 |
+ ystr("hide"); |
195 |
+ break; |
196 |
+ } |
197 |
+ |
198 |
+ ystr("modifier"); |
199 |
+ switch (config->modifier) { |
200 |
+ case M_CONTROL: |
201 |
+ ystr("ctrl"); |
202 |
+ break; |
203 |
+ case M_SHIFT: |
204 |
+ ystr("shift"); |
205 |
+ break; |
206 |
+ case M_MOD1: |
207 |
+ ystr("Mod1"); |
208 |
+ break; |
209 |
+ case M_MOD2: |
210 |
+ ystr("Mod2"); |
211 |
+ break; |
212 |
+ case M_MOD3: |
213 |
+ ystr("Mod3"); |
214 |
+ break; |
215 |
+ /* |
216 |
+ case M_MOD4: |
217 |
+ ystr("Mod4"); |
218 |
+ break; |
219 |
+ */ |
220 |
+ case M_MOD5: |
221 |
+ ystr("Mod5"); |
222 |
+ break; |
223 |
+ default: |
224 |
+ ystr("Mod4"); |
225 |
+ break; |
226 |
+ } |
227 |
+ |
228 |
+ ystr("position"); |
229 |
+ if (config->position == P_BOTTOM) |
230 |
+ ystr("bottom"); |
231 |
+ else ystr("top"); |
232 |
+ |
233 |
+ YSTR_IF_SET(status_command); |
234 |
+ YSTR_IF_SET(font); |
235 |
+ |
236 |
+ ystr("workspace_buttons"); |
237 |
+ y(bool, !config->hide_workspace_buttons); |
238 |
+ |
239 |
+ ystr("binding_mode_indicator"); |
240 |
+ y(bool, !config->hide_binding_mode_indicator); |
241 |
+ |
242 |
+ ystr("verbose"); |
243 |
+ y(bool, config->verbose); |
244 |
+ |
245 |
+#undef YSTR_IF_SET |
246 |
+#define YSTR_IF_SET(name) \ |
247 |
+ do { \ |
248 |
+ if (config->colors.name) { \ |
249 |
+ ystr( # name); \ |
250 |
+ ystr(config->colors.name); \ |
251 |
+ } \ |
252 |
+ } while (0) |
253 |
+ |
254 |
+ ystr("colors"); |
255 |
+ y(map_open); |
256 |
+ YSTR_IF_SET(background); |
257 |
+ YSTR_IF_SET(statusline); |
258 |
+ YSTR_IF_SET(separator); |
259 |
+ YSTR_IF_SET(focused_workspace_border); |
260 |
+ YSTR_IF_SET(focused_workspace_bg); |
261 |
+ YSTR_IF_SET(focused_workspace_text); |
262 |
+ YSTR_IF_SET(active_workspace_border); |
263 |
+ YSTR_IF_SET(active_workspace_bg); |
264 |
+ YSTR_IF_SET(active_workspace_text); |
265 |
+ YSTR_IF_SET(inactive_workspace_border); |
266 |
+ YSTR_IF_SET(inactive_workspace_bg); |
267 |
+ YSTR_IF_SET(inactive_workspace_text); |
268 |
+ YSTR_IF_SET(urgent_workspace_border); |
269 |
+ YSTR_IF_SET(urgent_workspace_bg); |
270 |
+ YSTR_IF_SET(urgent_workspace_text); |
271 |
+ y(map_close); |
272 |
+ |
273 |
+ y(map_close); |
274 |
+#undef YSTR_IF_SET |
275 |
+} |
276 |
+ |
277 |
IPC_HANDLER(tree) { |
278 |
setlocale(LC_NUMERIC, "C"); |
279 |
yajl_gen gen = ygenalloc(); |
280 |
@@ -651,141 +780,19 @@ IPC_HANDLER(get_bar_config) { |
281 |
break; |
282 |
} |
283 |
|
284 |
- y(map_open); |
285 |
- |
286 |
if (!config) { |
287 |
/* If we did not find a config for the given ID, the reply will contain |
288 |
* a null 'id' field. */ |
289 |
+ y(map_open); |
290 |
+ |
291 |
ystr("id"); |
292 |
y(null); |
293 |
- } else { |
294 |
- ystr("id"); |
295 |
- ystr(config->id); |
296 |
- |
297 |
- if (config->num_outputs > 0) { |
298 |
- ystr("outputs"); |
299 |
- y(array_open); |
300 |
- for (int c = 0; c < config->num_outputs; c++) |
301 |
- ystr(config->outputs[c]); |
302 |
- y(array_close); |
303 |
- } |
304 |
- |
305 |
-#define YSTR_IF_SET(name) \ |
306 |
- do { \ |
307 |
- if (config->name) { \ |
308 |
- ystr( # name); \ |
309 |
- ystr(config->name); \ |
310 |
- } \ |
311 |
- } while (0) |
312 |
- |
313 |
- YSTR_IF_SET(tray_output); |
314 |
- YSTR_IF_SET(socket_path); |
315 |
- |
316 |
- ystr("mode"); |
317 |
- switch (config->mode) { |
318 |
- case M_HIDE: |
319 |
- ystr("hide"); |
320 |
- break; |
321 |
- case M_INVISIBLE: |
322 |
- ystr("invisible"); |
323 |
- break; |
324 |
- case M_DOCK: |
325 |
- default: |
326 |
- ystr("dock"); |
327 |
- break; |
328 |
- } |
329 |
- |
330 |
- ystr("hidden_state"); |
331 |
- switch (config->hidden_state) { |
332 |
- case S_SHOW: |
333 |
- ystr("show"); |
334 |
- break; |
335 |
- case S_HIDE: |
336 |
- default: |
337 |
- ystr("hide"); |
338 |
- break; |
339 |
- } |
340 |
- |
341 |
- ystr("modifier"); |
342 |
- switch (config->modifier) { |
343 |
- case M_CONTROL: |
344 |
- ystr("ctrl"); |
345 |
- break; |
346 |
- case M_SHIFT: |
347 |
- ystr("shift"); |
348 |
- break; |
349 |
- case M_MOD1: |
350 |
- ystr("Mod1"); |
351 |
- break; |
352 |
- case M_MOD2: |
353 |
- ystr("Mod2"); |
354 |
- break; |
355 |
- case M_MOD3: |
356 |
- ystr("Mod3"); |
357 |
- break; |
358 |
- /* |
359 |
- case M_MOD4: |
360 |
- ystr("Mod4"); |
361 |
- break; |
362 |
- */ |
363 |
- case M_MOD5: |
364 |
- ystr("Mod5"); |
365 |
- break; |
366 |
- default: |
367 |
- ystr("Mod4"); |
368 |
- break; |
369 |
- } |
370 |
- |
371 |
- ystr("position"); |
372 |
- if (config->position == P_BOTTOM) |
373 |
- ystr("bottom"); |
374 |
- else ystr("top"); |
375 |
- |
376 |
- YSTR_IF_SET(status_command); |
377 |
- YSTR_IF_SET(font); |
378 |
- |
379 |
- ystr("workspace_buttons"); |
380 |
- y(bool, !config->hide_workspace_buttons); |
381 |
- |
382 |
- ystr("binding_mode_indicator"); |
383 |
- y(bool, !config->hide_binding_mode_indicator); |
384 |
- |
385 |
- ystr("verbose"); |
386 |
- y(bool, config->verbose); |
387 |
|
388 |
-#undef YSTR_IF_SET |
389 |
-#define YSTR_IF_SET(name) \ |
390 |
- do { \ |
391 |
- if (config->colors.name) { \ |
392 |
- ystr( # name); \ |
393 |
- ystr(config->colors.name); \ |
394 |
- } \ |
395 |
- } while (0) |
396 |
- |
397 |
- ystr("colors"); |
398 |
- y(map_open); |
399 |
- YSTR_IF_SET(background); |
400 |
- YSTR_IF_SET(statusline); |
401 |
- YSTR_IF_SET(separator); |
402 |
- YSTR_IF_SET(focused_workspace_border); |
403 |
- YSTR_IF_SET(focused_workspace_bg); |
404 |
- YSTR_IF_SET(focused_workspace_text); |
405 |
- YSTR_IF_SET(active_workspace_border); |
406 |
- YSTR_IF_SET(active_workspace_bg); |
407 |
- YSTR_IF_SET(active_workspace_text); |
408 |
- YSTR_IF_SET(inactive_workspace_border); |
409 |
- YSTR_IF_SET(inactive_workspace_bg); |
410 |
- YSTR_IF_SET(inactive_workspace_text); |
411 |
- YSTR_IF_SET(urgent_workspace_border); |
412 |
- YSTR_IF_SET(urgent_workspace_bg); |
413 |
- YSTR_IF_SET(urgent_workspace_text); |
414 |
y(map_close); |
415 |
- |
416 |
-#undef YSTR_IF_SET |
417 |
+ } else { |
418 |
+ dump_bar_config(gen, config); |
419 |
} |
420 |
|
421 |
- y(map_close); |
422 |
- |
423 |
const unsigned char *payload; |
424 |
ylength length; |
425 |
y(get_buf, &payload, &length); |
426 |
@@ -1090,3 +1097,22 @@ void ipc_send_window_event(const char *property, Con *con) { |
427 |
y(free); |
428 |
setlocale(LC_NUMERIC, ""); |
429 |
} |
430 |
+ |
431 |
+/** |
432 |
+ * For the barconfig update events, we send the serialized barconfig. |
433 |
+ */ |
434 |
+void ipc_send_barconfig_update_event(Barconfig *barconfig) { |
435 |
+ DLOG("Issue barconfig_update event for id = %s\n", barconfig->id); |
436 |
+ setlocale(LC_NUMERIC, "C"); |
437 |
+ yajl_gen gen = ygenalloc(); |
438 |
+ |
439 |
+ dump_bar_config(gen, barconfig); |
440 |
+ |
441 |
+ const unsigned char *payload; |
442 |
+ ylength length; |
443 |
+ y(get_buf, &payload, &length); |
444 |
+ |
445 |
+ ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, (const char *)payload); |
446 |
+ y(free); |
447 |
+ setlocale(LC_NUMERIC, ""); |
448 |
+} |