diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-09-02 21:41:11 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-09-04 16:48:50 -1000 |
commit | 1fd2c6ba498e61f4fe823bf552f9d2fce8612de4 (patch) | |
tree | 8e2d9adab3451f1f05c76340d466a442c840e558 /swaybar/ipc.c | |
parent | seatop_default: only focus container on press (diff) | |
download | sway-1fd2c6ba498e61f4fe823bf552f9d2fce8612de4.tar.gz sway-1fd2c6ba498e61f4fe823bf552f9d2fce8612de4.tar.zst sway-1fd2c6ba498e61f4fe823bf552f9d2fce8612de4.zip |
swaybar: complete barconfig_update event handling
This adds complete support for the barconfig_update ipc event. This also
changes the bar command and subcommand handlers to correctly emit the
event. This makes it so all bar subcommands other than id and
swaybar_command are dynamically changeable at runtime. sway-bar.5 has
been updated accordingly
Diffstat (limited to 'swaybar/ipc.c')
-rw-r--r-- | swaybar/ipc.c | 367 |
1 files changed, 207 insertions, 160 deletions
diff --git a/swaybar/ipc.c b/swaybar/ipc.c index a096f01a..afaffb04 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c | |||
@@ -1,15 +1,21 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | 1 | #define _POSIX_C_SOURCE 200809 |
2 | #include <limits.h> | 2 | #include <limits.h> |
3 | #include <poll.h> | ||
3 | #include <stdio.h> | 4 | #include <stdio.h> |
4 | #include <string.h> | 5 | #include <string.h> |
5 | #include <strings.h> | 6 | #include <strings.h> |
6 | #include <json.h> | 7 | #include <json.h> |
7 | #include "swaybar/config.h" | 8 | #include "swaybar/config.h" |
8 | #include "swaybar/ipc.h" | 9 | #include "swaybar/ipc.h" |
10 | #include "swaybar/status_line.h" | ||
11 | #if HAVE_TRAY | ||
12 | #include "swaybar/tray/tray.h" | ||
13 | #endif | ||
9 | #include "config.h" | 14 | #include "config.h" |
10 | #include "ipc-client.h" | 15 | #include "ipc-client.h" |
11 | #include "list.h" | 16 | #include "list.h" |
12 | #include "log.h" | 17 | #include "log.h" |
18 | #include "loop.h" | ||
13 | #include "util.h" | 19 | #include "util.h" |
14 | 20 | ||
15 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws) { | 21 | void ipc_send_workspace_command(struct swaybar *bar, const char *ws) { |
@@ -169,75 +175,58 @@ static bool ipc_parse_config( | |||
169 | json_object *success; | 175 | json_object *success; |
170 | if (json_object_object_get_ex(bar_config, "success", &success) | 176 | if (json_object_object_get_ex(bar_config, "success", &success) |
171 | && !json_object_get_boolean(success)) { | 177 | && !json_object_get_boolean(success)) { |
172 | sway_log(SWAY_ERROR, "No bar with that ID. Use 'swaymsg -t get_bar_config to get the available bar configs."); | 178 | sway_log(SWAY_ERROR, "No bar with that ID. Use 'swaymsg -t " |
179 | "get_bar_config' to get the available bar configs."); | ||
173 | json_object_put(bar_config); | 180 | json_object_put(bar_config); |
174 | return false; | 181 | return false; |
175 | } | 182 | } |
176 | json_object *markup, *mode, *hidden_state, *position, *status_command; | 183 | |
177 | json_object *font, *gaps, *bar_height, *wrap_scroll, *workspace_buttons; | 184 | json_object *bar_height = json_object_object_get(bar_config, "bar_height"); |
178 | json_object *strip_workspace_numbers, *strip_workspace_name; | 185 | if (bar_height) { |
179 | json_object *binding_mode_indicator, *verbose, *colors, *sep_symbol; | 186 | config->height = json_object_get_int(bar_height); |
180 | json_object *outputs, *bindings, *status_padding, *status_edge_padding; | ||
181 | json_object_object_get_ex(bar_config, "mode", &mode); | ||
182 | json_object_object_get_ex(bar_config, "hidden_state", &hidden_state); | ||
183 | json_object_object_get_ex(bar_config, "position", &position); | ||
184 | json_object_object_get_ex(bar_config, "status_command", &status_command); | ||
185 | json_object_object_get_ex(bar_config, "font", &font); | ||
186 | json_object_object_get_ex(bar_config, "gaps", &gaps); | ||
187 | json_object_object_get_ex(bar_config, "bar_height", &bar_height); | ||
188 | json_object_object_get_ex(bar_config, "wrap_scroll", &wrap_scroll); | ||
189 | json_object_object_get_ex(bar_config, "workspace_buttons", &workspace_buttons); | ||
190 | json_object_object_get_ex(bar_config, "strip_workspace_numbers", &strip_workspace_numbers); | ||
191 | json_object_object_get_ex(bar_config, "strip_workspace_name", &strip_workspace_name); | ||
192 | json_object_object_get_ex(bar_config, "binding_mode_indicator", &binding_mode_indicator); | ||
193 | json_object_object_get_ex(bar_config, "verbose", &verbose); | ||
194 | json_object_object_get_ex(bar_config, "separator_symbol", &sep_symbol); | ||
195 | json_object_object_get_ex(bar_config, "colors", &colors); | ||
196 | json_object_object_get_ex(bar_config, "outputs", &outputs); | ||
197 | json_object_object_get_ex(bar_config, "pango_markup", &markup); | ||
198 | json_object_object_get_ex(bar_config, "bindings", &bindings); | ||
199 | json_object_object_get_ex(bar_config, "status_padding", &status_padding); | ||
200 | json_object_object_get_ex(bar_config, "status_edge_padding", | ||
201 | &status_edge_padding); | ||
202 | if (status_command) { | ||
203 | free(config->status_command); | ||
204 | config->status_command = strdup(json_object_get_string(status_command)); | ||
205 | } | ||
206 | if (position) { | ||
207 | config->position = parse_position(json_object_get_string(position)); | ||
208 | } | ||
209 | if (font) { | ||
210 | free(config->font); | ||
211 | config->font = parse_font(json_object_get_string(font)); | ||
212 | } | ||
213 | if (sep_symbol) { | ||
214 | free(config->sep_symbol); | ||
215 | config->sep_symbol = strdup(json_object_get_string(sep_symbol)); | ||
216 | } | ||
217 | if (strip_workspace_numbers) { | ||
218 | config->strip_workspace_numbers = json_object_get_boolean(strip_workspace_numbers); | ||
219 | } | ||
220 | if (strip_workspace_name) { | ||
221 | config->strip_workspace_name = json_object_get_boolean(strip_workspace_name); | ||
222 | } | 187 | } |
188 | |||
189 | json_object *binding_mode_indicator = | ||
190 | json_object_object_get(bar_config, "binding_mode_indicator"); | ||
223 | if (binding_mode_indicator) { | 191 | if (binding_mode_indicator) { |
224 | config->binding_mode_indicator = json_object_get_boolean(binding_mode_indicator); | 192 | config->binding_mode_indicator = |
193 | json_object_get_boolean(binding_mode_indicator); | ||
225 | } | 194 | } |
226 | if (wrap_scroll) { | 195 | |
227 | config->wrap_scroll = json_object_get_boolean(wrap_scroll); | 196 | json_object *bindings = json_object_object_get(bar_config, "bindings"); |
228 | } | 197 | while (config->bindings->length) { |
229 | if (workspace_buttons) { | 198 | struct swaybar_binding *binding = config->bindings->items[0]; |
230 | config->workspace_buttons = json_object_get_boolean(workspace_buttons); | 199 | list_del(config->bindings, 0); |
200 | free_binding(binding); | ||
231 | } | 201 | } |
232 | if (bar_height) { | 202 | if (bindings) { |
233 | config->height = json_object_get_int(bar_height); | 203 | int length = json_object_array_length(bindings); |
204 | for (int i = 0; i < length; ++i) { | ||
205 | json_object *bindobj = json_object_array_get_idx(bindings, i); | ||
206 | struct swaybar_binding *binding = | ||
207 | calloc(1, sizeof(struct swaybar_binding)); | ||
208 | binding->button = json_object_get_int( | ||
209 | json_object_object_get(bindobj, "event_code")); | ||
210 | binding->command = strdup(json_object_get_string( | ||
211 | json_object_object_get(bindobj, "command"))); | ||
212 | binding->release = json_object_get_boolean( | ||
213 | json_object_object_get(bindobj, "release")); | ||
214 | list_add(config->bindings, binding); | ||
215 | } | ||
234 | } | 216 | } |
235 | if (status_padding) { | 217 | |
236 | config->status_padding = json_object_get_int(status_padding); | 218 | json_object *colors = json_object_object_get(bar_config, "colors"); |
219 | if (colors) { | ||
220 | ipc_parse_colors(config, colors); | ||
237 | } | 221 | } |
238 | if (status_edge_padding) { | 222 | |
239 | config->status_edge_padding = json_object_get_int(status_edge_padding); | 223 | json_object *font = json_object_object_get(bar_config, "font"); |
224 | if (font) { | ||
225 | free(config->font); | ||
226 | config->font = parse_font(json_object_get_string(font)); | ||
240 | } | 227 | } |
228 | |||
229 | json_object *gaps = json_object_object_get(bar_config, "gaps"); | ||
241 | if (gaps) { | 230 | if (gaps) { |
242 | json_object *top = json_object_object_get(gaps, "top"); | 231 | json_object *top = json_object_object_get(gaps, "top"); |
243 | if (top) { | 232 | if (top) { |
@@ -256,33 +245,21 @@ static bool ipc_parse_config( | |||
256 | config->gaps.left = json_object_get_int(left); | 245 | config->gaps.left = json_object_get_int(left); |
257 | } | 246 | } |
258 | } | 247 | } |
259 | if (markup) { | 248 | |
260 | config->pango_markup = json_object_get_boolean(markup); | 249 | json_object *hidden_state = |
261 | } | 250 | json_object_object_get(bar_config, "hidden_state"); |
262 | if (bindings) { | ||
263 | int length = json_object_array_length(bindings); | ||
264 | for (int i = 0; i < length; ++i) { | ||
265 | json_object *bindobj = json_object_array_get_idx(bindings, i); | ||
266 | struct swaybar_binding *binding = | ||
267 | calloc(1, sizeof(struct swaybar_binding)); | ||
268 | binding->button = json_object_get_int( | ||
269 | json_object_object_get(bindobj, "event_code")); | ||
270 | binding->command = strdup(json_object_get_string( | ||
271 | json_object_object_get(bindobj, "command"))); | ||
272 | binding->release = json_object_get_boolean( | ||
273 | json_object_object_get(bindobj, "release")); | ||
274 | list_add(config->bindings, binding); | ||
275 | } | ||
276 | } | ||
277 | if (hidden_state) { | 251 | if (hidden_state) { |
278 | free(config->hidden_state); | 252 | free(config->hidden_state); |
279 | config->hidden_state = strdup(json_object_get_string(hidden_state)); | 253 | config->hidden_state = strdup(json_object_get_string(hidden_state)); |
280 | } | 254 | } |
255 | |||
256 | json_object *mode = json_object_object_get(bar_config, "mode"); | ||
281 | if (mode) { | 257 | if (mode) { |
282 | free(config->mode); | 258 | free(config->mode); |
283 | config->mode = strdup(json_object_get_string(mode)); | 259 | config->mode = strdup(json_object_get_string(mode)); |
284 | } | 260 | } |
285 | 261 | ||
262 | json_object *outputs = json_object_object_get(bar_config, "outputs"); | ||
286 | struct config_output *output, *tmp; | 263 | struct config_output *output, *tmp; |
287 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { | 264 | wl_list_for_each_safe(output, tmp, &config->outputs, link) { |
288 | wl_list_remove(&output->link); | 265 | wl_list_remove(&output->link); |
@@ -295,40 +272,115 @@ static bool ipc_parse_config( | |||
295 | json_object *output = json_object_array_get_idx(outputs, i); | 272 | json_object *output = json_object_array_get_idx(outputs, i); |
296 | const char *name = json_object_get_string(output); | 273 | const char *name = json_object_get_string(output); |
297 | if (strcmp("*", name) == 0) { | 274 | if (strcmp("*", name) == 0) { |
298 | config->all_outputs = true; | 275 | struct config_output *coutput, *tmp; |
276 | wl_list_for_each_safe(coutput, tmp, &config->outputs, link) { | ||
277 | wl_list_remove(&coutput->link); | ||
278 | free(coutput->name); | ||
279 | free(coutput); | ||
280 | } | ||
299 | break; | 281 | break; |
300 | } | 282 | } |
301 | struct config_output *coutput = calloc( | 283 | struct config_output *coutput = calloc( |
302 | 1, sizeof(struct config_output)); | 284 | 1, sizeof(struct config_output)); |
303 | coutput->name = strdup(name); | 285 | coutput->name = strdup(name); |
304 | coutput->index = SIZE_MAX; | ||
305 | wl_list_insert(&config->outputs, &coutput->link); | 286 | wl_list_insert(&config->outputs, &coutput->link); |
306 | } | 287 | } |
307 | } else { | ||
308 | config->all_outputs = true; | ||
309 | } | 288 | } |
310 | 289 | ||
311 | if (colors) { | 290 | json_object *pango_markup = |
312 | ipc_parse_colors(config, colors); | 291 | json_object_object_get(bar_config, "pango_markup"); |
292 | if (pango_markup) { | ||
293 | config->pango_markup = json_object_get_boolean(pango_markup); | ||
294 | } | ||
295 | |||
296 | json_object *position = json_object_object_get(bar_config, "position"); | ||
297 | if (position) { | ||
298 | config->position = parse_position(json_object_get_string(position)); | ||
299 | } | ||
300 | |||
301 | json_object *separator_symbol = | ||
302 | json_object_object_get(bar_config, "separator_symbol"); | ||
303 | if (separator_symbol) { | ||
304 | free(config->sep_symbol); | ||
305 | config->sep_symbol = strdup(json_object_get_string(separator_symbol)); | ||
306 | } | ||
307 | |||
308 | json_object *status_command = | ||
309 | json_object_object_get(bar_config, "status_command"); | ||
310 | if (status_command) { | ||
311 | const char *command = json_object_get_string(status_command); | ||
312 | free(config->status_command); | ||
313 | config->status_command = strdup(command); | ||
314 | } | ||
315 | |||
316 | json_object *status_edge_padding = | ||
317 | json_object_object_get(bar_config, "status_edge_padding"); | ||
318 | if (status_edge_padding) { | ||
319 | config->status_edge_padding = json_object_get_int(status_edge_padding); | ||
320 | } | ||
321 | |||
322 | json_object *status_padding = | ||
323 | json_object_object_get(bar_config, "status_padding"); | ||
324 | if (status_padding) { | ||
325 | config->status_padding = json_object_get_int(status_padding); | ||
326 | } | ||
327 | |||
328 | json_object *strip_workspace_name = | ||
329 | json_object_object_get(bar_config, "strip_workspace_name"); | ||
330 | if (strip_workspace_name) { | ||
331 | config->strip_workspace_name = | ||
332 | json_object_get_boolean(strip_workspace_name); | ||
313 | } | 333 | } |
314 | 334 | ||
335 | json_object *strip_workspace_numbers = | ||
336 | json_object_object_get(bar_config, "strip_workspace_numbers"); | ||
337 | if (strip_workspace_numbers) { | ||
338 | config->strip_workspace_numbers = | ||
339 | json_object_get_boolean(strip_workspace_numbers); | ||
340 | } | ||
341 | |||
342 | json_object *workspace_buttons = | ||
343 | json_object_object_get(bar_config, "workspace_buttons"); | ||
344 | if (workspace_buttons) { | ||
345 | config->workspace_buttons = json_object_get_boolean(workspace_buttons); | ||
346 | } | ||
347 | |||
348 | json_object *wrap_scroll = json_object_object_get(bar_config, "wrap_scroll"); | ||
349 | if (wrap_scroll) { | ||
350 | config->wrap_scroll = json_object_get_boolean(wrap_scroll); | ||
351 | } | ||
315 | #if HAVE_TRAY | 352 | #if HAVE_TRAY |
316 | json_object *tray_outputs, *tray_padding, *tray_bindings, *icon_theme; | 353 | json_object *tray_outputs, *tray_padding, *tray_bindings, *icon_theme; |
317 | 354 | ||
355 | if (config->tray_outputs && config->tray_outputs->length) { | ||
356 | list_free_items_and_destroy(config->tray_outputs); | ||
357 | } | ||
318 | if ((json_object_object_get_ex(bar_config, "tray_outputs", &tray_outputs))) { | 358 | if ((json_object_object_get_ex(bar_config, "tray_outputs", &tray_outputs))) { |
319 | config->tray_outputs = create_list(); | 359 | config->tray_outputs = create_list(); |
320 | int length = json_object_array_length(tray_outputs); | 360 | int length = json_object_array_length(tray_outputs); |
321 | for (int i = 0; i < length; ++i) { | 361 | for (int i = 0; i < length; ++i) { |
322 | json_object *o = json_object_array_get_idx(tray_outputs, i); | 362 | json_object *output= json_object_array_get_idx(tray_outputs, i); |
323 | list_add(config->tray_outputs, strdup(json_object_get_string(o))); | 363 | const char *name = json_object_get_string(output); |
364 | if (strcmp(name, "none") == 0) { | ||
365 | config->tray_hidden = true; | ||
366 | list_free_items_and_destroy(config->tray_outputs); | ||
367 | config->tray_outputs = create_list(); | ||
368 | break; | ||
369 | } | ||
370 | list_add(config->tray_outputs, strdup(name)); | ||
324 | } | 371 | } |
325 | config->tray_hidden = strcmp(config->tray_outputs->items[0], "none") == 0; | ||
326 | } | 372 | } |
327 | 373 | ||
328 | if ((json_object_object_get_ex(bar_config, "tray_padding", &tray_padding))) { | 374 | if ((json_object_object_get_ex(bar_config, "tray_padding", &tray_padding))) { |
329 | config->tray_padding = json_object_get_int(tray_padding); | 375 | config->tray_padding = json_object_get_int(tray_padding); |
330 | } | 376 | } |
331 | 377 | ||
378 | struct tray_binding *tray_bind = NULL, *tmp_tray_bind = NULL; | ||
379 | wl_list_for_each_safe(tray_bind, tmp_tray_bind, &config->tray_bindings, | ||
380 | link) { | ||
381 | wl_list_remove(&tray_bind->link); | ||
382 | free_tray_binding(tray_bind); | ||
383 | } | ||
332 | if ((json_object_object_get_ex(bar_config, "tray_bindings", &tray_bindings))) { | 384 | if ((json_object_object_get_ex(bar_config, "tray_bindings", &tray_bindings))) { |
333 | int length = json_object_array_length(tray_bindings); | 385 | int length = json_object_array_length(tray_bindings); |
334 | for (int i = 0; i < length; ++i) { | 386 | for (int i = 0; i < length; ++i) { |
@@ -423,41 +475,6 @@ bool ipc_get_workspaces(struct swaybar *bar) { | |||
423 | return determine_bar_visibility(bar, false); | 475 | return determine_bar_visibility(bar, false); |
424 | } | 476 | } |
425 | 477 | ||
426 | static void ipc_get_outputs(struct swaybar *bar) { | ||
427 | uint32_t len = 0; | ||
428 | char *res = ipc_single_command(bar->ipc_socketfd, | ||
429 | IPC_GET_OUTPUTS, NULL, &len); | ||
430 | json_object *outputs = json_tokener_parse(res); | ||
431 | for (size_t i = 0; i < json_object_array_length(outputs); ++i) { | ||
432 | json_object *output = json_object_array_get_idx(outputs, i); | ||
433 | json_object *output_name, *output_active; | ||
434 | json_object_object_get_ex(output, "name", &output_name); | ||
435 | json_object_object_get_ex(output, "active", &output_active); | ||
436 | const char *name = json_object_get_string(output_name); | ||
437 | bool active = json_object_get_boolean(output_active); | ||
438 | if (!active) { | ||
439 | continue; | ||
440 | } | ||
441 | if (bar->config->all_outputs) { | ||
442 | struct config_output *coutput = | ||
443 | calloc(1, sizeof(struct config_output)); | ||
444 | coutput->name = strdup(name); | ||
445 | coutput->index = i; | ||
446 | wl_list_insert(&bar->config->outputs, &coutput->link); | ||
447 | } else { | ||
448 | struct config_output *coutput; | ||
449 | wl_list_for_each(coutput, &bar->config->outputs, link) { | ||
450 | if (strcmp(name, coutput->name) == 0) { | ||
451 | coutput->index = i; | ||
452 | break; | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | } | ||
457 | json_object_put(outputs); | ||
458 | free(res); | ||
459 | } | ||
460 | |||
461 | void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { | 478 | void ipc_execute_binding(struct swaybar *bar, struct swaybar_binding *bind) { |
462 | sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`", | 479 | sway_log(SWAY_DEBUG, "Executing binding for button %u (release=%d): `%s`", |
463 | bind->button, bind->release, bind->command); | 480 | bind->button, bind->release, bind->command); |
@@ -475,7 +492,6 @@ bool ipc_initialize(struct swaybar *bar) { | |||
475 | return false; | 492 | return false; |
476 | } | 493 | } |
477 | free(res); | 494 | free(res); |
478 | ipc_get_outputs(bar); | ||
479 | 495 | ||
480 | struct swaybar_config *config = bar->config; | 496 | struct swaybar_config *config = bar->config; |
481 | char subscribe[128]; // suitably large buffer | 497 | char subscribe[128]; // suitably large buffer |
@@ -509,56 +525,87 @@ static bool handle_bar_state_update(struct swaybar *bar, json_object *event) { | |||
509 | return determine_bar_visibility(bar, false); | 525 | return determine_bar_visibility(bar, false); |
510 | } | 526 | } |
511 | 527 | ||
512 | static bool handle_barconfig_update(struct swaybar *bar, | 528 | static bool handle_barconfig_update(struct swaybar *bar, const char *payload, |
513 | json_object *json_config) { | 529 | json_object *json_config) { |
514 | json_object *json_id; | 530 | json_object *json_id = json_object_object_get(json_config, "id"); |
515 | json_object_object_get_ex(json_config, "id", &json_id); | ||
516 | const char *id = json_object_get_string(json_id); | 531 | const char *id = json_object_get_string(json_id); |
517 | if (strcmp(id, bar->id) != 0) { | 532 | if (strcmp(id, bar->id) != 0) { |
518 | return false; | 533 | return false; |
519 | } | 534 | } |
520 | 535 | ||
521 | struct swaybar_config *config = bar->config; | 536 | struct swaybar_config *newcfg = init_config(); |
537 | ipc_parse_config(newcfg, payload); | ||
522 | 538 | ||
523 | json_object *json_state; | 539 | struct swaybar_config *oldcfg = bar->config; |
524 | json_object_object_get_ex(json_config, "hidden_state", &json_state); | 540 | bar->config = newcfg; |
525 | const char *new_state = json_object_get_string(json_state); | 541 | |
526 | char *old_state = config->hidden_state; | 542 | struct swaybar_output *output, *tmp_output; |
527 | if (strcmp(new_state, old_state) != 0) { | 543 | wl_list_for_each_safe(output, tmp_output, &bar->outputs, link) { |
528 | sway_log(SWAY_DEBUG, "Changing bar hidden state to %s", new_state); | 544 | bool found = wl_list_empty(&newcfg->outputs); |
529 | free(old_state); | 545 | struct config_output *coutput; |
530 | config->hidden_state = strdup(new_state); | 546 | wl_list_for_each(coutput, &newcfg->outputs, link) { |
531 | return determine_bar_visibility(bar, false); | 547 | if (strcmp(coutput->name, output->name) == 0 || |
532 | } | 548 | strcmp(coutput->name, output->identifier) == 0) { |
533 | 549 | found = true; | |
534 | free(config->mode); | 550 | break; |
535 | json_object *json_mode; | 551 | } |
536 | json_object_object_get_ex(json_config, "mode", &json_mode); | ||
537 | config->mode = strdup(json_object_get_string(json_mode)); | ||
538 | sway_log(SWAY_DEBUG, "Changing bar mode to %s", config->mode); | ||
539 | |||
540 | json_object *gaps; | ||
541 | json_object_object_get_ex(json_config, "gaps", &gaps); | ||
542 | if (gaps) { | ||
543 | json_object *top = json_object_object_get(gaps, "top"); | ||
544 | if (top) { | ||
545 | config->gaps.top = json_object_get_int(top); | ||
546 | } | 552 | } |
547 | json_object *right = json_object_object_get(gaps, "right"); | 553 | if (!found) { |
548 | if (right) { | 554 | destroy_layer_surface(output); |
549 | config->gaps.right = json_object_get_int(right); | 555 | wl_list_remove(&output->link); |
556 | wl_list_insert(&bar->unused_outputs, &output->link); | ||
557 | } else if (!oldcfg->font || !newcfg->font || | ||
558 | strcmp(oldcfg->font, newcfg->font) != 0) { | ||
559 | output->height = 0; // force update height | ||
550 | } | 560 | } |
551 | json_object *bottom = json_object_object_get(gaps, "bottom"); | 561 | } |
552 | if (bottom) { | 562 | wl_list_for_each_safe(output, tmp_output, &bar->unused_outputs, link) { |
553 | config->gaps.bottom = json_object_get_int(bottom); | 563 | bool found = wl_list_empty(&newcfg->outputs); |
564 | struct config_output *coutput; | ||
565 | wl_list_for_each(coutput, &newcfg->outputs, link) { | ||
566 | if (strcmp(coutput->name, output->name) == 0 || | ||
567 | strcmp(coutput->name, output->identifier) == 0) { | ||
568 | found = true; | ||
569 | break; | ||
570 | } | ||
554 | } | 571 | } |
555 | json_object *left = json_object_object_get(gaps, "left"); | 572 | if (found) { |
556 | if (left) { | 573 | wl_list_remove(&output->link); |
557 | config->gaps.left = json_object_get_int(left); | 574 | wl_list_insert(&bar->outputs, &output->link); |
558 | } | 575 | } |
559 | } | 576 | } |
560 | 577 | ||
561 | return determine_bar_visibility(bar, true); | 578 | if (bar->status && (!newcfg->status_command || |
579 | strcmp(newcfg->status_command, oldcfg->status_command) != 0)) { | ||
580 | status_line_free(bar->status); | ||
581 | bar->status = NULL; | ||
582 | } | ||
583 | if (!bar->status && newcfg->status_command) { | ||
584 | bar->status = status_line_init(newcfg->status_command); | ||
585 | bar->status->bar = bar; | ||
586 | loop_add_fd(bar->eventloop, bar->status->read_fd, POLLIN, | ||
587 | status_in, bar); | ||
588 | } | ||
589 | |||
590 | #if HAVE_TRAY | ||
591 | if (oldcfg->tray_hidden && !newcfg->tray_hidden) { | ||
592 | bar->tray = create_tray(bar); | ||
593 | loop_add_fd(bar->eventloop, bar->tray->fd, POLLIN, tray_in, | ||
594 | bar->tray->bus); | ||
595 | } else if (bar->tray && newcfg->tray_hidden) { | ||
596 | loop_remove_fd(bar->eventloop, bar->tray->fd); | ||
597 | destroy_tray(bar->tray); | ||
598 | bar->tray = NULL; | ||
599 | } | ||
600 | #endif | ||
601 | |||
602 | if (newcfg->workspace_buttons) { | ||
603 | ipc_get_workspaces(bar); | ||
604 | } | ||
605 | |||
606 | free_config(oldcfg); | ||
607 | determine_bar_visibility(bar, true); | ||
608 | return true; | ||
562 | } | 609 | } |
563 | 610 | ||
564 | bool handle_ipc_readable(struct swaybar *bar) { | 611 | bool handle_ipc_readable(struct swaybar *bar) { |
@@ -599,7 +646,7 @@ bool handle_ipc_readable(struct swaybar *bar) { | |||
599 | break; | 646 | break; |
600 | } | 647 | } |
601 | case IPC_EVENT_BARCONFIG_UPDATE: | 648 | case IPC_EVENT_BARCONFIG_UPDATE: |
602 | bar_is_dirty = handle_barconfig_update(bar, result); | 649 | bar_is_dirty = handle_barconfig_update(bar, resp->payload, result); |
603 | break; | 650 | break; |
604 | case IPC_EVENT_BAR_STATE_UPDATE: | 651 | case IPC_EVENT_BAR_STATE_UPDATE: |
605 | bar_is_dirty = handle_bar_state_update(bar, result); | 652 | bar_is_dirty = handle_bar_state_update(bar, result); |