From cab1352801b62d1b8a12ca1c995cb24445ce4bc9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 23:04:20 -0400 Subject: Start port of swaybar to layer shell This starts up the event loop and wayland display and shims out the basic top level rendering concepts. Also includes some changes to incorporate pango into the 1.x codebase properly. --- swaybar/bar.c | 444 +++++++++++++--------------------------------------------- 1 file changed, 100 insertions(+), 344 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index f12923a8..e1d594b4 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -1,390 +1,146 @@ #define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include #include -#include #include -#include -#include #include -#include -#include -#ifdef __FreeBSD__ -#include -#else -#include -#endif -#ifdef ENABLE_TRAY -#include -#include "swaybar/tray/sni_watcher.h" -#include "swaybar/tray/tray.h" -#include "swaybar/tray/sni.h" -#endif -#include "swaybar/ipc.h" +#include +#include +#include #include "swaybar/render.h" #include "swaybar/config.h" -#include "swaybar/status_line.h" #include "swaybar/event_loop.h" #include "swaybar/bar.h" -#include "ipc-client.h" #include "list.h" -#include "log.h" +#include "pango.h" +#include "pool-buffer.h" +#include "wlr-layer-shell-unstable-v1-client-protocol.h" -static void bar_init(struct bar *bar) { +static void bar_init(struct swaybar *bar) { bar->config = init_config(); - bar->status = init_status_line(); - bar->outputs = create_list(); + wl_list_init(&bar->outputs); } -static void spawn_status_cmd_proc(struct bar *bar) { - if (bar->config->status_command) { - int pipe_read_fd[2]; - int pipe_write_fd[2]; - - if (pipe(pipe_read_fd) != 0) { - sway_log(L_ERROR, "Unable to create pipes for status_command fork"); - return; - } - if (pipe(pipe_write_fd) != 0) { - sway_log(L_ERROR, "Unable to create pipe for status_command fork (write)"); - close(pipe_read_fd[0]); - close(pipe_read_fd[1]); - return; - } - - bar->status_command_pid = fork(); - if (bar->status_command_pid == 0) { - close(pipe_read_fd[0]); - dup2(pipe_read_fd[1], STDOUT_FILENO); - close(pipe_read_fd[1]); - - dup2(pipe_write_fd[0], STDIN_FILENO); - close(pipe_write_fd[0]); - close(pipe_write_fd[1]); - - char *const cmd[] = { - "sh", - "-c", - bar->config->status_command, - NULL, - }; - execvp(cmd[0], cmd); - return; - } - - close(pipe_read_fd[1]); - bar->status_read_fd = pipe_read_fd[0]; - fcntl(bar->status_read_fd, F_SETFL, O_NONBLOCK); - - close(pipe_write_fd[0]); - bar->status_write_fd = pipe_write_fd[1]; - fcntl(bar->status_write_fd, F_SETFL, O_NONBLOCK); - } -} - -struct output *new_output(const char *name) { - struct output *output = malloc(sizeof(struct output)); +struct swaybar_output *new_output(const char *name) { + struct swaybar_output *output = malloc(sizeof(struct swaybar_output)); output->name = strdup(name); - output->window = NULL; - output->registry = NULL; - output->workspaces = create_list(); -#ifdef ENABLE_TRAY - output->items = create_list(); -#endif return output; } -static void mouse_button_notify(struct window *window, int x, int y, - uint32_t button, uint32_t state_w) { - sway_log(L_DEBUG, "Mouse button %d clicked at %d %d %d", button, x, y, state_w); - if (!state_w) { - return; - } - - struct output *clicked_output = NULL; - for (int i = 0; i < swaybar.outputs->length; i++) { - struct output *output = swaybar.outputs->items[i]; - if (window == output->window) { - clicked_output = output; - break; - } - } - - if (!sway_assert(clicked_output != NULL, "Got pointer event for non-existing output")) { - return; - } - - double button_x = 0.5; - for (int i = 0; i < clicked_output->workspaces->length; i++) { - struct workspace *workspace = clicked_output->workspaces->items[i]; - int button_width, button_height; - - workspace_button_size(window, workspace->name, &button_width, &button_height); - - button_x += button_width; - if (x <= button_x) { - ipc_send_workspace_command(workspace->name); - break; - } - } - - switch (button) { - case BTN_LEFT: - status_line_mouse_event(&swaybar, x, y, 1); - break; - case BTN_MIDDLE: - status_line_mouse_event(&swaybar, x, y, 2); - break; - case BTN_RIGHT: - status_line_mouse_event(&swaybar, x, y, 3); - break; - } - -#ifdef ENABLE_TRAY - tray_mouse_event(clicked_output, x, y, button, state_w); -#endif - +static void layer_surface_configure(void *data, + struct zwlr_layer_surface_v1 *surface, + uint32_t serial, uint32_t width, uint32_t height) { + struct swaybar_output *output = data; + output->width = width; + output->height = height; + zwlr_layer_surface_v1_ack_configure(surface, serial); + render_frame(output->bar, output); } -static void mouse_scroll_notify(struct window *window, enum scroll_direction direction) { - sway_log(L_DEBUG, "Mouse wheel scrolled %s", direction == SCROLL_UP ? "up" : "down"); - - // If there are status blocks and click_events are enabled - // check if the position is within the status area and if so - // tell the status line to output the event and skip workspace - // switching below. - int num_blocks = swaybar.status->block_line->length; - if (swaybar.status->click_events && num_blocks > 0) { - struct status_block *first_block = swaybar.status->block_line->items[0]; - int x = window->pointer_input.last_x; - int y = window->pointer_input.last_y; - if (x > first_block->x) { - if (direction == SCROLL_UP) { - status_line_mouse_event(&swaybar, x, y, 4); - } else { - status_line_mouse_event(&swaybar, x, y, 5); - } - return; - } - } +static void layer_surface_closed(void *_output, + struct zwlr_layer_surface_v1 *surface) { + // TODO: Deal with hotplugging + struct swaybar_output *output = output; + zwlr_layer_surface_v1_destroy(output->layer_surface); + wl_surface_destroy(output->surface); +} - if (!swaybar.config->wrap_scroll) { - // Find output this window lives on - int i; - struct output *output = NULL; - for (i = 0; i < swaybar.outputs->length; ++i) { - output = swaybar.outputs->items[i]; - if (output->window == window) { - break; - } - } - if (!sway_assert(i != swaybar.outputs->length, "Unknown window in scroll event")) { - return; - } - int focused = -1; - for (i = 0; i < output->workspaces->length; ++i) { - struct workspace *ws = output->workspaces->items[i]; - if (ws->focused) { - focused = i; - break; - } - } - if (!sway_assert(focused != -1, "Scroll wheel event received on inactive output")) { - return; - } - if ((focused == 0 && direction == SCROLL_UP) || - (focused == output->workspaces->length - 1 && direction == SCROLL_DOWN)) { - // Do not wrap - return; - } +struct zwlr_layer_surface_v1_listener layer_surface_listener = { + .configure = layer_surface_configure, + .closed = layer_surface_closed, +}; + +static void handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) { + struct swaybar *bar = data; + if (strcmp(interface, wl_compositor_interface.name) == 0) { + bar->compositor = wl_registry_bind(registry, name, + &wl_compositor_interface, 1); + } else if (strcmp(interface, wl_shm_interface.name) == 0) { + bar->shm = wl_registry_bind(registry, name, + &wl_shm_interface, 1); + } else if (strcmp(interface, wl_output_interface.name) == 0) { + static int idx = 0; + struct swaybar_output *output = + calloc(1, sizeof(struct swaybar_output)); + output->bar = bar; + output->output = wl_registry_bind(registry, name, + &wl_output_interface, 1); + output->idx = idx++; + wl_list_insert(&bar->outputs, &output->link); + } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { + bar->layer_shell = wl_registry_bind( + registry, name, &zwlr_layer_shell_v1_interface, 1); } +} - const char *workspace_name = direction == SCROLL_UP ? "prev_on_output" : "next_on_output"; - ipc_send_workspace_command(workspace_name); +static void handle_global_remove(void *data, struct wl_registry *registry, + uint32_t name) { + // who cares } -void bar_setup(struct bar *bar, const char *socket_path, const char *bar_id) { - /* initialize bar with default values */ - bar_init(bar); +static const struct wl_registry_listener registry_listener = { + .global = handle_global, + .global_remove = handle_global_remove, +}; - /* Initialize event loop lists */ +void bar_setup(struct swaybar *bar, + const char *socket_path, const char *bar_id) { + bar_init(bar); init_event_loop(); - /* 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, bar_id); - - int i; - for (i = 0; i < bar->outputs->length; ++i) { - struct output *bar_output = bar->outputs->items[i]; - - bar_output->registry = registry_poll(); - - if (!bar_output->registry->desktop_shell) { - sway_abort("swaybar requires the compositor to support the desktop-shell extension."); - } - - struct output_state *output = bar_output->registry->outputs->items[bar_output->idx]; - - bar_output->window = window_setup(bar_output->registry, - output->width / output->scale, 30, output->scale, 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, + assert(bar->display = wl_display_connect(NULL)); + + struct wl_registry *registry = wl_display_get_registry(bar->display); + wl_registry_add_listener(registry, ®istry_listener, bar); + wl_display_roundtrip(bar->display); + assert(bar->compositor && bar->layer_shell && bar->shm); + + // TODO: we might not necessarily be meant to do all of the outputs + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + assert(output->surface = wl_compositor_create_surface(bar->compositor)); + output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + bar->layer_shell, output->surface, output->output, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); + assert(output->layer_surface); + zwlr_layer_surface_v1_add_listener(output->layer_surface, + &layer_surface_listener, output); + zwlr_layer_surface_v1_set_anchor(output->layer_surface, bar->config->position); - - window_make_shell(bar_output->window); - - /* set font */ - bar_output->window->font = bar->config->font; - - /* set mouse event callbacks */ - bar_output->window->pointer_input.notify_button = mouse_button_notify; - bar_output->window->pointer_input.notify_scroll = mouse_scroll_notify; - - /* set window height */ - set_window_height(bar_output->window, bar->config->height); + render_frame(bar, output); } - /* spawn status command */ - spawn_status_cmd_proc(bar); - -#ifdef ENABLE_TRAY - init_tray(bar); -#endif } -bool dirty = true; - -static void respond_ipc(int fd, short mask, void *_bar) { - struct bar *bar = (struct bar *)_bar; - sway_log(L_DEBUG, "Got IPC event."); - dirty = handle_ipc_event(bar); -} - -static void respond_command(int fd, short mask, void *_bar) { - struct bar *bar = (struct bar *)_bar; - dirty = handle_status_line(bar); -} - -static void respond_output(int fd, short mask, void *_output) { - struct output *output = (struct output *)_output; - if (wl_display_dispatch(output->registry->display) == -1) { - sway_log(L_ERROR, "failed to dispatch wl: %d", errno); +static void display_in(int fd, short mask, void *_bar) { + struct swaybar *bar = (struct swaybar *)_bar; + if (wl_display_dispatch(bar->display) == -1) { + wlr_log(L_ERROR, "failed to dispatch wl: %d", errno); } } -void bar_run(struct bar *bar) { - add_event(bar->ipc_event_socketfd, POLLIN, respond_ipc, bar); - add_event(bar->status_read_fd, POLLIN, respond_command, bar); - - int i; - for (i = 0; i < bar->outputs->length; ++i) { - struct output *output = bar->outputs->items[i]; - add_event(wl_display_get_fd(output->registry->display), - POLLIN, respond_output, output); - } - +void bar_run(struct swaybar *bar) { + add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); while (1) { - if (dirty) { - 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; - event_loop_poll(); -#ifdef ENABLE_TRAY - dispatch_dbus(); -#endif } } -void free_workspaces(list_t *workspaces) { - int i; - for (i = 0; i < workspaces->length; ++i) { - struct workspace *ws = workspaces->items[i]; - free(ws->name); - free(ws); +static void free_outputs(struct wl_list *list) { + struct swaybar_output *output, *tmp; + wl_list_for_each_safe(output, tmp, list, link) { + wl_list_remove(&output->link); + free(output->name); + free(output); } - list_free(workspaces); } -static void free_output(struct output *output) { - window_teardown(output->window); - if (output->registry) { - registry_teardown(output->registry); - } - - free(output->name); - - if (output->workspaces) { - free_workspaces(output->workspaces); - } - - 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 - int ret = kill(pid, SIGTERM); - if (ret != 0) { - sway_log(L_ERROR, "Unable to terminate status_command [pid: %d]", pid); - } else { - int status; - waitpid(pid, &status, 0); - } - } -} - -void bar_teardown(struct bar *bar) { +void bar_teardown(struct swaybar *bar) { + free_outputs(&bar->outputs); if (bar->config) { free_config(bar->config); } - - if (bar->outputs) { - free_outputs(bar->outputs); - } - - if (bar->status) { - free_status_line(bar->status); - } - - /* close sockets/pipes */ - if (bar->status_read_fd) { - close(bar->status_read_fd); - } - - if (bar->status_write_fd) { - close(bar->status_write_fd); - } - - if (bar->ipc_socketfd) { - close(bar->ipc_socketfd); - } - - if (bar->ipc_event_socketfd) { - close(bar->ipc_event_socketfd); - } - - /* terminate status command process */ - terminate_status_command(bar->status_command_pid); } -- cgit v1.2.3 From 5c9ad035db1bebba3f1954dd1f4328c6421776d4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 28 Mar 2018 23:56:02 -0400 Subject: Wire up basic IPC support --- swaybar/bar.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index e1d594b4..433e2948 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -14,6 +14,8 @@ #include "swaybar/config.h" #include "swaybar/event_loop.h" #include "swaybar/bar.h" +#include "swaybar/ipc.h" +#include "ipc-client.h" #include "list.h" #include "pango.h" #include "pool-buffer.h" @@ -92,6 +94,10 @@ void bar_setup(struct swaybar *bar, bar_init(bar); init_event_loop(); + bar->ipc_socketfd = ipc_open_socket(socket_path); + bar->ipc_event_socketfd = ipc_open_socket(socket_path); + ipc_get_config(bar, bar_id); + assert(bar->display = wl_display_connect(NULL)); struct wl_registry *registry = wl_display_get_registry(bar->display); @@ -122,6 +128,11 @@ static void display_in(int fd, short mask, void *_bar) { } } +static void ipc_in(int fd, short mask, void *_bar) { + struct swaybar *bar = (struct swaybar *)_bar; + handle_ipc_event(bar); +} + void bar_run(struct swaybar *bar) { add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); while (1) { -- cgit v1.2.3 From e5e8094dc3119584ae611c3197b38243b6c016c9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 00:07:35 -0400 Subject: Only utilize the configured outputs --- swaybar/bar.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 433e2948..a6e3b780 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -65,13 +65,13 @@ static void handle_global(void *data, struct wl_registry *registry, bar->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); } else if (strcmp(interface, wl_output_interface.name) == 0) { - static int idx = 0; + static size_t index = 0; struct swaybar_output *output = calloc(1, sizeof(struct swaybar_output)); output->bar = bar; output->output = wl_registry_bind(registry, name, &wl_output_interface, 1); - output->idx = idx++; + output->index = index++; wl_list_insert(&bar->outputs, &output->link); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { bar->layer_shell = wl_registry_bind( @@ -108,16 +108,24 @@ void bar_setup(struct swaybar *bar, // TODO: we might not necessarily be meant to do all of the outputs struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { - assert(output->surface = wl_compositor_create_surface(bar->compositor)); - output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - bar->layer_shell, output->surface, output->output, - ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); - assert(output->layer_surface); - zwlr_layer_surface_v1_add_listener(output->layer_surface, - &layer_surface_listener, output); - zwlr_layer_surface_v1_set_anchor(output->layer_surface, - bar->config->position); - render_frame(bar, output); + struct config_output *coutput; + wl_list_for_each(coutput, &bar->config->outputs, link) { + if (coutput->index != output->index) { + continue; + } + assert(output->surface = wl_compositor_create_surface( + bar->compositor)); + output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + bar->layer_shell, output->surface, output->output, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); + assert(output->layer_surface); + zwlr_layer_surface_v1_add_listener(output->layer_surface, + &layer_surface_listener, output); + zwlr_layer_surface_v1_set_anchor(output->layer_surface, + bar->config->position); + render_frame(bar, output); + break; + } } } -- cgit v1.2.3 From 3399ad9840f0d3d42b377f4404115d887f65e18a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 00:21:05 -0400 Subject: Round up workspaces on each output --- swaybar/bar.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index a6e3b780..68dea408 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -72,6 +72,7 @@ static void handle_global(void *data, struct wl_registry *registry, output->output = wl_registry_bind(registry, name, &wl_output_interface, 1); output->index = index++; + wl_list_init(&output->workspaces); wl_list_insert(&bar->outputs, &output->link); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { bar->layer_shell = wl_registry_bind( @@ -96,7 +97,7 @@ void bar_setup(struct swaybar *bar, bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_event_socketfd = ipc_open_socket(socket_path); - ipc_get_config(bar, bar_id); + ipc_initialize(bar, bar_id); assert(bar->display = wl_display_connect(NULL)); @@ -113,6 +114,7 @@ void bar_setup(struct swaybar *bar, if (coutput->index != output->index) { continue; } + output->name = strdup(coutput->name); assert(output->surface = wl_compositor_create_surface( bar->compositor)); output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( @@ -123,10 +125,13 @@ void bar_setup(struct swaybar *bar, &layer_surface_listener, output); zwlr_layer_surface_v1_set_anchor(output->layer_surface, bar->config->position); - render_frame(bar, output); break; } } + ipc_get_workspaces(bar); + wl_list_for_each(output, &bar->outputs, link) { + render_frame(bar, output); + } } static void display_in(int fd, short mask, void *_bar) { -- cgit v1.2.3 From 86ba0fc15d7615b09f0279616d538af5c23bc551 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 10:38:17 -0400 Subject: Re-render bar on IPC updates --- swaybar/bar.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 68dea408..90fd5ad4 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -143,11 +143,17 @@ static void display_in(int fd, short mask, void *_bar) { static void ipc_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; - handle_ipc_event(bar); + if (handle_ipc_event(bar)) { + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + render_frame(bar, output); + } + } } void bar_run(struct swaybar *bar) { add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); + add_event(bar->ipc_event_socketfd, POLLIN, ipc_in, bar); while (1) { event_loop_poll(); } -- cgit v1.2.3 From 0d0ab7c5ce148bce841fa0682d04bc7b6c21b902 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 15:16:12 -0400 Subject: Implement status line Does not yet support i3bar json protocol --- swaybar/bar.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 90fd5ad4..72c4be8f 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -13,6 +13,7 @@ #include "swaybar/render.h" #include "swaybar/config.h" #include "swaybar/event_loop.h" +#include "swaybar/status_line.h" #include "swaybar/bar.h" #include "swaybar/ipc.h" #include "ipc-client.h" @@ -98,6 +99,9 @@ void bar_setup(struct swaybar *bar, bar->ipc_socketfd = ipc_open_socket(socket_path); bar->ipc_event_socketfd = ipc_open_socket(socket_path); ipc_initialize(bar, bar_id); + if (bar->config->status_command) { + bar->status = status_line_init(bar->config->status_command); + } assert(bar->display = wl_display_connect(NULL)); @@ -134,6 +138,13 @@ void bar_setup(struct swaybar *bar, } } +static void render_all_frames(struct swaybar *bar) { + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + render_frame(bar, output); + } +} + static void display_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; if (wl_display_dispatch(bar->display) == -1) { @@ -144,16 +155,23 @@ static void display_in(int fd, short mask, void *_bar) { static void ipc_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; if (handle_ipc_event(bar)) { - struct swaybar_output *output; - wl_list_for_each(output, &bar->outputs, link) { - render_frame(bar, output); - } + render_all_frames(bar); + } +} + +static void status_in(int fd, short mask, void *_bar) { + struct swaybar *bar = (struct swaybar *)_bar; + if (handle_status_readable(bar->status)) { + render_all_frames(bar); } } void bar_run(struct swaybar *bar) { add_event(wl_display_get_fd(bar->display), POLLIN, display_in, bar); add_event(bar->ipc_event_socketfd, POLLIN, ipc_in, bar); + if (bar->status) { + add_event(bar->status->read_fd, POLLIN, status_in, bar); + } while (1) { event_loop_poll(); } -- cgit v1.2.3 From 0464a9910da2b99abea0ab202e179d66260a893b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 15:19:42 -0400 Subject: Clean up status line on exit --- swaybar/bar.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 72c4be8f..44f4ee31 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -191,4 +191,9 @@ void bar_teardown(struct swaybar *bar) { if (bar->config) { free_config(bar->config); } + close(bar->ipc_event_socketfd); + close(bar->ipc_socketfd); + if (bar->status) { + status_line_free(bar->status); + } } -- cgit v1.2.3 From da6e48520bad9718a7c4ddf0591474d54736c1c2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 15:36:52 -0400 Subject: Tear down bar when display exits --- swaybar/bar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 44f4ee31..afbce7cc 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -148,7 +148,8 @@ static void render_all_frames(struct swaybar *bar) { static void display_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; if (wl_display_dispatch(bar->display) == -1) { - wlr_log(L_ERROR, "failed to dispatch wl: %d", errno); + bar_teardown(bar); + exit(0); } } -- cgit v1.2.3 From 6fe66d0e6c9a20a9dbe2d464671ff19ea5b0387c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 22:25:25 -0400 Subject: Fix layer_surface_closed --- swaybar/bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index afbce7cc..82404d33 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -46,7 +46,7 @@ static void layer_surface_configure(void *data, static void layer_surface_closed(void *_output, struct zwlr_layer_surface_v1 *surface) { // TODO: Deal with hotplugging - struct swaybar_output *output = output; + struct swaybar_output *output = _output; zwlr_layer_surface_v1_destroy(output->layer_surface); wl_surface_destroy(output->surface); } -- cgit v1.2.3 From 095ac319214d6e51df223950292bfca5ddaf591a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 29 Mar 2018 22:32:17 -0400 Subject: Use render_all_frames from bar_setup --- swaybar/bar.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 82404d33..0fc41517 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -91,6 +91,13 @@ static const struct wl_registry_listener registry_listener = { .global_remove = handle_global_remove, }; +static void render_all_frames(struct swaybar *bar) { + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + render_frame(bar, output); + } +} + void bar_setup(struct swaybar *bar, const char *socket_path, const char *bar_id) { bar_init(bar); @@ -133,16 +140,7 @@ void bar_setup(struct swaybar *bar, } } ipc_get_workspaces(bar); - wl_list_for_each(output, &bar->outputs, link) { - render_frame(bar, output); - } -} - -static void render_all_frames(struct swaybar *bar) { - struct swaybar_output *output; - wl_list_for_each(output, &bar->outputs, link) { - render_frame(bar, output); - } + render_all_frames(bar); } static void display_in(int fd, short mask, void *_bar) { -- cgit v1.2.3 From 8d1425bde9e7f17a5a9e6bce73dffcf296dad6a1 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 21:38:28 -0400 Subject: Initialize seat pointer in swaybar --- swaybar/bar.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 0fc41517..e7b8b2ca 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -9,7 +9,13 @@ #include #include #include +#include #include +#ifdef __FreeBSD__ +#include +#else +#include +#endif #include "swaybar/render.h" #include "swaybar/config.h" #include "swaybar/event_loop.h" @@ -56,12 +62,102 @@ struct zwlr_layer_surface_v1_listener layer_surface_listener = { .closed = layer_surface_closed, }; +static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t surface_x, wl_fixed_t surface_y) { + struct swaybar *bar = data; + struct swaybar_pointer *pointer = &bar->pointer; + wl_surface_attach(pointer->cursor_surface, + wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); + wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, + pointer->cursor_image->hotspot_x, + pointer->cursor_image->hotspot_y); + wl_surface_commit(pointer->cursor_surface); +} + +static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, struct wl_surface *surface) { + // Who cares +} + +static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { + wlr_log(L_DEBUG, "motion"); + // TODO +} + +static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { + wlr_log(L_DEBUG, "button"); + // TODO +} + +static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) { + wlr_log(L_DEBUG, "axis"); + // TODO +} + +static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { + // Who cares +} + +static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, + uint32_t axis_source) { + // Who cares +} + +static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis) { + // Who cares +} + +static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, + uint32_t axis, int32_t discrete) { + // Who cares +} + +struct wl_pointer_listener pointer_listener = { + .enter = wl_pointer_enter, + .leave = wl_pointer_leave, + .motion = wl_pointer_motion, + .button = wl_pointer_button, + .axis = wl_pointer_axis, + .frame = wl_pointer_frame, + .axis_source = wl_pointer_axis_source, + .axis_stop = wl_pointer_axis_stop, + .axis_discrete = wl_pointer_axis_discrete, +}; + +static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, + enum wl_seat_capability caps) { + struct swaybar *bar = data; + if ((caps & WL_SEAT_CAPABILITY_POINTER)) { + bar->pointer.pointer = wl_seat_get_pointer(wl_seat); + wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar); + } +} + +static void seat_handle_name(void *data, struct wl_seat *wl_seat, + const char *name) { + // Who cares +} + +const struct wl_seat_listener seat_listener = { + .capabilities = seat_handle_capabilities, + .name = seat_handle_name, +}; + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct swaybar *bar = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { bar->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); + } else if (strcmp(interface, wl_seat_interface.name) == 0) { + bar->seat = wl_registry_bind(registry, name, + &wl_seat_interface, 1); + wl_seat_add_listener(bar->seat, &seat_listener, bar); } else if (strcmp(interface, wl_shm_interface.name) == 0) { bar->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); @@ -116,6 +212,15 @@ void bar_setup(struct swaybar *bar, wl_registry_add_listener(registry, ®istry_listener, bar); wl_display_roundtrip(bar->display); assert(bar->compositor && bar->layer_shell && bar->shm); + struct swaybar_pointer *pointer = &bar->pointer; + + assert(pointer->cursor_theme = wl_cursor_theme_load(NULL, 16, bar->shm)); + struct wl_cursor *cursor; + assert(cursor = wl_cursor_theme_get_cursor( + pointer->cursor_theme, "left_ptr")); + pointer->cursor_image = cursor->images[0]; + assert(pointer->cursor_surface = + wl_compositor_create_surface(bar->compositor)); // TODO: we might not necessarily be meant to do all of the outputs struct swaybar_output *output; -- cgit v1.2.3 From ae14dfc7ae70f16a31a10f4ff2395d4ac432308d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 22:02:55 -0400 Subject: Implement scroll wheel workspace switching --- swaybar/bar.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index e7b8b2ca..5679a892 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -24,6 +24,7 @@ #include "swaybar/ipc.h" #include "ipc-client.h" #include "list.h" +#include "log.h" #include "pango.h" #include "pool-buffer.h" #include "wlr-layer-shell-unstable-v1-client-protocol.h" @@ -67,6 +68,13 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, wl_fixed_t surface_x, wl_fixed_t surface_y) { struct swaybar *bar = data; struct swaybar_pointer *pointer = &bar->pointer; + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + if (output->surface == surface) { + pointer->current = output; + break; + } + } wl_surface_attach(pointer->cursor_surface, wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, @@ -77,12 +85,12 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface) { - // Who cares + struct swaybar *bar = data; + bar->pointer.current = NULL; } static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - wlr_log(L_DEBUG, "motion"); // TODO } @@ -94,8 +102,36 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { - wlr_log(L_DEBUG, "axis"); - // TODO + struct swaybar *bar = data; + struct swaybar_output *output = bar->pointer.current; + if (!output) { + return; + } + double amt = wl_fixed_to_double(value); + if (!bar->config->wrap_scroll) { + int i = 0; + struct swaybar_workspace *ws = NULL; + wl_list_for_each(ws, &output->workspaces, link) { + if (ws->focused) { + break; + } + ++i; + } + int len = wl_list_length(&output->workspaces); + if (!sway_assert(i != len, "axis with null workspace")) { + return; + } + if (i == 0 && amt > 0) { + return; // Do not wrap + } + if (i == len - 1 && amt < 0) { + return; // Do not wrap + } + } + + const char *workspace_name = + amt < 0 ? "prev_on_output" : "next_on_output"; + ipc_send_workspace_command(bar, workspace_name); } static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { -- cgit v1.2.3 From 2a5108a2786383cf5c3bcefd653605c916193837 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 22:42:59 -0400 Subject: Implement workspace switch on click --- swaybar/bar.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index 5679a892..f743236c 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -34,12 +34,6 @@ static void bar_init(struct swaybar *bar) { wl_list_init(&bar->outputs); } -struct swaybar_output *new_output(const char *name) { - struct swaybar_output *output = malloc(sizeof(struct swaybar_output)); - output->name = strdup(name); - return output; -} - static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { @@ -91,20 +85,39 @@ static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - // TODO + struct swaybar *bar = data; + bar->pointer.x = wl_fixed_to_int(surface_x); + bar->pointer.y = wl_fixed_to_int(surface_y); } static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - wlr_log(L_DEBUG, "button"); - // TODO + struct swaybar *bar = data; + struct swaybar_pointer *pointer = &bar->pointer; + struct swaybar_output *output = pointer->current; + if (!sway_assert(output, "button with no active output")) { + return; + } + if (state != WL_POINTER_BUTTON_STATE_PRESSED) { + return; + } + struct swaybar_hotspot *hotspot; + wl_list_for_each(hotspot, &output->hotspots, link) { + if (pointer->x >= hotspot->x + && pointer->y >= hotspot->y + && pointer->x < hotspot->x + hotspot->width + && pointer->y < hotspot->y + hotspot->height) { + hotspot->callback(output, pointer->x, pointer->y, + button, hotspot->data); + } + } } static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) { struct swaybar *bar = data; struct swaybar_output *output = bar->pointer.current; - if (!output) { + if (!sway_assert(output, "axis with no active output")) { return; } double amt = wl_fixed_to_double(value); @@ -206,6 +219,7 @@ static void handle_global(void *data, struct wl_registry *registry, &wl_output_interface, 1); output->index = index++; wl_list_init(&output->workspaces); + wl_list_init(&output->hotspots); wl_list_insert(&bar->outputs, &output->link); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { bar->layer_shell = wl_registry_bind( -- cgit v1.2.3 From 333dbcbe72b6af95573e374b66ad6ab63f274299 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 31 Mar 2018 14:39:18 -0400 Subject: Render i3bar blocks --- swaybar/bar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index f743236c..fb417095 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -308,14 +308,14 @@ static void display_in(int fd, short mask, void *_bar) { static void ipc_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; - if (handle_ipc_event(bar)) { + if (handle_ipc_readable(bar)) { render_all_frames(bar); } } static void status_in(int fd, short mask, void *_bar) { struct swaybar *bar = (struct swaybar *)_bar; - if (handle_status_readable(bar->status)) { + if (status_handle_readable(bar->status)) { render_all_frames(bar); } } -- cgit v1.2.3 From 260595076977729bcaf9aadcfbbc8c5f269c6387 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 3 Apr 2018 21:06:28 -0400 Subject: Add hidpi support to swaybar --- swaybar/bar.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 10 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index fb417095..cf812a60 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -69,11 +69,19 @@ static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, break; } } + int max_scale = 1; + struct swaybar_output *_output; + wl_list_for_each(_output, &bar->outputs, link) { + if (_output->scale > max_scale) { + max_scale = _output->scale; + } + } + wl_surface_set_buffer_scale(pointer->cursor_surface, max_scale); wl_surface_attach(pointer->cursor_surface, wl_cursor_image_get_buffer(pointer->cursor_image), 0, 0); wl_pointer_set_cursor(wl_pointer, serial, pointer->cursor_surface, - pointer->cursor_image->hotspot_x, - pointer->cursor_image->hotspot_y); + pointer->cursor_image->hotspot_x / max_scale, + pointer->cursor_image->hotspot_y / max_scale); wl_surface_commit(pointer->cursor_surface); } @@ -103,10 +111,12 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, } struct swaybar_hotspot *hotspot; wl_list_for_each(hotspot, &output->hotspots, link) { - if (pointer->x >= hotspot->x - && pointer->y >= hotspot->y - && pointer->x < hotspot->x + hotspot->width - && pointer->y < hotspot->y + hotspot->height) { + double x = pointer->x * output->scale; + double y = pointer->y * output->scale; + if (x >= hotspot->x + && y >= hotspot->y + && x < hotspot->x + hotspot->width + && y < hotspot->y + hotspot->height) { hotspot->callback(output, pointer->x, pointer->y, button, hotspot->data); } @@ -197,12 +207,43 @@ const struct wl_seat_listener seat_listener = { .name = seat_handle_name, }; +static void output_geometry(void *data, struct wl_output *output, int32_t x, + int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, + const char *make, const char *model, int32_t transform) { + // Who cares +} + +static void output_mode(void *data, struct wl_output *output, uint32_t flags, + int32_t width, int32_t height, int32_t refresh) { + // Who cares +} + +static void output_done(void *data, struct wl_output *output) { + // Who cares +} + +static void output_scale(void *data, struct wl_output *wl_output, + int32_t factor) { + struct swaybar_output *output = data; + output->scale = factor; + if (output->surface) { + render_frame(output->bar, output); + } +} + +struct wl_output_listener output_listener = { + .geometry = output_geometry, + .mode = output_mode, + .done = output_done, + .scale = output_scale, +}; + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct swaybar *bar = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { bar->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); + &wl_compositor_interface, 3); } else if (strcmp(interface, wl_seat_interface.name) == 0) { bar->seat = wl_registry_bind(registry, name, &wl_seat_interface, 1); @@ -216,7 +257,9 @@ static void handle_global(void *data, struct wl_registry *registry, calloc(1, sizeof(struct swaybar_output)); output->bar = bar; output->output = wl_registry_bind(registry, name, - &wl_output_interface, 1); + &wl_output_interface, 3); + wl_output_add_listener(output->output, &output_listener, output); + output->scale = 1; output->index = index++; wl_list_init(&output->workspaces); wl_list_init(&output->hotspots); @@ -262,9 +305,20 @@ void bar_setup(struct swaybar *bar, wl_registry_add_listener(registry, ®istry_listener, bar); wl_display_roundtrip(bar->display); assert(bar->compositor && bar->layer_shell && bar->shm); + wl_display_roundtrip(bar->display); + struct swaybar_pointer *pointer = &bar->pointer; - assert(pointer->cursor_theme = wl_cursor_theme_load(NULL, 16, bar->shm)); + int max_scale = 1; + struct swaybar_output *output; + wl_list_for_each(output, &bar->outputs, link) { + if (output->scale > max_scale) { + max_scale = output->scale; + } + } + + assert(pointer->cursor_theme = wl_cursor_theme_load( + NULL, 16 * (max_scale * 2), bar->shm)); struct wl_cursor *cursor; assert(cursor = wl_cursor_theme_get_cursor( pointer->cursor_theme, "left_ptr")); @@ -273,7 +327,6 @@ void bar_setup(struct swaybar *bar, wl_compositor_create_surface(bar->compositor)); // TODO: we might not necessarily be meant to do all of the outputs - struct swaybar_output *output; wl_list_for_each(output, &bar->outputs, link) { struct config_output *coutput; wl_list_for_each(coutput, &bar->config->outputs, link) { -- cgit v1.2.3 From d48e7036aa04f8503737de678519cc389058b259 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 3 Apr 2018 21:29:43 -0400 Subject: Don't use asserts with side-effects --- swaybar/bar.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index cf812a60..b617f9ab 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -299,7 +299,8 @@ void bar_setup(struct swaybar *bar, bar->status = status_line_init(bar->config->status_command); } - assert(bar->display = wl_display_connect(NULL)); + bar->display = wl_display_connect(NULL); + assert(bar->display); struct wl_registry *registry = wl_display_get_registry(bar->display); wl_registry_add_listener(registry, ®istry_listener, bar); @@ -317,14 +318,15 @@ void bar_setup(struct swaybar *bar, } } - assert(pointer->cursor_theme = wl_cursor_theme_load( - NULL, 16 * (max_scale * 2), bar->shm)); + pointer->cursor_theme = wl_cursor_theme_load( + NULL, 16 * (max_scale * 2), bar->shm); + assert(pointer->cursor_theme); struct wl_cursor *cursor; - assert(cursor = wl_cursor_theme_get_cursor( - pointer->cursor_theme, "left_ptr")); + cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); + assert(cursor); pointer->cursor_image = cursor->images[0]; - assert(pointer->cursor_surface = - wl_compositor_create_surface(bar->compositor)); + pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); + assert(pointer->cursor_surface); // TODO: we might not necessarily be meant to do all of the outputs wl_list_for_each(output, &bar->outputs, link) { @@ -334,8 +336,8 @@ void bar_setup(struct swaybar *bar, continue; } output->name = strdup(coutput->name); - assert(output->surface = wl_compositor_create_surface( - bar->compositor)); + output->surface = wl_compositor_create_surface(bar->compositor); + assert(output->surface); output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( bar->layer_shell, output->surface, output->output, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); -- cgit v1.2.3 From 38bdd4bdebc4938f25af90bc4f79e278f61808e0 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 3 Apr 2018 22:52:40 -0400 Subject: Address review feedback --- swaybar/bar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index b617f9ab..ea0141cc 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -319,7 +319,7 @@ void bar_setup(struct swaybar *bar, } pointer->cursor_theme = wl_cursor_theme_load( - NULL, 16 * (max_scale * 2), bar->shm); + NULL, 24 * max_scale, bar->shm); assert(pointer->cursor_theme); struct wl_cursor *cursor; cursor = wl_cursor_theme_get_cursor(pointer->cursor_theme, "left_ptr"); -- cgit v1.2.3 From f242362e7e521a8f35f47572038a20d404d25327 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 5 Apr 2018 15:39:57 -0400 Subject: Handle output removal on swaybar --- swaybar/bar.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index ea0141cc..f1a701b9 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -34,6 +34,34 @@ static void bar_init(struct swaybar *bar) { wl_list_init(&bar->outputs); } +static void swaybar_output_free(struct swaybar_output *output) { + if (!output) { + return; + } + wlr_log(L_DEBUG, "Removing output %s", output->name); + zwlr_layer_surface_v1_destroy(output->layer_surface); + wl_surface_destroy(output->surface); + wl_output_destroy(output->output); + destroy_buffer(&output->buffers[0]); + destroy_buffer(&output->buffers[1]); + struct swaybar_workspace *ws, *ws_tmp; + wl_list_for_each_safe(ws, ws_tmp, &output->workspaces, link) { + wl_list_remove(&ws->link); + free(ws->name); + free(ws); + } + struct swaybar_hotspot *hotspot, *hotspot_tmp; + wl_list_for_each_safe(hotspot, hotspot_tmp, &output->hotspots, link) { + if (hotspot->destroy) { + hotspot->destroy(hotspot->data); + } + free(hotspot); + } + wl_list_remove(&output->link); + free(output->name); + free(output); +} + static void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height) { @@ -46,10 +74,8 @@ static void layer_surface_configure(void *data, static void layer_surface_closed(void *_output, struct zwlr_layer_surface_v1 *surface) { - // TODO: Deal with hotplugging struct swaybar_output *output = _output; - zwlr_layer_surface_v1_destroy(output->layer_surface); - wl_surface_destroy(output->surface); + swaybar_output_free(output); } struct zwlr_layer_surface_v1_listener layer_surface_listener = { @@ -261,6 +287,7 @@ static void handle_global(void *data, struct wl_registry *registry, wl_output_add_listener(output->output, &output_listener, output); output->scale = 1; output->index = index++; + output->wl_name = name; wl_list_init(&output->workspaces); wl_list_init(&output->hotspots); wl_list_insert(&bar->outputs, &output->link); @@ -272,7 +299,14 @@ static void handle_global(void *data, struct wl_registry *registry, static void handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { - // who cares + struct swaybar *bar = data; + struct swaybar_output *output, *tmp; + wl_list_for_each_safe(output, tmp, &bar->outputs, link) { + if (output->wl_name == name) { + swaybar_output_free(output); + break; + } + } } static const struct wl_registry_listener registry_listener = { -- cgit v1.2.3 From c38de1672255e9906623c133598ac7fded10640a Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Tue, 10 Apr 2018 13:38:15 +1000 Subject: Fix swaybar output config. --- swaybar/bar.c | 70 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 28 deletions(-) (limited to 'swaybar/bar.c') diff --git a/swaybar/bar.c b/swaybar/bar.c index f1a701b9..d51c4ec7 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -264,6 +264,19 @@ struct wl_output_listener output_listener = { .scale = output_scale, }; +static bool bar_uses_output(struct swaybar *bar, size_t output_index) { + if (bar->config->all_outputs) { + return true; + } + struct config_output *coutput; + wl_list_for_each(coutput, &bar->config->outputs, link) { + if (coutput->index == output_index) { + return true; + } + } + return false; +} + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct swaybar *bar = data; @@ -278,19 +291,22 @@ static void handle_global(void *data, struct wl_registry *registry, bar->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); } else if (strcmp(interface, wl_output_interface.name) == 0) { - static size_t index = 0; - struct swaybar_output *output = - calloc(1, sizeof(struct swaybar_output)); - output->bar = bar; - output->output = wl_registry_bind(registry, name, - &wl_output_interface, 3); - wl_output_add_listener(output->output, &output_listener, output); - output->scale = 1; - output->index = index++; - output->wl_name = name; - wl_list_init(&output->workspaces); - wl_list_init(&output->hotspots); - wl_list_insert(&bar->outputs, &output->link); + static size_t output_index = 0; + if (bar_uses_output(bar, output_index)) { + struct swaybar_output *output = + calloc(1, sizeof(struct swaybar_output)); + output->bar = bar; + output->output = wl_registry_bind(registry, name, + &wl_output_interface, 3); + wl_output_add_listener(output->output, &output_listener, output); + output->scale = 1; + output->index = output_index; + output->wl_name = name; + wl_list_init(&output->workspaces); + wl_list_init(&output->hotspots); + wl_list_insert(&bar->outputs, &output->link); + } + ++output_index; } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { bar->layer_shell = wl_registry_bind( registry, name, &zwlr_layer_shell_v1_interface, 1); @@ -362,26 +378,24 @@ void bar_setup(struct swaybar *bar, pointer->cursor_surface = wl_compositor_create_surface(bar->compositor); assert(pointer->cursor_surface); - // TODO: we might not necessarily be meant to do all of the outputs wl_list_for_each(output, &bar->outputs, link) { struct config_output *coutput; wl_list_for_each(coutput, &bar->config->outputs, link) { - if (coutput->index != output->index) { - continue; + if (coutput->index == output->index) { + output->name = strdup(coutput->name); + break; } - output->name = strdup(coutput->name); - output->surface = wl_compositor_create_surface(bar->compositor); - assert(output->surface); - output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( - bar->layer_shell, output->surface, output->output, - ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); - assert(output->layer_surface); - zwlr_layer_surface_v1_add_listener(output->layer_surface, - &layer_surface_listener, output); - zwlr_layer_surface_v1_set_anchor(output->layer_surface, - bar->config->position); - break; } + output->surface = wl_compositor_create_surface(bar->compositor); + assert(output->surface); + output->layer_surface = zwlr_layer_shell_v1_get_layer_surface( + bar->layer_shell, output->surface, output->output, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, "panel"); + assert(output->layer_surface); + zwlr_layer_surface_v1_add_listener(output->layer_surface, + &layer_surface_listener, output); + zwlr_layer_surface_v1_set_anchor(output->layer_surface, + bar->config->position); } ipc_get_workspaces(bar); render_all_frames(bar); -- cgit v1.2.3