diff options
Diffstat (limited to 'sway/config/bar.c')
| -rw-r--r-- | sway/config/bar.c | 95 | 
1 files changed, 95 insertions, 0 deletions
| diff --git a/sway/config/bar.c b/sway/config/bar.c index ecc357d0..5e02c01c 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c @@ -141,3 +141,98 @@ cleanup:  	free_bar_config(bar);  	return NULL;  } + +void invoke_swaybar(struct bar_config *bar) { +	// Pipe to communicate errors +	int filedes[2]; +	if (pipe(filedes) == -1) { +		wlr_log(L_ERROR, "Pipe setup failed! Cannot fork into bar"); +		return; +	} + +	bar->pid = fork(); +	if (bar->pid == 0) { +		close(filedes[0]); + +		// run custom swaybar +		size_t len = snprintf(NULL, 0, "%s -b %s", +				bar->swaybar_command ? bar->swaybar_command : "swaybar", +				bar->id); +		char *command = malloc(len + 1); +		if (!command) { +			const char msg[] = "Unable to allocate swaybar command string"; +			size_t len = sizeof(msg); +			if (write(filedes[1], &len, sizeof(int))) {}; +			if (write(filedes[1], msg, len)) {}; +			close(filedes[1]); +			exit(1); +		} +		snprintf(command, len + 1, "%s -b %s", +				bar->swaybar_command ? bar->swaybar_command : "swaybar", +				bar->id); +		char *const cmd[] = { "sh", "-c", command, NULL, }; +		close(filedes[1]); +		execvp(cmd[0], cmd); +		exit(1); +	} +	close(filedes[0]); +	ssize_t len; +	if (read(filedes[1], &len, sizeof(int)) == sizeof(int)) { +		char *buf = malloc(len); +		if(!buf) { +			wlr_log(L_ERROR, "Cannot allocate error string"); +			return; +		} +		if (read(filedes[1], buf, len)) { +			wlr_log(L_ERROR, "%s", buf); +		} +		free(buf); +	} +	close(filedes[1]); +} + +static void terminate_swaybar(pid_t pid) { +	int ret = kill(pid, SIGTERM); +	if (ret != 0) { +		wlr_log_errno(L_ERROR, "Unable to terminate swaybar %d", pid); +	} else { +		int status; +		waitpid(pid, &status, 0); +	} +} + +static bool active_output(const char *name) { +	swayc_t *cont = NULL; +	for (int i = 0; i < root_container.children->length; ++i) { +		cont = root_container.children->items[i]; +		if (cont->type == C_OUTPUT && strcasecmp(name, cont->name) == 0) { +			return true; +		} +	} +	return false; +} + +void load_swaybars() { +	for (int i = 0; i < config->bars->length; ++i) { +		struct bar_config *bar = config->bars->items[i]; +		bool apply = false; +		if (bar->outputs) { +			for (int j = 0; j < bar->outputs->length; ++j) { +				char *o = bar->outputs->items[j]; +				if (!strcmp(o, "*") || active_output(o)) { +					apply = true; +					break; +				} +			} +		} else { +			apply = true; +		} +		if (apply) { +			if (bar->pid != 0) { +				terminate_swaybar(bar->pid); +			} +			wlr_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); +			invoke_swaybar(bar); +		} +	} +} | 
