summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-18 17:43:03 +0100
committerLibravatar Mikkel Oscar Lyderik <mikkeloscar@gmail.com>2015-12-18 18:27:44 +0100
commitede27eabc53dc926aa1932c2a58c06def1000f86 (patch)
tree4d734e99a6163d846423c79a2d7ff04070018e78
parentswaybar: ipc_update_ws: Fix memory corruption. (diff)
downloadsway-ede27eabc53dc926aa1932c2a58c06def1000f86.tar.gz
sway-ede27eabc53dc926aa1932c2a58c06def1000f86.tar.zst
sway-ede27eabc53dc926aa1932c2a58c06def1000f86.zip
Reload swaybar/swaybg on config reload.
This works by tracking the pids of the child processes in the related output container and terminating the processes and spawning new ones on a config reload. Should solve: #347
-rw-r--r--include/config.h2
-rw-r--r--include/container.h6
-rw-r--r--sway/commands.c9
-rw-r--r--sway/config.c147
-rw-r--r--sway/container.c5
5 files changed, 125 insertions, 44 deletions
diff --git a/include/config.h b/include/config.h
index 32562908..1f25a0cd 100644
--- a/include/config.h
+++ b/include/config.h
@@ -184,6 +184,8 @@ int sway_mouse_binding_cmp(const void *a, const void *b);
184int sway_mouse_binding_cmp_buttons(const void *a, const void *b); 184int sway_mouse_binding_cmp_buttons(const void *a, const void *b);
185void free_sway_mouse_binding(struct sway_mouse_binding *smb); 185void free_sway_mouse_binding(struct sway_mouse_binding *smb);
186 186
187void load_swaybars(swayc_t *output, int output_idx);
188
187/** 189/**
188 * Allocate and initialize default bar configuration. 190 * Allocate and initialize default bar configuration.
189 */ 191 */
diff --git a/include/container.h b/include/container.h
index 9a67a689..d76160de 100644
--- a/include/container.h
+++ b/include/container.h
@@ -1,5 +1,6 @@
1#ifndef _SWAY_CONTAINER_H 1#ifndef _SWAY_CONTAINER_H
2#define _SWAY_CONTAINER_H 2#define _SWAY_CONTAINER_H
3#include <sys/types.h>
3#include <wlc/wlc.h> 4#include <wlc/wlc.h>
4typedef struct sway_container swayc_t; 5typedef struct sway_container swayc_t;
5 6
@@ -81,6 +82,11 @@ struct sway_container {
81 char *class; 82 char *class;
82 char *app_id; 83 char *app_id;
83 84
85 // Used by output containers to keep track of swaybar/swaybg child
86 // processes.
87 list_t *bar_pids;
88 pid_t bg_pid;
89
84 int gaps; 90 int gaps;
85 91
86 list_t *children; 92 list_t *children;
diff --git a/sway/commands.c b/sway/commands.c
index 24d56052..13bc7dc2 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -1094,6 +1094,15 @@ static struct cmd_results *cmd_reload(int argc, char **argv) {
1094 } 1094 }
1095 if (!load_config(NULL)) return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); 1095 if (!load_config(NULL)) return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
1096 1096
1097 int i;
1098 swayc_t *cont = NULL;
1099 for (i = 0; i < root_container.children->length; ++i) {
1100 cont = root_container.children->items[i];
1101 if (cont->type == C_OUTPUT) {
1102 load_swaybars(cont, i);
1103 }
1104 }
1105
1097 arrange_windows(&root_container, -1, -1); 1106 arrange_windows(&root_container, -1, -1);
1098 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 1107 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
1099} 1108}
diff --git a/sway/config.c b/sway/config.c
index 970225f4..23fe5388 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -3,6 +3,9 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <unistd.h> 4#include <unistd.h>
5#include <wordexp.h> 5#include <wordexp.h>
6#include <sys/types.h>
7#include <sys/wait.h>
8#include <signal.h>
6#include "wayland-desktop-shell-server-protocol.h" 9#include "wayland-desktop-shell-server-protocol.h"
7#include "readline.h" 10#include "readline.h"
8#include "stringop.h" 11#include "stringop.h"
@@ -360,6 +363,91 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
360 } 363 }
361} 364}
362 365
366static void invoke_swaybar(swayc_t *output, struct bar_config *bar, int output_i) {
367 sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, output_i, bar->id);
368
369 size_t bufsize = 4;
370 char output_id[bufsize];
371 snprintf(output_id, bufsize, "%d", output_i);
372 output_id[bufsize-1] = 0;
373
374 char *const cmd[] = {
375 "swaybar",
376 "-b",
377 bar->id,
378 output_id,
379 NULL,
380 };
381
382 pid_t *pid = malloc(sizeof(pid_t));
383 *pid = fork();
384 if (*pid == 0) {
385 execvp(cmd[0], cmd);
386 }
387
388 // add swaybar pid to output
389 list_add(output->bar_pids, pid);
390}
391
392static void terminate_swaybars(list_t *pids) {
393 int i, ret;
394 pid_t *pid;
395 for (i = 0; i < pids->length; ++i) {
396 pid = pids->items[i];
397 ret = kill(*pid, SIGTERM);
398 if (ret != 0) {
399 sway_log(L_ERROR, "Unable to terminate swaybar [pid: %d]", *pid);
400 } else {
401 int status;
402 waitpid(*pid, &status, 0);
403 }
404 }
405
406 // empty pids list
407 for (i = 0; i < pids->length; ++i) {
408 pid = pids->items[i];
409 list_del(pids, i);
410 free(pid);
411 }
412}
413
414void load_swaybars(swayc_t *output, int output_idx) {
415 // Check for bars
416 list_t *bars = create_list();
417 struct bar_config *bar = NULL;
418 int i;
419 for (i = 0; i < config->bars->length; ++i) {
420 bar = config->bars->items[i];
421 bool apply = false;
422 if (bar->outputs) {
423 int j;
424 for (j = 0; j < bar->outputs->length; ++j) {
425 char *o = bar->outputs->items[j];
426 if (strcmp(o, "*") || strcasecmp(o, output->name)) {
427 apply = true;
428 break;
429 }
430 }
431 } else {
432 apply = true;
433 }
434 if (apply) {
435 list_add(bars, bar);
436 }
437 }
438
439 // terminate swaybar processes previously spawned for this
440 // output.
441 terminate_swaybars(output->bar_pids);
442
443 for (i = 0; i < bars->length; ++i) {
444 bar = bars->items[i];
445 invoke_swaybar(output, bar, output_idx);
446 }
447
448 list_free(bars);
449}
450
363void apply_output_config(struct output_config *oc, swayc_t *output) { 451void apply_output_config(struct output_config *oc, swayc_t *output) {
364 if (oc && oc->width > 0 && oc->height > 0) { 452 if (oc && oc->width > 0 && oc->height > 0) {
365 output->width = oc->width; 453 output->width = oc->width;
@@ -407,6 +495,16 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
407 495
408 if (oc && oc->background) { 496 if (oc && oc->background) {
409 497
498 if (output->bg_pid != 0) {
499 int ret = kill(output->bg_pid, SIGTERM);
500 if (ret != 0) {
501 sway_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", output->bg_pid);
502 } else {
503 int status;
504 waitpid(output->bg_pid, &status, 0);
505 }
506 }
507
410 sway_log(L_DEBUG, "Setting background for output %d to %s", output_i, oc->background); 508 sway_log(L_DEBUG, "Setting background for output %d to %s", output_i, oc->background);
411 509
412 size_t bufsize = 4; 510 size_t bufsize = 4;
@@ -421,54 +519,15 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
421 oc->background_option, 519 oc->background_option,
422 NULL, 520 NULL,
423 }; 521 };
424 if (fork() == 0) {
425 execvp(cmd[0], cmd);
426 }
427 }
428
429 // Check for a bar
430 struct bar_config *bar = NULL;
431 int i;
432 for (i = 0; i < config->bars->length; ++i) {
433 bar = config->bars->items[i];
434 bool apply = false;
435 if (bar->outputs) {
436 int j;
437 for (j = 0; j < bar->outputs->length; ++j) {
438 char *o = bar->outputs->items[j];
439 if (strcmp(o, "*") || strcasecmp(o, output->name)) {
440 apply = true;
441 break;
442 }
443 }
444 } else {
445 apply = true;
446 }
447 if (apply) {
448 break;
449 } else {
450 bar = NULL;
451 }
452 }
453 if (bar) {
454 sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, i, bar->id);
455 522
456 size_t bufsize = 4; 523 output->bg_pid = fork();
457 char output_id[bufsize]; 524 if (output->bg_pid == 0) {
458 snprintf(output_id, bufsize, "%d", output_i);
459 output_id[bufsize-1] = 0;
460
461 char *const cmd[] = {
462 "swaybar",
463 "-b",
464 bar->id,
465 output_id,
466 NULL,
467 };
468 if (fork() == 0) {
469 execvp(cmd[0], cmd); 525 execvp(cmd[0], cmd);
470 } 526 }
471 } 527 }
528
529 // load swaybars for output
530 load_swaybars(output, output_i);
472} 531}
473 532
474char *do_var_replacement(char *str) { 533char *do_var_replacement(char *str) {
diff --git a/sway/container.c b/sway/container.c
index 36056ff7..395eb04d 100644
--- a/sway/container.c
+++ b/sway/container.c
@@ -60,6 +60,9 @@ static void free_swayc(swayc_t *cont) {
60 if (cont->app_id) { 60 if (cont->app_id) {
61 free(cont->app_id); 61 free(cont->app_id);
62 } 62 }
63 if (cont->bar_pids) {
64 free_flat_list(cont->bar_pids);
65 }
63 free(cont); 66 free(cont);
64} 67}
65 68
@@ -109,6 +112,8 @@ swayc_t *new_output(wlc_handle handle) {
109 output->width = size->w; 112 output->width = size->w;
110 output->height = size->h; 113 output->height = size->h;
111 output->unmanaged = create_list(); 114 output->unmanaged = create_list();
115 output->bar_pids = create_list();
116 output->bg_pid = 0;
112 117
113 apply_output_config(oc, output); 118 apply_output_config(oc, output);
114 add_child(&root_container, output); 119 add_child(&root_container, output);