2026-10-24 — kitty shaders, kernel 7.3.0, tblockd repair, Razer LED dead end, Hal overlay¶
Highlights¶
- Kitty 0.49 custom shaders explored end to end; wrote a background-only
water-bgshader, then reverted because the motion was distracting — files kept. - CachyOS upgrade: 55 repo + 4 AUR packages, kernel
7.2.11→7.3.0. Removed the only DKMS module (openrazer) first, so it upgraded like a normal system. - tblockd repaired after breaking on 2026-10-16: python 3.13→3.14 orphan, Codeberg checksum drift, group membership and a stale pidfile. Protection active again (3.5 M rules).
- Razer DeathAdder Essential LED saga ends in the spec sheet: single-colour green, so colour control is impossible. OpenRazer and OpenRGB removed again.
- Repo reviews:
koala73/worldmonitor(impressive scaffolding, bus factor 1) andPLAYER99-void/void(voice companion for Claude Code). - Built
~/Projects/hal-overlay: a keyboard-only top-centre notch that drivesopencode; verified end to end with OCR.
Full log¶
2026-10-24 — Session Log (raw)¶
Long mixed session: kitty shaders → JPEG XL → CachyOS upgrade → tblockd repair → Razer LED dead end → repo reviews → built a Hal overlay.
Kitty custom shaders (0.49.2)¶
- kitty 0.49 added
custom_shaders(slang, singleendslot). Shipped set lives in/usr/lib/kitty/kitty/shaders/custom/— backgrounds (inside-the-matrix,northern-lights,fireworks,fireworks-rockets,water,underwater), mouse (pond-ripple,spotlight), cursor trails (cursor-trail-default/-blaze/-lightning/-motion-blur), navigation (dim-inactive-windows,focus-highlight,tab-change), retro (crt,crt-blue,tft), composable fragments (negative,bloom,sample). - Enabled
custom_shaders waterwith a dated backup (kitty.conf.bak-2026-10-22-water). - Verdict: too distracting / hurts legibility. Causes:
UV_DISPLACEMENT 0.04resamples and smears glyphs,WATER_COLOR 0.5× 1.2 washes the whole screen toward grey. Unlikeunderwater/fireworksit has no luminance gate. - Wrote a replacement
~/.config/kitty/shaders/water-bg.{slang,pipeline}: same caustic math, no UV warp, additive ripples gated by luminance (BLACK_BLEND_THRESHOLD 0.35+ softness) so text is untouched; animation gated onos-window-focus-in|user-activity. Compiled through kitty's own builder (parse_pipeline+build_custom_shader_pipeline_glsl, slangc-warnings-as-errors all) → OK, 3216 B vert / 8332 B frag. - Shader reload semantics (important):
varoverrides only work on uncommented lines and must match the shader'sstatic constname+type exactly (a typo fails silently). kitty watches config files, notshaders/, andrecompile_if_needed()only rebuilds when thecustom_shadersoption changes or the force flag is armed (armed after the check byload_config_file) — so a restart is the reliable reload, or touch kitty.conf twice. - Reverted to the backup; kept the shader files +
kitty.conf.shaders-water-bgfor later.
JPEG XL¶
- Their
~/Pictures/wall/3000.jxl(1020×510, lossy, 8-bit sRGB, 43 KB) — native JXL, not a JPEG rewrap. Tooling present:magick(libjxl 0.12.0 rw),djxl/cjxl/jxlinfo,ffmpeg/mpv(libjxl decoders). No gdk-pixbuf JXL loader →eogcan't open it;loupe/glycin likely can. magick 3000.jxl → pngtook 0.26 s (43 KB → 544 KB). Noctalia handles JXL for wallpaper, so no conversion needed.
CachyOS upgrade¶
checkupdates(fresh sync) → 55 repo + 4 AUR; local DBs were 2 days stale.- Notable: kernel
7.2.11→7.3.0,linux-firmware*20260916→20261019, mesa 26.2.4→26.2.5, pipewire 1.6.9→1.6.10, mutter 51.1, nss/ca-certificates,cachyos-hooksbig jump, opencode 2.1.3, yt-dlp. AUR: google-chrome 156, vscode-bin 1.143.1, pyprland, hyprwhspr. - Only DKMS module on the box was
openrazer-driver/3.12.4 (7.2.11)— the one thing a kernel bump could break. Removed the whole openrazer stack (openrazer-daemon,openrazer-driver-dkms,python-openrazer,razercommander; daemon had been disabled and razercommander never configured) →dkms statusempty → plain upgrade, then reboot. - Post-reboot verification: 7.3.0-2 running, 0 pending, dkms empty, no razer pkgs,
razermousenot loaded, one failed unit (tblockd).
pacnew cleanup¶
/etc/locale.gen.pacnew→ keep current (pacnew enables no locales; adopting would wipeen_AU/en_US)./etc/pacman.d/mirrorlist.pacnew→ keep current (CachyOS-generated list vs stock Arch).- Both
tpm2-tss/fapi-profiles/*.json.pacnew→ adopt (upstream data).
tblockd repair (broken since 2026-10-16)¶
- Symptom:
ModuleNotFoundError: No module named 'tblock'. Cause: package installed into/usr/lib/python3.13/site-packages, system python is 3.14.8 (python-autoeqwas fine — it is in 3.14). paru -S tblock tblock-guidid nothing — "is up to date — reinstall? [y/N]" defaults to No, so no transaction ran (pacman.logshowed only rebuild-detector chatter).--rebuildthen failed on sha512 mismatch: Codeberg regenerated its archive tarballs (top dir also changed fromtblock-2.7.5/totblock/; the PKGBUILD'scd "$srcdir/$pkgname"still matches). Verified content was genuine (gzip OK,VERSION = "2.7.5", Makefile/pyproject present, AUR tags confirm 2.7.5 is current stable) → built withparu -S --rebuild --mflags "--skipchecksums" tblock tblock-gui.- Then the daemon failed three ways in sequence:
User is not a member of the openrazer style group— actuallyopenrazergroup membership was missing →sudo gpasswd -a dini openrazer(needs re-login).systemctl restartSIGKILLed it afterTimeoutStopUSec=10swhile it rebuilt its DB → stale/run/tblockd.pid→ "instance already running". Fixed by removing the pidfile and adding a drop-in (TimeoutStopSec=90,Restart=on-failure,RestartSec=5).sudo tblock -B -n && sudo tblock -E -n→ protection active,/etc/hosts= 3,526,030 lines.- Verified:
googleadservices.comandadsbygoogle.js→ "could not resolve" (000);example.com200. Notegetentreturns nothing (not0.0.0.0) because nsswitch runsresolvefirst andnss-resolvedrops0.0.0.0→ surfaces asEAI_NODATA. Entry is present in/etc/hosts; cosmetic. - Cost:
tblockd~338 MB +systemd-resolved~346 MB for 3.5 M rules. User has RAM, so kept.
Razer DeathAdder Essential — the LED dead end¶
- Device
1532:0098. OpenRGB 1.1: CLI-m/-cis a no-op — verified in a 3973-line-vvtrace and against a live server on :6742; noSetMode/SetColorever reaches the device. GUI works but setting Direct/Static just left the logo black. - Reinstalled OpenRazer (daemon was disabled before — that's why it "never worked"). Rebuild gave
sysfs attrs:
logo_led_brightness,logo_matrix_effect_static/breath/none,device_mode. Writes worked (LED went black) but colour never applied. device_modeis a binary 2-byte attribute (buf[0]=mode,buf[1]=param);echo 3sent ASCII0x33 0x0Aand was rejected → extended colour packets ignored. Correct write isprintf "\003\000". Confirmedod→03 00.- Still black after driver mode +
\377\000\000. Answer: the DeathAdder Essential has a single-colour green LED (Razer spec sheet: "Single-color green lighting"; Razer Insider confirms colour cannot change). Firmware implements the RGB protocol, but only a green emitter exists → red/blue bytes = off; green bytes would light it. - Decision: remove openrazer + openrgb again (LED is green-only, nothing to gain, and it removes
the DKMS module). Keep the hand-made
/etc/udev/rules.d/99-razer-no-autosuspend.rules(unowned by any package, still useful). - Side buttons:
BTN_SIDE 275/BTN_EXTRA 276(decoded from the kernel bitmap), no onboard remap possible; options are Hyprlandmouse:275binds orinput-remapper(AUR). User decided to leave them as back/forward for now.
Repo reviews¶
- koala73/worldmonitor — 89 k stars in 9.5 months, 13.7 k forks, AGPL-3.0, TS+JS ≈ 80 MB,
283 MB repo, ~150 npm scripts, custom security lint rules, e2e shards, Tauri desktop, MCP server.
Assessment: real engineering discipline, but bus factor 1 (7962 commits by
koala73vs 84 next; botsclaude/cursoragentcontributing), scale far beyond one person's comprehension, freemium product with OSS core, stars = marketing curve. Read it for the lint-as-guardrail pattern; treat output as leads to verify, not conclusions. - PLAYER99-void/void — voice-first Claude Code companion (16 stars, MIT, 12 days old).
Linux overlay = GTK + WebKit + layer shell; brain =
claude -p --output-format stream-json; ears/mouth = faster-whisper + Kokoro. Inspired the overlay build below.
Built: ~/Projects/hal-overlay¶
- Keyboard-only top-centre notch driving
opencode, no voice. - Stack: GTK4 + WebKit 6.0 (
webkitgtk-6.0, not webkit2gtk-4.1 which is GTK3) +gtk4-layer-shell; face isface.htmlwith the Hal eye as inline SVG + CSS states. - Gotchas found:
LD_PRELOAD=/usr/lib/libgtk4-layer-shell.sois mandatory or the surface silently becomes a normal toplevel ("GTK4 Layer Shell may have been linked after libwayland"). Stripped from the child env before spawning opencode.- GTK4 has no
Gtk.main()→GLib.MainLoop(). - Hyprland places top-anchored layer surfaces 48 px down;
HAL_TOP_MARGIN=-48puts it at y=0. - webkit2gtk-4.1 + GTK4 = version conflict; use WebKit 6.0.
- Agent:
opencode run --format json --auto [--session sid] <prompt>, NDJSON parsed line by line;textevents stream into the transcript, tool events become chips,sessionIDreused. - Flags: default toggle,
--show,--hide,--start-hidden(autostart dormant),--quit; single instance via$XDG_RUNTIME_DIR/hal-overlay.sock; appears on the focused monitor. - Verified end-to-end: layer at
920 0 720 128,wtypetyped a prompt, OCR of a grim crop showedHAL / ❯ reply with exactly: HAL ONLINE / HAL ONLINE. - Not done: keybind (offered), approval bubble (
--autohardcoded), history, model switch, theme sync.
Tooling notes / mistakes¶
- Interactive shell is fish: no heredocs (
<<EOF→ "Expected a string, but found a redirection"), unmatched globs are hard errors ("No matches for wildcard"). Usesudo sh -c 'printf ... > file'and fish nullglob(N), e.g.ls /dev/razer*(N). - Two self-inflicted errors worth remembering:
pkill -f <pattern>matched my ownbash -ccommand line and killed the shell (twice);pkill -x python3was dangerously broad. Kill by PID fromhyprctl layers/ss -xlpinstead.
Links¶
- https://github.com/koala73/worldmonitor
- https://github.com/PLAYER99-void/void
- https://github.com/wmww/gtk4-layer-shell/blob/main/linking.md
- https://gitlab.com/CalcProgrammer1/OpenRGB
- https://github.com/openrazer/openrazer