docs: expand README with design philosophy, features, and architecture sections while adding panel dirty tracking, Xft color caching, and XInput2 mouse distance monitoring

This commit is contained in:
2026-01-27 01:50:47 +00:00
parent 2f096a55ac
commit a0d5b1b091
18 changed files with 1216 additions and 336 deletions
+83 -36
View File
@@ -19,6 +19,83 @@
#define RESIZE_EDGE 8
#define DEC_XFT_COLOR_CACHE_SIZE 8
typedef struct {
unsigned long pixel;
XftColor xft_color;
bool valid;
int lru_counter;
} DecCachedXftColor;
static DecCachedXftColor dec_xft_color_cache[DEC_XFT_COLOR_CACHE_SIZE];
static Visual *dec_cached_visual = NULL;
static int dec_xft_color_lru_counter = 0;
static XftDraw *dec_cached_xft_draw = NULL;
static Window dec_cached_window = None;
static XftDraw *dec_get_xft_draw(Window w)
{
if (dec_cached_window == w && dec_cached_xft_draw != NULL) {
return dec_cached_xft_draw;
}
if (dec_cached_xft_draw != NULL) {
XftDrawDestroy(dec_cached_xft_draw);
}
if (dec_cached_visual == NULL) {
dec_cached_visual = DefaultVisual(dwn->display, dwn->screen);
}
dec_cached_xft_draw = XftDrawCreate(dwn->display, w, dec_cached_visual, dwn->colormap);
dec_cached_window = w;
return dec_cached_xft_draw;
}
static XftColor *dec_get_cached_xft_color(unsigned long color)
{
if (dec_cached_visual == NULL) {
dec_cached_visual = DefaultVisual(dwn->display, dwn->screen);
}
for (int i = 0; i < DEC_XFT_COLOR_CACHE_SIZE; i++) {
if (dec_xft_color_cache[i].valid && dec_xft_color_cache[i].pixel == color) {
dec_xft_color_cache[i].lru_counter = ++dec_xft_color_lru_counter;
return &dec_xft_color_cache[i].xft_color;
}
}
int oldest_idx = 0;
int oldest_lru = dec_xft_color_cache[0].lru_counter;
for (int i = 1; i < DEC_XFT_COLOR_CACHE_SIZE; i++) {
if (!dec_xft_color_cache[i].valid) {
oldest_idx = i;
break;
}
if (dec_xft_color_cache[i].lru_counter < oldest_lru) {
oldest_lru = dec_xft_color_cache[i].lru_counter;
oldest_idx = i;
}
}
if (dec_xft_color_cache[oldest_idx].valid) {
XftColorFree(dwn->display, dec_cached_visual, dwn->colormap,
&dec_xft_color_cache[oldest_idx].xft_color);
}
XRenderColor render_color;
render_color.red = ((color >> 16) & 0xFF) * 257;
render_color.green = ((color >> 8) & 0xFF) * 257;
render_color.blue = (color & 0xFF) * 257;
render_color.alpha = 0xFFFF;
XftColorAllocValue(dwn->display, dec_cached_visual, dwn->colormap,
&render_color, &dec_xft_color_cache[oldest_idx].xft_color);
dec_xft_color_cache[oldest_idx].pixel = color;
dec_xft_color_cache[oldest_idx].valid = true;
dec_xft_color_cache[oldest_idx].lru_counter = ++dec_xft_color_lru_counter;
return &dec_xft_color_cache[oldest_idx].xft_color;
}
void decorations_init(void)
{
@@ -117,27 +194,12 @@ void decorations_render_title_bar(Client *client, bool focused)
strncat(display_title, "...", sizeof(display_title) - strlen(display_title) - 1);
}
XftDraw *xft_draw = XftDrawCreate(dpy, client->frame,
DefaultVisual(dpy, dwn->screen),
dwn->colormap);
XftDraw *xft_draw = dec_get_xft_draw(client->frame);
if (xft_draw != NULL) {
XftColor xft_color;
XRenderColor render_color;
render_color.red = ((fg_color >> 16) & 0xFF) * 257;
render_color.green = ((fg_color >> 8) & 0xFF) * 257;
render_color.blue = (fg_color & 0xFF) * 257;
render_color.alpha = 0xFFFF;
XftColorAllocValue(dpy, DefaultVisual(dpy, dwn->screen),
dwn->colormap, &render_color, &xft_color);
XftDrawStringUtf8(xft_draw, &xft_color, title_font,
XftColor *xft_color = dec_get_cached_xft_color(fg_color);
XftDrawStringUtf8(xft_draw, xft_color, title_font,
text_x, text_y,
(const FcChar8 *)display_title, strlen(display_title));
XftColorFree(dpy, DefaultVisual(dpy, dwn->screen),
dwn->colormap, &xft_color);
XftDrawDestroy(xft_draw);
}
}
}
@@ -334,26 +396,11 @@ void decorations_draw_text(Window window, GC gc, int x, int y,
}
if (dwn->xft_font != NULL) {
XftDraw *xft_draw = XftDrawCreate(dwn->display, window,
DefaultVisual(dwn->display, dwn->screen),
dwn->colormap);
XftDraw *xft_draw = dec_get_xft_draw(window);
if (xft_draw != NULL) {
XftColor xft_color;
XRenderColor render_color;
render_color.red = ((color >> 16) & 0xFF) * 257;
render_color.green = ((color >> 8) & 0xFF) * 257;
render_color.blue = (color & 0xFF) * 257;
render_color.alpha = 0xFFFF;
XftColorAllocValue(dwn->display, DefaultVisual(dwn->display, dwn->screen),
dwn->colormap, &render_color, &xft_color);
XftDrawStringUtf8(xft_draw, &xft_color, dwn->xft_font,
XftColor *xft_color = dec_get_cached_xft_color(color);
XftDrawStringUtf8(xft_draw, xft_color, dwn->xft_font,
x, y, (const FcChar8 *)text, strlen(text));
XftColorFree(dwn->display, DefaultVisual(dwn->display, dwn->screen),
dwn->colormap, &xft_color);
XftDrawDestroy(xft_draw);
return;
}
}