Something went wrong. Try again.
extremely opinionated bar. you don't want to use this
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195#include "bar/config.h"#include "bar/modules.h"#include "bar/util.h"
#include <ctype.h>#include <stdlib.h>#include <string.h>
typedef struct { redraw_fn_t redraw; void *redraw_data; const char *compositor_name;
char *class; char *title; char workspace[16]; bool has_window;} window_state_t;
static const char *remap_class(const char *cls){ if (!cls) return "unknown"; if (!strcmp(cls, "footclient") || !strcmp(cls, "foot")) return "terminal";
if (strchr(cls, ' ') != nullptr) return cls;
const char *last_dot = strrchr(cls, '.'); return (last_dot != nullptr) ? (last_dot + 1) : cls;}
static void clean_discord(const char *in, char *out, size_t max){ const char *p = in; if (*p == '(') { while (*p && *p != ')') p++; if (*p) p++; while (*p == ' ') p++; }
constexpr char sep[] = "Discord | "; if (!strncmp(p, sep, sizeof sep - 1)) p += sizeof sep - 1;
strncpy(out, p, max - 1); out[max - 1] = '\0';}
static void rebuild_ws_label(char *buffer, size_t buffer_size, const workspace_info_t *workspaces, size_t count){ if (!buffer || buffer_size == 0) return;
for (size_t i = 0; i < count; i++) { if (workspaces[i].flags & WS_FOCUSED) { if (workspaces[i].name && workspaces[i].name[0] != '\0') snprintf(buffer, buffer_size, "Workspace %s", workspaces[i].name); else snprintf(buffer, buffer_size, "Workspace %d", workspaces[i].index); return; } } snprintf(buffer, buffer_size, "Workspace ?");}
static void on_focus(const focus_info_t *info, void *data){ module_t *mod = data; window_state_t *w = mod->internal;
w->has_window = info->has_window;
if (!w->has_window) { assign_str(&w->class, ""); assign_str(&w->title, ""); w->redraw(w->redraw_data); return; }
char tmp_class[128]; const char *cls = remap_class(info->class); strncpy(tmp_class, cls, sizeof tmp_class - 1); tmp_class[sizeof tmp_class - 1] = '\0'; for (int i = 0; tmp_class[i]; i++) { tmp_class[i] = tolower((unsigned char)tmp_class[i]); }
char clean_class[128]; sanitise_and_truncate(clean_class, tmp_class, sizeof clean_class); assign_str(&w->class, clean_class);
char tmp_title[128]; bool discord = !strcmp(w->class, "discord") || !strcmp(w->class, "vesktop"); if (discord) { clean_discord(info->title ? info->title : "", tmp_title, sizeof tmp_title); } else { strncpy(tmp_title, info->title ? info->title : "", sizeof tmp_title - 1); tmp_title[sizeof tmp_title - 1] = '\0'; }
char clean_title[128]; sanitise_and_truncate(clean_title, tmp_title, g_config.max_title_length); assign_str(&w->title, clean_title);
w->redraw(w->redraw_data);}
static void on_workspaces(const workspace_info_t *wss, size_t count, void *data){ module_t *mod = data; window_state_t *w = mod->internal;
size_t n = count < MAX_WORKSPACES ? count : MAX_WORKSPACES; rebuild_ws_label(w->workspace, sizeof w->workspace, wss, n);
if (!w->has_window) w->redraw(w->redraw_data);}
static size_t window_render(module_t *mod, segment_t *out){ window_state_t *w = mod->internal;
*out = (segment_t){.is_multi_line = true, .top_fg = CLR_MUTED, .bottom_fg = CLR_FG, .bg = CLR_BG};
if (w->has_window) { out->top = w->class; out->bottom = w->title; } else { out->top = w->compositor_name; out->bottom = w->workspace; }
return 1;}
static void window_destroy(module_t *mod){ window_state_t *w = mod->internal;
if (w->class) free(w->class); if (w->title) free(w->title); free(w); free(mod);}
module_t *window_module_new(protocol_t *proto, redraw_fn_t fn, void *data){ if (!proto) { warn("no protocol provided for window module"); return nullptr; }
module_t *mod = malloc(sizeof *mod); window_state_t *w = calloc(1, sizeof *w);
if (!mod || !w) { if (mod) free(mod); if (w) free(w); return nullptr; }
w->redraw = fn; w->redraw_data = data; w->compositor_name = proto ? proto->name : "wayland"; strncpy(w->workspace, "Workspace ?", sizeof w->workspace - 1);
*mod = (module_t){ .render = window_render, .destroy = window_destroy, .internal = w};
if (proto->on_focus_changed) proto->on_focus_changed(proto, on_focus, mod); if (proto->on_workspaces_changed) proto->on_workspaces_changed(proto, on_workspaces, mod);
return mod;}