From f96c847cf7666f3556210589892354461c87a67a Mon Sep 17 00:00:00 2001 From: lkn Date: Tue, 23 Jun 2026 20:50:52 +0200 Subject: [PATCH] workspace name: match original bold shadow text rendering Draw white text at 5x5 offsets to build a shape mask (like the original XShape-based approach), then draw centered text at (2,2) and apply the mask as alpha. This gives the same outlined text appearance as the X11 version. --- src/backend/wayland/wl_badge.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/backend/wayland/wl_badge.c b/src/backend/wayland/wl_badge.c index ee73877..d7e31ae 100644 --- a/src/backend/wayland/wl_badge.c +++ b/src/backend/wayland/wl_badge.c @@ -38,15 +38,34 @@ wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win, W_RegisterBacking(fb->id, fb->image); } - /* Fill transparent */ + /* Build shape mask: draw white text at 5x5 offsets on black. + * Any pixel that becomes non-black is part of the text outline. */ uint32_t *px = pixman_image_get_data(fb->image); - for (int i = 0; i < width * height; i++) - px[i] = 0x00000000; + int npx = width * height; + for (int i = 0; i < npx; i++) + px[i] = 0xFF000000; - /* Draw white text */ + for (int x = 0; x <= 4; x++) + for (int y = 0; y <= 4; y++) + WMDrawString(scr->wmscreen, (WMDrawable)badge_win, scr->white, + scr->workspace_name_font, x, y, name, name_len); + + /* Save mask: pixels with any white component are visible */ + uint8_t *mask = wmalloc(npx); + for (int i = 0; i < npx; i++) + mask[i] = (px[i] & 0x00FFFFFF) ? 0xFF : 0x00; + + /* Draw final text: white on black at center (2,2) */ + for (int i = 0; i < npx; i++) + px[i] = 0xFF000000; WMDrawString(scr->wmscreen, (WMDrawable)badge_win, scr->white, scr->workspace_name_font, 2, 2, name, name_len); + /* Apply mask as alpha channel */ + for (int i = 0; i < npx; i++) + px[i] = (px[i] & 0x00FFFFFF) | ((uint32_t)mask[i] << 24); + wfree(mask); + /* Update scene buffer */ if (fb->scene_buf) wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);