diff options
Diffstat (limited to 'swaybar')
| -rw-r--r-- | swaybar/main.c | 118 | ||||
| -rw-r--r-- | swaybar/state.c | 112 | ||||
| -rw-r--r-- | swaybar/state.h | 13 | 
3 files changed, 124 insertions, 119 deletions
| diff --git a/swaybar/main.c b/swaybar/main.c index 976fcea0..51846bca 100644 --- a/swaybar/main.c +++ b/swaybar/main.c @@ -1,86 +1,28 @@ -#include <fcntl.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <stdint.h>  #include <stdbool.h> -#include <unistd.h> -#include <sys/select.h> -#include <sys/wait.h> -#include <errno.h> -#include <json-c/json.h> -#include <sys/un.h> -#include <sys/socket.h> -#include <sys/ioctl.h>  #include <getopt.h>  #include "ipc-client.h" -#include "client/registry.h" -#include "client/window.h" -#include "client/pango.h" -#include "stringop.h"  #include "log.h"  #include "state.h" -#include "config.h" -#include "render.h" -#include "status_line.h" -#include "ipc.h" -struct swaybar_state *state; +struct swaybar_state state;  void sway_terminate(void) { -	free_state(state); +	state_teardown(&state);  	exit(EXIT_FAILURE);  }  void sig_handler(int signal) { -	free_state(state); +	state_teardown(&state);  	exit(0);  } -void poll_for_update() { -	fd_set readfds; -	int activity; -	bool dirty = true; - -	while (1) { -		if (dirty) { -			struct output *output = state->output; -			if (window_prerender(output->window) && output->window->cairo) { -				render(output, state->config, state->status); -				window_render(output->window); -				if (wl_display_dispatch(output->registry->display) == -1) { -					break; -				} -			} -		} - -		dirty = false; -		FD_ZERO(&readfds); -		FD_SET(state->ipc_event_socketfd, &readfds); -		FD_SET(state->status_read_fd, &readfds); - -		activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); -		if (activity < 0) { -			sway_log(L_ERROR, "polling failed: %d", errno); -		} - -		if (FD_ISSET(state->ipc_event_socketfd, &readfds)) { -			sway_log(L_DEBUG, "Got IPC event."); -			dirty = handle_ipc_event(state); -		} - -		if (state->config->status_command && FD_ISSET(state->status_read_fd, &readfds)) { -			sway_log(L_DEBUG, "Got update from status command."); -			dirty = handle_status_line(state); -		} -	} -} -  int main(int argc, char **argv) {  	char *socket_path = NULL;  	char *bar_id = NULL;  	bool debug = false; -	state = init_state();  	static struct option long_options[] = {  		{"help", no_argument, NULL, 'h'}, @@ -145,72 +87,30 @@ int main(int argc, char **argv) {  		init_log(L_ERROR);  	} -	state->output->registry = registry_poll(); - -	if (!state->output->registry->desktop_shell) { -		sway_abort("swaybar requires the compositor to support the desktop-shell extension."); -	} -  	if (!socket_path) {  		socket_path = get_socketpath();  		if (!socket_path) {  			sway_abort("Unable to retrieve socket path");  		}  	} -	state->ipc_socketfd = ipc_open_socket(socket_path); -	state->ipc_event_socketfd = ipc_open_socket(socket_path);  	if (argc == optind) {  		sway_abort("No output index provided");  	}  	int desired_output = atoi(argv[optind]); -	ipc_bar_init(state, desired_output, bar_id); - -	struct output_state *output = state->output->registry->outputs->items[desired_output]; -	state->output->window = window_setup(state->output->registry, output->width, 30, false); -	if (!state->output->window) { -		sway_abort("Failed to create window."); -	} -	desktop_shell_set_panel(state->output->registry->desktop_shell, output->output, state->output->window->surface); -	desktop_shell_set_panel_position(state->output->registry->desktop_shell, state->config->position); - -	/* set font */ -	state->output->window->font = state->config->font; - -	/* set window height */ -	set_window_height(state->output->window, state->config->height); - -	if (state->config->status_command) { -		int pipefd[2]; -		pipe(pipefd); -		state->status_command_pid = fork(); -		if (state->status_command_pid == 0) { -			close(pipefd[0]); -			dup2(pipefd[1], STDOUT_FILENO); -			close(pipefd[1]); -			char *const cmd[] = { -				"sh", -				"-c", -				state->config->status_command, -				NULL, -			}; -			execvp(cmd[0], cmd); -			return 0; -		} +	signal(SIGTERM, sig_handler); -		close(pipefd[1]); -		state->status_read_fd = pipefd[0]; -		fcntl(state->status_read_fd, F_SETFL, O_NONBLOCK); -	} +	state_setup(&state, socket_path, bar_id, desired_output); -	signal(SIGTERM, sig_handler); +	free(socket_path); +	free(bar_id); -	poll_for_update(); +	state_run(&state);  	// gracefully shutdown swaybar and status_command -	free_state(state); +	state_teardown(&state);  	return 0;  } diff --git a/swaybar/state.c b/swaybar/state.c index 26cdcafe..535efbc4 100644 --- a/swaybar/state.c +++ b/swaybar/state.c @@ -1,16 +1,20 @@  #include <stdlib.h>  #include <unistd.h> +#include <fcntl.h> +#include <errno.h>  #include <sys/types.h>  #include <sys/wait.h> +#include "ipc-client.h"  #include "list.h"  #include "log.h" +#include "ipc.h" +#include "render.h"  #include "config.h"  #include "status_line.h"  #include "state.h" -struct swaybar_state *init_state() { -	struct swaybar_state *state = calloc(1, sizeof(struct swaybar_state)); +static void state_init(struct swaybar_state *state) {  	state->config = init_config();  	state->status = init_status_line();  	state->output = malloc(sizeof(struct output)); @@ -18,8 +22,106 @@ struct swaybar_state *init_state() {  	state->output->registry = NULL;  	state->output->workspaces = create_list();  	state->output->name = NULL; +} + +static void spawn_status_cmd_proc(struct swaybar_state *state) { +	if (state->config->status_command) { +		int pipefd[2]; +		pipe(pipefd); +		state->status_command_pid = fork(); +		if (state->status_command_pid == 0) { +			close(pipefd[0]); +			dup2(pipefd[1], STDOUT_FILENO); +			close(pipefd[1]); +			char *const cmd[] = { +				"sh", +				"-c", +				state->config->status_command, +				NULL, +			}; +			execvp(cmd[0], cmd); +			return; +		} -	return state; +		close(pipefd[1]); +		state->status_read_fd = pipefd[0]; +		fcntl(state->status_read_fd, F_SETFL, O_NONBLOCK); +	} +} + + +void state_setup(struct swaybar_state *state, const char *socket_path, const char *bar_id, int desired_output) { +	/* initialize state with default values */ +	state_init(state); + +	state->output->registry = registry_poll(); + +	if (!state->output->registry->desktop_shell) { +		sway_abort("swaybar requires the compositor to support the desktop-shell extension."); +	} + +	/* connect to sway ipc */ +	state->ipc_socketfd = ipc_open_socket(socket_path); +	state->ipc_event_socketfd = ipc_open_socket(socket_path); + +	ipc_bar_init(state, desired_output, bar_id); + +	struct output_state *output = state->output->registry->outputs->items[desired_output]; + +	state->output->window = window_setup(state->output->registry, output->width, 30, false); +	if (!state->output->window) { +		sway_abort("Failed to create window."); +	} +	desktop_shell_set_panel(state->output->registry->desktop_shell, output->output, state->output->window->surface); +	desktop_shell_set_panel_position(state->output->registry->desktop_shell, state->config->position); + +	/* set font */ +	state->output->window->font = state->config->font; + +	/* set window height */ +	set_window_height(state->output->window, state->config->height); + +	/* spawn status command */ +	spawn_status_cmd_proc(state); +} + +void state_run(struct swaybar_state *state) { +	fd_set readfds; +	int activity; +	bool dirty = true; + +	while (1) { +		if (dirty) { +			struct output *output = state->output; +			if (window_prerender(output->window) && output->window->cairo) { +				render(output, state->config, state->status); +				window_render(output->window); +				if (wl_display_dispatch(output->registry->display) == -1) { +					break; +				} +			} +		} + +		dirty = false; +		FD_ZERO(&readfds); +		FD_SET(state->ipc_event_socketfd, &readfds); +		FD_SET(state->status_read_fd, &readfds); + +		activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); +		if (activity < 0) { +			sway_log(L_ERROR, "polling failed: %d", errno); +		} + +		if (FD_ISSET(state->ipc_event_socketfd, &readfds)) { +			sway_log(L_DEBUG, "Got IPC event."); +			dirty = handle_ipc_event(state); +		} + +		if (state->config->status_command && FD_ISSET(state->status_read_fd, &readfds)) { +			sway_log(L_DEBUG, "Got update from status command."); +			dirty = handle_status_line(state); +		} +	}  }  void free_workspaces(list_t *workspaces) { @@ -60,7 +162,7 @@ static void terminate_status_command(pid_t pid) {  	}  } -void free_state(struct swaybar_state *state) { +void state_teardown(struct swaybar_state *state) {  	free_config(state->config);  	free_output(state->output);  	free_status_line(state->status); @@ -80,6 +182,4 @@ void free_state(struct swaybar_state *state) {  	/* terminate status command process */  	terminate_status_command(state->status_command_pid); - -	free(state);  } diff --git a/swaybar/state.h b/swaybar/state.h index e09807d0..985002f8 100644 --- a/swaybar/state.h +++ b/swaybar/state.h @@ -33,9 +33,14 @@ struct workspace {  };  /** - * Initialize state. + * Setup state.   */ -struct swaybar_state *init_state(); +void state_setup(struct swaybar_state *state, const char *socket_path, const char *bar_id, int desired_output); + +/** + * State mainloop. + */ +void state_run(struct swaybar_state *state);  /**   * free workspace list. @@ -43,8 +48,8 @@ struct swaybar_state *init_state();  void free_workspaces(list_t *workspaces);  /** - * Free state struct. + * Teardown state.   */ -void free_state(struct swaybar_state *state); +void state_teardown(struct swaybar_state *state);  #endif /* _SWAYBAR_STATE_H */ | 
