Skip to content

Commit

Permalink
Reload swaybar/swaybg on config reload.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mikkeloscar committed Dec 18, 2015
1 parent de219f6 commit ede27ea
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 44 deletions.
2 changes: 2 additions & 0 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ int sway_mouse_binding_cmp(const void *a, const void *b);
int sway_mouse_binding_cmp_buttons(const void *a, const void *b);
void free_sway_mouse_binding(struct sway_mouse_binding *smb);

void load_swaybars(swayc_t *output, int output_idx);

/**
* Allocate and initialize default bar configuration.
*/
Expand Down
6 changes: 6 additions & 0 deletions include/container.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef _SWAY_CONTAINER_H
#define _SWAY_CONTAINER_H
#include <sys/types.h>
#include <wlc/wlc.h>
typedef struct sway_container swayc_t;

Expand Down Expand Up @@ -81,6 +82,11 @@ struct sway_container {
char *class;
char *app_id;

// Used by output containers to keep track of swaybar/swaybg child
// processes.
list_t *bar_pids;
pid_t bg_pid;

int gaps;

list_t *children;
Expand Down
9 changes: 9 additions & 0 deletions sway/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,15 @@ static struct cmd_results *cmd_reload(int argc, char **argv) {
}
if (!load_config(NULL)) return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");

int i;
swayc_t *cont = NULL;
for (i = 0; i < root_container.children->length; ++i) {
cont = root_container.children->items[i];
if (cont->type == C_OUTPUT) {
load_swaybars(cont, i);
}
}

arrange_windows(&root_container, -1, -1);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
Expand Down
147 changes: 103 additions & 44 deletions sway/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <stdlib.h>
#include <unistd.h>
#include <wordexp.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include "wayland-desktop-shell-server-protocol.h"
#include "readline.h"
#include "stringop.h"
Expand Down Expand Up @@ -360,6 +363,91 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
}
}

static void invoke_swaybar(swayc_t *output, struct bar_config *bar, int output_i) {
sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, output_i, bar->id);

size_t bufsize = 4;
char output_id[bufsize];
snprintf(output_id, bufsize, "%d", output_i);
output_id[bufsize-1] = 0;

char *const cmd[] = {
"swaybar",
"-b",
bar->id,
output_id,
NULL,
};

pid_t *pid = malloc(sizeof(pid_t));
*pid = fork();
if (*pid == 0) {
execvp(cmd[0], cmd);
}

// add swaybar pid to output
list_add(output->bar_pids, pid);
}

static void terminate_swaybars(list_t *pids) {
int i, ret;
pid_t *pid;
for (i = 0; i < pids->length; ++i) {
pid = pids->items[i];
ret = kill(*pid, SIGTERM);
if (ret != 0) {
sway_log(L_ERROR, "Unable to terminate swaybar [pid: %d]", *pid);
} else {
int status;
waitpid(*pid, &status, 0);
}
}

// empty pids list
for (i = 0; i < pids->length; ++i) {
pid = pids->items[i];
list_del(pids, i);
free(pid);
}
}

void load_swaybars(swayc_t *output, int output_idx) {
// Check for bars
list_t *bars = create_list();
struct bar_config *bar = NULL;
int i;
for (i = 0; i < config->bars->length; ++i) {
bar = config->bars->items[i];
bool apply = false;
if (bar->outputs) {
int j;
for (j = 0; j < bar->outputs->length; ++j) {
char *o = bar->outputs->items[j];
if (strcmp(o, "*") || strcasecmp(o, output->name)) {
apply = true;
break;
}
}
} else {
apply = true;
}
if (apply) {
list_add(bars, bar);
}
}

// terminate swaybar processes previously spawned for this
// output.
terminate_swaybars(output->bar_pids);

for (i = 0; i < bars->length; ++i) {
bar = bars->items[i];
invoke_swaybar(output, bar, output_idx);
}

list_free(bars);
}

void apply_output_config(struct output_config *oc, swayc_t *output) {
if (oc && oc->width > 0 && oc->height > 0) {
output->width = oc->width;
Expand Down Expand Up @@ -407,6 +495,16 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {

if (oc && oc->background) {

if (output->bg_pid != 0) {
int ret = kill(output->bg_pid, SIGTERM);
if (ret != 0) {
sway_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", output->bg_pid);
} else {
int status;
waitpid(output->bg_pid, &status, 0);
}
}

sway_log(L_DEBUG, "Setting background for output %d to %s", output_i, oc->background);

size_t bufsize = 4;
Expand All @@ -421,54 +519,15 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
oc->background_option,
NULL,
};
if (fork() == 0) {
execvp(cmd[0], cmd);
}
}

// Check for a bar
struct bar_config *bar = NULL;
int i;
for (i = 0; i < config->bars->length; ++i) {
bar = config->bars->items[i];
bool apply = false;
if (bar->outputs) {
int j;
for (j = 0; j < bar->outputs->length; ++j) {
char *o = bar->outputs->items[j];
if (strcmp(o, "*") || strcasecmp(o, output->name)) {
apply = true;
break;
}
}
} else {
apply = true;
}
if (apply) {
break;
} else {
bar = NULL;
}
}
if (bar) {
sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, i, bar->id);

size_t bufsize = 4;
char output_id[bufsize];
snprintf(output_id, bufsize, "%d", output_i);
output_id[bufsize-1] = 0;

char *const cmd[] = {
"swaybar",
"-b",
bar->id,
output_id,
NULL,
};
if (fork() == 0) {
output->bg_pid = fork();
if (output->bg_pid == 0) {
execvp(cmd[0], cmd);
}
}

// load swaybars for output
load_swaybars(output, output_i);
}

char *do_var_replacement(char *str) {
Expand Down
5 changes: 5 additions & 0 deletions sway/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ static void free_swayc(swayc_t *cont) {
if (cont->app_id) {
free(cont->app_id);
}
if (cont->bar_pids) {
free_flat_list(cont->bar_pids);
}
free(cont);
}

Expand Down Expand Up @@ -109,6 +112,8 @@ swayc_t *new_output(wlc_handle handle) {
output->width = size->w;
output->height = size->h;
output->unmanaged = create_list();
output->bar_pids = create_list();
output->bg_pid = 0;

apply_output_config(oc, output);
add_child(&root_container, output);
Expand Down

0 comments on commit ede27ea

Please sign in to comment.