From e277d4e094a8294f9541048c0a4a6d0cf9c3f0bc Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sun, 13 Dec 2015 16:04:54 -0500 Subject: [PATCH] Subscribe to workspace change events and redraw --- common/ipc-client.c | 31 ++++++---- include/ipc-client.h | 5 ++ swaybar/main.c | 142 ++++++++++++++++++++++++------------------- 3 files changed, 104 insertions(+), 74 deletions(-) diff --git a/common/ipc-client.c b/common/ipc-client.c index 5d2d5808..e92a09fe 100644 --- a/common/ipc-client.c +++ b/common/ipc-client.c @@ -39,20 +39,9 @@ int ipc_open_socket(const char *socket_path) { return socketfd; } -char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) { +char *ipc_recv_response(int socketfd, uint32_t *len) { char data[ipc_header_size]; uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); - memcpy(data, ipc_magic, sizeof(ipc_magic)); - data32[0] = *len; - data32[1] = type; - - if (write(socketfd, data, ipc_header_size) == -1) { - sway_abort("Unable to send IPC header"); - } - - if (write(socketfd, payload, *len) == -1) { - sway_abort("Unable to send IPC payload"); - } size_t total = 0; while (total < ipc_header_size) { @@ -77,3 +66,21 @@ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint3 return response; } + +char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len) { + char data[ipc_header_size]; + uint32_t *data32 = (uint32_t *)(data + sizeof(ipc_magic)); + memcpy(data, ipc_magic, sizeof(ipc_magic)); + data32[0] = *len; + data32[1] = type; + + if (write(socketfd, data, ipc_header_size) == -1) { + sway_abort("Unable to send IPC header"); + } + + if (write(socketfd, payload, *len) == -1) { + sway_abort("Unable to send IPC payload"); + } + + return ipc_recv_response(socketfd, len); +} diff --git a/include/ipc-client.h b/include/ipc-client.h index e6c988c2..a4cfd87f 100644 --- a/include/ipc-client.h +++ b/include/ipc-client.h @@ -16,5 +16,10 @@ int ipc_open_socket(const char *socket_path); * the length of the buffer returned from sway. */ char *ipc_single_command(int socketfd, uint32_t type, const char *payload, uint32_t *len); +/** + * Receives a single IPC resposne and returns the buffer. len will be updated + * with the length of the buffer returned from sway. + */ +char *ipc_recv_response(int socketfd, uint32_t *len); #endif diff --git a/swaybar/main.c b/swaybar/main.c index c7c4ed47..56c69aff 100644 --- a/swaybar/main.c +++ b/swaybar/main.c @@ -3,7 +3,11 @@ #include #include #include +#include #include +#include +#include +#include #include "ipc-client.h" #include "readline.h" #include "client/registry.h" @@ -93,68 +97,6 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { (color & 0xFF) / 256.0); } -void update() { - if (!feof(command)) { - free(line); - line = read_line(command); - int l = strlen(line) - 1; - if (line[l] == '\n') { - line[l] = '\0'; - } - } -} - -void render() { - // Clear - cairo_save(window->cairo); - cairo_set_operator(window->cairo, CAIRO_OPERATOR_CLEAR); - cairo_paint(window->cairo); - cairo_restore(window->cairo); - - // Background - cairo_set_source_u32(window->cairo, colors.background); - cairo_paint(window->cairo); - - // Command output - cairo_set_source_u32(window->cairo, colors.statusline); - int width, height; - get_text_size(window, &width, &height, "%s", line); - - cairo_move_to(window->cairo, window->width - MARGIN - width, MARGIN); - pango_printf(window, "%s", line); - - // Workspaces - int x = 0; - int i; - for (i = 0; i < workspaces->length; ++i) { - struct workspace *ws = workspaces->items[i]; - get_text_size(window, &width, &height, "%s", ws->name); - struct box_colors box_colors; - if (ws->urgent) { - box_colors = colors.urgent_workspace; - } else if (ws->focused) { - box_colors = colors.focused_workspace; - } else if (ws->visible) { - box_colors = colors.active_workspace; - } else { - box_colors = colors.inactive_workspace; - } - cairo_set_source_u32(window->cairo, box_colors.background); - cairo_rectangle(window->cairo, x, 0, width + MARGIN * 2, window->height); - cairo_fill(window->cairo); - - cairo_set_source_u32(window->cairo, box_colors.border); - cairo_rectangle(window->cairo, x, 0, width + MARGIN * 2, window->height); - cairo_stroke(window->cairo); - - cairo_set_source_u32(window->cairo, box_colors.text); - cairo_move_to(window->cairo, x + MARGIN, MARGIN); - pango_printf(window, "%s", ws->name); - - x += width + MARGIN * 2 + MARGIN; - } -} - void ipc_update_workspaces() { if (workspaces) { free_flat_list(workspaces); @@ -212,9 +154,85 @@ void bar_ipc_init(int outputi) { json_object_put(outputs); sway_log(L_INFO, "Running on output %s", output); + const char *subscribe_json = "[ \"workspace\" ]"; + len = strlen(subscribe_json); + res = ipc_single_command(socketfd, IPC_SUBSCRIBE, subscribe_json, &len); + sway_log(L_INFO, "%s", res); + ipc_update_workspaces(); } +void update() { + int pending; + if (ioctl(fileno(command), FIONREAD, &pending) != -1 && pending > 0) { + free(line); + line = read_line(command); + int l = strlen(line) - 1; + if (line[l] == '\n') { + line[l] = '\0'; + } + } + if (ioctl(socketfd, FIONREAD, &pending) != -1 && pending > 0) { + sway_log(L_INFO, "data available"); + uint32_t len; + char *buf = ipc_recv_response(socketfd, &len); + sway_log(L_INFO, "%s", buf); + free(buf); + ipc_update_workspaces(); + } +} + +void render() { + // Clear + cairo_save(window->cairo); + cairo_set_operator(window->cairo, CAIRO_OPERATOR_CLEAR); + cairo_paint(window->cairo); + cairo_restore(window->cairo); + + // Background + cairo_set_source_u32(window->cairo, colors.background); + cairo_paint(window->cairo); + + // Command output + cairo_set_source_u32(window->cairo, colors.statusline); + int width, height; + get_text_size(window, &width, &height, "%s", line); + + cairo_move_to(window->cairo, window->width - MARGIN - width, MARGIN); + pango_printf(window, "%s", line); + + // Workspaces + int x = 0; + int i; + for (i = 0; i < workspaces->length; ++i) { + struct workspace *ws = workspaces->items[i]; + get_text_size(window, &width, &height, "%s", ws->name); + struct box_colors box_colors; + if (ws->urgent) { + box_colors = colors.urgent_workspace; + } else if (ws->focused) { + box_colors = colors.focused_workspace; + } else if (ws->visible) { + box_colors = colors.active_workspace; + } else { + box_colors = colors.inactive_workspace; + } + cairo_set_source_u32(window->cairo, box_colors.background); + cairo_rectangle(window->cairo, x, 0, width + MARGIN * 2, window->height); + cairo_fill(window->cairo); + + cairo_set_source_u32(window->cairo, box_colors.border); + cairo_rectangle(window->cairo, x, 0, width + MARGIN * 2, window->height); + cairo_stroke(window->cairo); + + cairo_set_source_u32(window->cairo, box_colors.text); + cairo_move_to(window->cairo, x + MARGIN, MARGIN); + pango_printf(window, "%s", ws->name); + + x += width + MARGIN * 2 + MARGIN; + } +} + int main(int argc, char **argv) { init_log(L_INFO); registry = registry_poll();