#include "bar/modules.h" #include "bar/protocol.h" #include "bar/util.h" #include "bar/config.h" #include #include #include #include typedef struct { redraw_fn_t redraw; void *redraw_data; struct fcft_font *font; workspace_info_t workspaces[MAX_WORKSPACES]; int workspace_count; } workspaces_state_t; static size_t workspaces_render(module_t *mod, segment_t *out) { workspaces_state_t *s = mod->internal; int count = s->workspace_count; if (g_config.persistent_workspaces > count) count = g_config.persistent_workspaces; if (count > MAX_WORKSPACES) count = MAX_WORKSPACES; for (int idx = 0; idx < count; idx++) { out[idx] = (segment_t){ .font = s->font, .text = g_config.ws_icons[idx][0] ? g_config.ws_icons[idx] : "?", .fg = CLR_GREY, .bg = CLR_BG, .connect_prev = idx != 0, .connect_next = idx != count - 1, }; } for (int i = 0; i < s->workspace_count; i++) { workspace_info_t ws = s->workspaces[i]; int idx = ws.index - 1; if (idx >= 0 && idx < count) { if (ws.flags & (WS_FOCUSED | WS_VISIBLE)) out[idx].fg = CLR_BLUE; else out[idx].fg = CLR_FG; } } return count; } static void workspaces_destroy(module_t *mod) { workspaces_state_t *s = mod->internal; if (s->font) fcft_destroy(s->font); free(s); free(mod); } static void on_workspaces(const workspace_info_t *wss, size_t count, void *data) { workspaces_state_t *w = data; for (int i = 0; i < w->workspace_count; i++) { if (w->workspaces[i].name) free(w->workspaces[i].name); } w->workspace_count = count < MAX_WORKSPACES ? count : MAX_WORKSPACES; for (int i = 0; i < w->workspace_count; i++) { w->workspaces[i] = wss[i]; if (wss[i].name) w->workspaces[i].name = strdup(wss[i].name); } dbg("workspace count: %zu", n); w->redraw(w->redraw_data); } module_t *workspaces_module_new(protocol_t *proto, redraw_fn_t fn, void *data) { if (!proto) { return warn("no protocol provided for window module"), nullptr; } workspaces_state_t *state = calloc(1, sizeof *state); if (!state) return nullptr; state->redraw = fn; state->redraw_data = data; const char *font[] = {g_config.font_workspace, "monospace:size=17:weight=bold", nullptr}; state->font = fcft_from_name(1, font, nullptr); module_t *mod = malloc(sizeof *mod); if (!mod) { fcft_destroy(state->font); free(state); return nullptr; } *mod = (module_t){.render = workspaces_render, .destroy = workspaces_destroy, .internal = state}; if (proto->on_workspaces_changed) proto->on_workspaces_changed(proto, on_workspaces, state); return mod; }