Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload swaybar/swaybg on config reload. #358

Merged
merged 2 commits into from
Dec 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ 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);
void terminate_swaybars(list_t *pids);
void terminate_swaybg(pid_t pid);

/**
* 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;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct is getting kind of out of control. Half of the properties only apply to a certain kind of swayc (i.e. C_OUTPUT, in this case). Can we figure out a good way of splitting these up?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is the best approach, but what about adding a void* field to swayc_t which can be used for whatever, in this case it would point to:

struct swayc_output {
    list_t *bar_pids;
    pid_t bg_pid;
    // other fields unique to a swayc_t of type C_OUTPUT
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a union of pointers to type-specific data?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's probably better so we don't need to cast all over the place.

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
151 changes: 107 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,101 @@ 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);
}

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 terminate_swaybg(pid_t pid) {
int ret = kill(pid, SIGTERM);
if (ret != 0) {
sway_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", pid);
} else {
int status;
waitpid(pid, &status, 0);
}
}

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 +505,10 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {

if (oc && oc->background) {

if (output->bg_pid != 0) {
terminate_swaybg(output->bg_pid);
}

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

size_t bufsize = 4;
Expand All @@ -421,54 +523,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
9 changes: 9 additions & 0 deletions sway/container.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ static void free_swayc(swayc_t *cont) {
if (cont->app_id) {
free(cont->app_id);
}
if (cont->bar_pids) {
terminate_swaybars(cont->bar_pids);
free_flat_list(cont->bar_pids);
}
if (cont->bg_pid != 0) {
terminate_swaybg(cont->bg_pid);
}
free(cont);
}

Expand Down Expand Up @@ -109,6 +116,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