diff options
Diffstat (limited to 'swaybar/bar.c')
-rw-r--r-- | swaybar/bar.c | 122 |
1 files changed, 79 insertions, 43 deletions
diff --git a/swaybar/bar.c b/swaybar/bar.c index d80c9af3..b6329123 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -1,9 +1,10 @@ #include <stdlib.h> #include <unistd.h> +#include <string.h> #include <fcntl.h> #include <errno.h> -#include <sys/types.h> #include <sys/wait.h> +#include <poll.h> #include "ipc-client.h" #include "list.h" @@ -17,11 +18,7 @@ static void bar_init(struct bar *bar) { bar->config = init_config(); bar->status = init_status_line(); - bar->output = malloc(sizeof(struct output)); - bar->output->window = NULL; - bar->output->registry = NULL; - bar->output->workspaces = create_list(); - bar->output->name = NULL; + bar->outputs = create_list(); } static void spawn_status_cmd_proc(struct bar *bar) { @@ -49,78 +46,109 @@ static void spawn_status_cmd_proc(struct bar *bar) { } } +struct output *new_output(const char *name) { + struct output *output = malloc(sizeof(struct output)); + output->name = strdup(name); + output->window = NULL; + output->registry = NULL; + output->workspaces = create_list(); + return output; +} -void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id, int desired_output) { +void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { /* initialize bar with default values */ bar_init(bar); - bar->output->registry = registry_poll(); - - if (!bar->output->registry->desktop_shell) { - sway_abort("swaybar requires the compositor to support the desktop-shell extension."); - } - /* connect to sway ipc */ bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_event_socketfd = ipc_open_socket(socket_path); - ipc_bar_init(bar, desired_output, bar_id); + ipc_bar_init(bar, bar_id); - struct output_state *output = bar->output->registry->outputs->items[desired_output]; + int i; + for (i = 0; i < bar->outputs->length; ++i) { + struct output *bar_output = bar->outputs->items[i]; - bar->output->window = window_setup(bar->output->registry, output->width, 30, false); - if (!bar->output->window) { - sway_abort("Failed to create window."); - } - desktop_shell_set_panel(bar->output->registry->desktop_shell, output->output, bar->output->window->surface); - desktop_shell_set_panel_position(bar->output->registry->desktop_shell, bar->config->position); + bar_output->registry = registry_poll(); - /* set font */ - bar->output->window->font = bar->config->font; + if (!bar_output->registry->desktop_shell) { + sway_abort("swaybar requires the compositor to support the desktop-shell extension."); + } - /* set window height */ - set_window_height(bar->output->window, bar->config->height); + struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; + bar_output->window = window_setup(bar_output->registry, output->width, 30, false); + if (!bar_output->window) { + sway_abort("Failed to create window."); + } + desktop_shell_set_panel(bar_output->registry->desktop_shell, output->output, bar_output->window->surface); + desktop_shell_set_panel_position(bar_output->registry->desktop_shell, bar->config->position); + + /* set font */ + bar_output->window->font = bar->config->font; + + /* set window height */ + set_window_height(bar_output->window, bar->config->height); + } /* spawn status command */ spawn_status_cmd_proc(bar); } void bar_run(struct bar *bar) { - fd_set readfds; - int activity; + int pfds = bar->outputs->length + 2; + struct pollfd *pfd = malloc(pfds * sizeof(struct pollfd)); bool dirty = true; + pfd[0].fd = bar->ipc_event_socketfd; + pfd[0].events = POLLIN; + pfd[1].fd = bar->status_read_fd; + pfd[1].events = POLLIN; + + int i; + for (i = 0; i < bar->outputs->length; ++i) { + struct output *output = bar->outputs->items[i]; + pfd[i+2].fd = wl_display_get_fd(output->registry->display); + pfd[i+2].events = POLLIN; + } + while (1) { if (dirty) { - struct output *output = bar->output; - if (window_prerender(output->window) && output->window->cairo) { - render(output, bar->config, bar->status); - window_render(output->window); - if (wl_display_dispatch(output->registry->display) == -1) { - break; + int i; + for (i = 0; i < bar->outputs->length; ++i) { + struct output *output = bar->outputs->items[i]; + if (window_prerender(output->window) && output->window->cairo) { + render(output, bar->config, bar->status); + window_render(output->window); + wl_display_flush(output->registry->display); } } } dirty = false; - FD_ZERO(&readfds); - FD_SET(bar->ipc_event_socketfd, &readfds); - FD_SET(bar->status_read_fd, &readfds); - activity = select(FD_SETSIZE, &readfds, NULL, NULL, NULL); - if (activity < 0) { - sway_log(L_ERROR, "polling failed: %d", errno); - } + poll(pfd, pfds, -1); - if (FD_ISSET(bar->ipc_event_socketfd, &readfds)) { + if (pfd[0].revents & POLLIN) { sway_log(L_DEBUG, "Got IPC event."); dirty = handle_ipc_event(bar); } - if (bar->config->status_command && FD_ISSET(bar->status_read_fd, &readfds)) { + if (bar->config->status_command && pfd[1].revents & POLLIN) { sway_log(L_DEBUG, "Got update from status command."); dirty = handle_status_line(bar); } + + // dispatch wl_display events + for (i = 0; i < bar->outputs->length; ++i) { + struct output *output = bar->outputs->items[i]; + if (pfd[i+2].revents & POLLIN) { + if (wl_display_dispatch(output->registry->display) == -1) { + sway_log(L_ERROR, "failed to dispatch wl: %d", errno); + } + } else { + wl_display_dispatch_pending(output->registry->display); + } + } } } @@ -149,6 +177,14 @@ static void free_output(struct output *output) { free(output); } +static void free_outputs(list_t *outputs) { + int i; + for (i = 0; i < outputs->length; ++i) { + free_output(outputs->items[i]); + } + list_free(outputs); +} + static void terminate_status_command(pid_t pid) { if (pid) { // terminate status_command process @@ -164,7 +200,7 @@ static void terminate_status_command(pid_t pid) { void bar_teardown(struct bar *bar) { free_config(bar->config); - free_output(bar->output); + free_outputs(bar->outputs); free_status_line(bar->status); /* close sockets/pipes */ |