aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
11 hourschore(git): untrack the generated dunst, conky and homepage configsHEADmasterDanilo M.4-219/+1
All three are written by udt-palette and rewritten by every install, so each scheme switch showed them as modified. dunstrc and conky.conf were already in .gitignore and tracked anyway, which does nothing: the ignore list is not consulted for files already in the index. homepage's custom.css was missing from the list entirely. Add the missing entry and drop all three from the index. AGENTS.md already documents them as generated and gitignored, so this makes the repo match what it says. Verified all three regenerate from an absent file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176XsV85ByN2ee7HseUKcqA
11 hoursfix(palette): emit waybar's Catppuccin names from rolesDanilo M.1-2/+18
styles/main.css and styles/global.css are edited in place, not generated, and reference nineteen colours by Catppuccin name: @surface1, @text, @crust, @lavender and the rest. gen_waybar emitted only the role layer plus the scheme's own palette names, which happen to include those names under the four Catppuccin schemes and none of the other five. Under tokyo-night every one of those references was undefined, GTK fell back to a default, and the separators in main.css went from a dim alpha(@surface1, 0.4) hairline to full brightness. The workspace underline, the bluetooth, mail and breaktimer state colours and the tooltip border were falling back the same way. Emit them from roles, reusing the ROFI_NAMES table that exists because rofi had this exact bug; mauve is the one name waybar uses that rofi does not, and maps to the highlight role. Verified across all nine schemes: every referenced name now resolves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0176XsV85ByN2ee7HseUKcqA
27 hoursfix(appthemes): take Obsidian vaults from its registry, not a directory scanDanilo M.1-6/+20
The installer found vaults by scanning ~/Documents/Obsidian for .obsidian directories, which cannot tell a vault from a leftover. That parent folder holds an abandoned .obsidian from a vault that no longer exists, so the scan found six vaults where Obsidian knows five, and the extra one got a snippet and an edited appearance.json for something Obsidian never opens. It now reads ~/.config/obsidian/obsidian.json, which is the list Obsidian itself maintains, and only writes to a path that is both registered and still has a .obsidian directory. The stray directory has been restored to its previous contents. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
27 hoursfeat(palette): add Obsidian and Typora as consumersDanilo M.6-0/+2060
Both expose a first-class, update-safe theming hook, which is what separates them from the Electron apps that cannot be consumers: Signal, Discord and Spotify ship closed bundles whose only theming route is patching a signed asar that every update reverts. Obsidian gets a CSS snippet rather than a theme, so it layers over whatever theme a vault already uses instead of replacing the user's choice. Enabling it means appending to enabledCssSnippets in each vault's appearance.json, which bin/udt-appthemes does by reading the list and adding to it: rewriting the file would have switched off the layout snippet one vault was already using. Typora's theme is derived from the Dracula theme installed here, whose 350 rules all resolve through :root variables, so only that block is templated and none of the layout is touched. Verified across six vaults, nested ones included: the vault with an existing snippet kept it, a vault with no appearance.json got a valid one, and three consecutive installs leave exactly one udt entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
27 hoursfeat(palette): generate the Kvantum theme so Qt apps follow the schemeDanilo M.15-2/+2520
Qt and GTK were the one part of the desktop the palette never reached: Kvantum was pinned to a hand-installed catppuccin-macchiato-lavender directory, so pcmanfm-qt and every other Qt app stayed Macchiato no matter which scheme was selected. A Kvantum theme is a .kvconfig of colours and a .svg of widget artwork with colours baked into the paths, which looked like it needed redrawing. It did not: the SVG carries only 27 distinct colours, 12 of them palette colours and the rest neutral greys that are shading, not theme colour. Both files are now templates with the 12 as placeholders, derived from the theme this desktop was already running. Installs to ~/.config/Kvantum/udt/ under one fixed name for every scheme, so a switch needs no change to kvantum.kvconfig and leaves no stale theme behind. Adds accent_dim and accent_bright roles for Kvantum's hover and pressed states. Verified: no placeholders survive generation, the SVG still parses as XML, and pcmanfm-qt picks up the new colours on restart. Qt reads a theme at startup only, so running apps need restarting; AGENTS.md says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
28 hoursfeat(palette): add five more schemes, and parse-check them allDanilo M.15-42/+828
Adds Catppuccin Frappe and Mocha, which share Macchiato's colour names so their role maps are the same mapping against different values, and Material Ocean, Palenight and Darker, which bring their own names and their own maps. Nine schemes now, all dark. Material ships one accent per hue and three greys where the roles want five depths, so each Material palette carries four interpolated shades, marked as not upstream, and its bright_* terminal slots name the same colours as the normal ones. The selftest now renders every scheme to a temp directory and has rofi parse every theme, not just check that roles resolve. Resolving was never the property that mattered: the Tokyo Night breakage resolved fine and still emitted a palette the themes could not use. Verified the check fails when a name is removed. Catppuccin Latte is deliberately absent. It is light, and that is not a role remap: homepage is pinned theme: dark and the generated card overrides target its dark-mode class. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
28 hoursfeat(install): reload running apps after generating configsDanilo M.6-36/+69
install.sh wrote every config and reloaded nothing, so a scheme switch looked half-applied: the files were correct but waybar, kitty, conky and dunst kept drawing the old colours until five commands were run by hand. It now signals waybar, kitty and Hyprland, runs udt-accent (which regenerates the accent and restarts dunst), and restarts conky, which has no hot-reload. Each is guarded on the process actually running, so a missing one is skipped rather than started: verified conky stays stopped when it was not up before. rofi needs nothing, it reads its theme per launch. Qt and GTK apps still need a manual restart and the README says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
28 hoursfix(palette): emit the rofi palette from roles, not scheme colour namesDanilo M.1-6/+43
Switching to tokyo-night broke every rofi launcher. The themes reference Catppuccin spellings (@base, @text, @surface0), and gen_rofi emitted whatever names the scheme happened to use, so under Tokyo Night the palette defined bg and fg instead and rofi refused to parse a theme referencing colours that did not exist. The names the themes ask for are now filled from roles, the same way every other consumer already worked. The spellings stay Catppuccin's because that is what the themes were written against; only the values change per scheme. Adds a selftest that collects every @name used in a colour property across the themes and asserts the generator emits it. Verified it fails when a name is removed, rather than passing vacuously, and all seven themes now parse under all four schemes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
28 hoursfeat(palette): generate the homepage stylesheet and stage it on installDanilo M.8-1/+162
The dashboard's custom.css was written by hand against Macchiato, so it would have drifted the moment the desktop changed scheme. It is now generated from the same roles as everything else and staged on the host by install.sh. Adds four intermediate grey roles to every scheme. homepage wants a full ten-step ramp where the other consumers want three depths, and without them several steps collapsed onto the same colour, flattening the mid-tones. The scp is deliberately soft: five second timeout, BatchMode, a warning rather than a failure when the host is unreachable, so a laptop away from that network still installs the local theme. It stages to ~/hp-stage only, because /opt/homepage/config is root-owned; install.sh prints the sudo copy to finish. Verified: the generated Macchiato stylesheet reproduces the deployed one colour-for-colour, switching to tokyo-night propagates through to the staged file, and a failing scp leaves install.sh exiting 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
29 hoursfeat(palette): move the scheme selection out of the repoDanilo M.6-23/+50
The selector was tracked at palette/roles.conf, which made switching scheme a committable change: the previous commit carried `scheme = tokyo-night` in its diff purely because that was the theme running at the time. Which theme a machine runs is local state, not a property of the project, so the live file is now ~/.config/udt/roles.conf. install.sh seeds it from palette/roles.conf.default on a first run and never overwrites it, so a switch leaves the working tree clean and two machines sharing this repo can run different schemes. udt-palette falls back to the seed when no live file exists, so a bare checkout still generates. This is the one exception to the repo holding the canonical copy of everything, and AGENTS.md says so. Verified: seeding on a missing file, the seed not overwriting an existing choice, generation from the seed alone, and both selftests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
29 hoursfix(accent): make udt-accent scheme-independentDanilo M.4-24/+35
Two things still assumed Catppuccin. The QML header hardcoded "Catppuccin Macchiato" regardless of the scheme in use, and the selftest asserted that an orange input snaps to a colour named "peach", which is true only under Catppuccin: Tokyo Night calls that hue "orange" and the test failed the moment the scheme changed. The header now names the scheme it generated from. The snapping assertions test the property instead of the spelling: an input must land within 0.6 rad of its own hue, and a border neighbour must sit nearer the accent than its opposite. Both hold under any palette. Verified: --selftest passes under macchiato, tokyo-night, nord and dracula. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
29 hoursfeat(palette): generate every themed config from one schemeDanilo M.20-226/+1269
Colours were written down five times: rofi's palette.rasi, the waybar theme, the kitty theme, the conky and dunst templates, and a MACCHIATO dict inside udt-accent. Changing scheme meant finding all five, and they had already drifted: the active waybar theme was Macchiato while theme.css next to it was Mocha, and nothing imported the latter. Now a scheme is two files. palette/<scheme>.conf holds the colours under the scheme's own names, and palette/roles-<scheme>.conf says what each is for. palette/roles.conf is one `scheme =` line selecting the pair. bin/udt-palette renders that into each consumer's syntax and install.sh runs it first. The role map is per-scheme rather than shared because the palettes are genuinely different shapes: Nord has no `base`, Dracula no `surface0`, and forcing Catppuccin's names onto them would have meant either renaming their colours or inventing values. A role names a palette colour with two optional modifiers, `name/75` for alpha and `name*50` for brightness. The second exists because GTK's shade() has no palette name to point at. Ships macchiato, tokyo-night, nord and dracula. --selftest resolves every role in every scheme and asserts they define the same set, so a scheme that cannot satisfy a consumer fails at install rather than when someone switches to it. Verified against the live configs: all 46 waybar colours resolve identically to the previously active theme including its alpha() and shade() derivations, the kitty theme is colour-for-colour identical, and the rofi palette has the same 26 values. Generated files are gitignored; switching scheme and switching back reproduces the originals. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
29 hoursrefactor(accent): resolve the wallpaper path, finish the atomic-write helperDanilo M.1-30/+7
colors.json recorded whatever path it was handed, so it read either the real wallpaper or ~/.cache/wal/wpaper, the symlink to it, depending on the caller. wallp passes the resolved file; a manual run usually passes the symlink. Same wallpaper either way, so record one spelling. write_atomic arrived with the quickshell palette but only write_border used it. The other four writers kept their own copy of the same write-then-rename, which is the duplication the helper was added to remove, so they use it now. No behaviour change: the temp file was already created by mkstemp in every case, so the resulting modes are the same. Verified by running the script before and after: udt-palette.qml, udt-accent.rasi and udt-border.lua are byte-identical, and colors.json differs only in the wallpaper field this commit intends to change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
30 hoursfeat(accent): generate a QML palette for quickshellDanilo M.3-12/+101
udt-accent now writes ~/.cache/wal/udt-palette.qml alongside the accent, border and colors.json it already produced. Quickshell components read it and watch it, so editing the palette here recolours a running shell without restarting it. Unlike the other outputs this one is not only the accent: it carries the structural colours too. Those are parsed out of rofi/udt/palette.rasi rather than restated in the script, so that file stays the single place the Macchiato values are written down. Hardcoding them a second time here is exactly the drift this is meant to remove: the quickshell components each had their own copy before this. The atomic write that write_border already did by hand is now a helper, write_atomic, used by both. Every generated file is watched by something, and a torn read shows up as a theme that briefly loses its colours. colors.json is untouched by this change, verified by running the script before and after and comparing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
30 hoursdocs: note the CM_LAUNCHER removal alongside .xprofileDanilo M.1-3/+5
It configured clipmenu, the X11 clipboard manager .xprofile started. cliphist through rofi replaced it, so the export had nothing left to configure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
30 hoursdocs: record the deletion of ~/.xprofileDanilo M.1-0/+13
An X11 leftover nothing reads under Wayland. Nothing sources it, and every program it started is either not running or started elsewhere now (dunst, by udt-accent). Backed up to /data/udt-backup/xprofile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
30 hoursdocs: record the pinentry theming fix in MIGRATION.mdDanilo M.1-7/+39
The GPG PIN dialog was the last unthemed Qt6 app. pinentry-qt links Qt6 despite the name, but gpg-agent is spawned from .bashrc and reparented to init, so it never inherits the QT_QPA_PLATFORMTHEME that Hyprland sets for its own children, and every pinentry it spawns fell back to Fusion. Also restructures the document: it was headed "phase 1 (rofi)" and now covers more than rofi, so the phase is a section rather than the title. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
31 hoursfeat: theme Firefox from the accent via pywalfoxDanilo M.2-9/+75
udt-accent now rewrites ~/.cache/wal/colors.json as a fixed Catppuccin Macchiato palette with the wallpaper's accent in the cursor and the two highlight slots, then runs `pywalfox update`. colors.json is the only file pywalfox reads, so this is the only way Firefox can follow the accent. Overwriting it wholesale costs nothing: wallp already rewrote it moments earlier via `wal --theme`, and nothing else consumes it. kitty reads its own current-theme.conf, so the terminal palette is unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
35 hoursdocs: add AGENTS.md with the project's non-obvious constraintsDanilo M.2-0/+118
Records what cost real time to discover: that rofi's -dump-theme normalises values and cannot tell you what renders, that measuring screenshot pixels beats reasoning about the box model, that GTK3's theme comes from gsettings rather than settings.ini on Wayland, that ClearlyU shadows Private Use Area glyphs in fontconfig fallback, and why accent extraction must not go through wal -i. CLAUDE.md is a thin pointer at it, matching the user's global convention. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfix: bump kitty font size for Inconsolata's narrower faceDanilo M.1-3/+3
13.0 to 15.0, the same correction waybar needed after the same font change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfeat: use Inconsolata for kitty as wellDanilo M.1-3/+10
Brings the terminal onto the same monospace font as the rest of the desktop. The live setting is inside the BEGIN_KITTY_FONTS block managed by kitty's font kitten; a stale commented-out font_family line above it was removed, since it looked authoritative but had no effect. Size left at 13.0. Inconsolata reads slightly smaller than CommitMono at the same nominal size, the same difference that needed a 2px bump in waybar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfeat: move kitty and neovim to Catppuccin MacchiatoDanilo M.2-0/+127
These were deliberately left until last: wallpaper-derived colours in kitty's ANSI slots were the original readability problem, since nothing in a wallpaper guarantees color4 stays legible against color0. A hand-tuned palette is safe for the opposite reason, so the move is onto Macchiato rather than back onto pywal. current-theme.conf was a symlink into the wal cache and is now a real file. wal.sh no longer recreates that symlink, which would have silently reverted the theme on the next wallpaper change. Neovim read the same pywal output via colorscheme pywal and now uses the catppuccin/nvim plugin. Its airline theme was base16_dracula, matching nothing; it is now base16, which derives from the active colorscheme. Measured before committing: every ANSI slot clears 4.5:1 against its own background in both themes except color0, which is the near-background slot in both. color8, used by some colourschemes for comments, does drop from 3.83:1 to 2.38:1, but the Catppuccin neovim plugin sets its own comment colour rather than using ANSI 8, confirmed on screen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfix: bump waybar font sizes for Inconsolata's narrower faceDanilo M.2-4/+8
Inconsolata renders smaller than Commit Mono at the same nominal size, so matching the number made the bar read smaller than before. Every size in fonts.css goes up by 2px. Both ends of the bar still fit without truncation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfeat: bring waybar's font in line with the rest of the desktopDanilo M.3-0/+116
Waybar was already Catppuccin Macchiato with a lavender accent, using the same hex values as the rofi palette, so only the font needed changing: it asked for Commit Mono Nerd Font, a third family outside the Noto Sans and Inconsolata pair. Monospace is kept deliberately, since a status bar is dense and numeric and proportional text makes values jitter as they update. Also records that the CSS load order in waybar's own CLAUDE.md is stale. The modules-*.css and states.css files it documents are not imported by anything; style.css pulls in styles/main.css instead. One of the dead files holds a font-family declaration that looks authoritative but has no effect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
35 hoursfeat: unify Qt5, Qt6 and GTK on Macchiato with a lavender accentDanilo M.7-6/+108
Installs the upstream Catppuccin Kvantum and GTK themes and points all four toolkits at them. Qt5 and Qt6 previously disagreed with each other as well as with the desktop: qt5ct carried a hand-rolled grey/purple palette and qt6ct used the stock darker.conf. Both now take their palette from Kvantum. Two things were not where they looked. GTK3's theme comes from gsettings on Wayland, not settings.ini, and gsettings was pinned to Breeze, which silently overrode the file; its icon-theme was likewise on breeze-dark while settings.ini said Material-Black-Plum-Suru. GTK4 ignores gtk-theme-name entirely, so its stylesheet is symlinked into ~/.config/gtk-4.0 instead. The accent is fixed rather than wallpaper-tracking, since Qt and GTK apps only reread a theme on restart. Lavender also replaces mauve as udt-accent's fallback so everything without a wallpaper-derived accent agrees. catppuccin/gtk is archived upstream. v1.0.3 works today but will not track future libadwaita changes; it is removable by deleting the directory. The tracked qt5ct/qt6ct files carry only the theme-relevant keys: the live files also hold an ignored_applications list of local paths. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfeat: repalette conky to MacchiatoDanilo M.1-0/+102
Only the seven colour definitions in conky.config changed. The conky.text block is byte-identical: its layout is column-based on absolute ${goto} pixel offsets, so touching label widths or glyphs would need every goto on that line re-tuned. Mapping keeps each colour's role and its light/dark relationship, so the widget reads the same: headings and glyphs to lavender, field labels to teal, accent glyphs to mauve, separators to surface1, values to text. Conky does not hot-reload, so this needs a restart to take effect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfeat: theme dunst in Macchiato with a wallpaper-driven accent frameDanilo M.2-0/+109
Notifications previously drew their colours from the pywal preset, so they were pure black on white and did not match anything else. Structural colours are now fixed Macchiato, with the accent as the frame on normal urgency, a muted surface frame on low, and Macchiato red on critical. Font moves to Noto Sans to match the rest of the desktop. udt-accent substitutes the accent after pywal renders the template, then restarts dunst so it rereads the file. It restarts rather than just killing: nothing else respawns dunst, and a dead dunst means no notifications at all. Also fixes a dangling reference: the template pointed dunst's dmenu at darknix/main.rasi, a theme that no longer exists. The template is tracked here as templates/dunstrc; the live copy is ~/.config/wal/templates/dunstrc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfeat: drive the Hyprland border gradient from the wallpaper accentDanilo M.1-1/+55
Replaces the six-stop RGB rainbow with the current accent plus its two neighbours on the perceptual hue wheel. The borderangle animation rotates a gradient, so it needs more than one colour to show motion; neighbouring hues keep that motion legible without leaving the palette. Emitted as Lua rather than a .conf snippet. Hyprland's Lua parser refuses hyprctl keyword ("keyword can't work with non-legacy parsers") and has no source directive, so look_and_feel.lua reads the generated table with dofile() and falls back to a fixed Macchiato triple when it is absent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursdocs: record archiving of the superseded rofi theme directoriesDanilo M.1-11/+19
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfeat: make the power menu overlay slightly translucentDanilo M.1-1/+10
The fullscreen ground drops to 88% opacity so the desktop stays faintly visible behind it, which keeps the menu reading as a layer over the session rather than a screen that replaced it. Written as an explicit rgba of the same colour rather than @base, since the palette entries carry a hard ff alpha. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursdocs: record the confirm dialog migration and glyph changeDanilo M.1-5/+11
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfeat: bring the power menu confirmation dialog into the themeDanilo M.2-1/+62
The yes/no gate in front of shutdown was still on the old adi1090x theme, so every shutdown showed a Macchiato power menu followed by a dialog that did not match it. Its glyphs now come from the theme's own Nerd Font rather than `feather`. That meant changing the codepoints the script sends, since the originals were Private Use Area points that only feather carries: they are now the Material circled check and close (U+F05E0, U+F0159), which Inconsolata Nerd Font Mono contains. Sized 42 to match the power menu, since the Material glyphs carry a lot of internal padding and render small. Worth knowing for future glyph choices: ClearlyU is installed and claims large parts of the Private Use Area, so it can win fontconfig's fallback and draw a blank where another font actually has the glyph. The U+F0xxx Nerd Font ranges avoid that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfix: widen the emoji grid so entry names fitDanilo M.1-11/+13
Each row is a glyph followed by its name, and five columns in a 680px window left cells too narrow for the name to survive. Three columns in a 1500px window gives about 485px a cell. Names are also left-aligned now rather than centred, since a row is a label rather than a lone symbol, and the glyph font drops from 20 to 16 so the name carries the row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfix: make the power menu avatar a centred circleDanilo M.1-11/+21
The widget only honours its margin. An explicit width with expand:false collapses it to a line, and a percentage margin resolves against the whole window rather than the padded column, which tiled the image across a 2560px screen. So the width comes from a pixel margin derived from the content column, and it has to equal the height the row gives the widget (220px) for the 100% radius to draw a circle instead of an ellipse. Also bounds the content column, which was previously full screen width: four options spread across ~640px cells read as scattered glyphs and the selection highlight became a slab. Measured from screenshots rather than guessed: the avatar renders 220x220, ratio 1.000, centred within a pixel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfix: draw the power menu avatar againDanilo M.2-8/+15
Sizing the widget with an explicit width and height collapsed it, so nothing was drawn. The original type-4 theme sized it with a horizontal margin instead, letting the widget expand to the window and squeezing it back to a square, so do that. The margin is computed with calc() from 50% rather than the original's hardcoded 710px, which assumed one screen width and would sit off-center on a second monitor. The tilde path was never the problem: rofi does expand it inside a url(). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
36 hoursfix: restore message widget, fullscreen power menu, and emoji gridDanilo M.4-2/+144
Three regressions from collapsing five theme systems into three layouts. The layouts hardcoded `children`, which silently dropped any -mesg a script passed. rofipass lost its keybinding cheatsheet and the power menu lost its uptime line. list.rasi now lists the message widget; rofi hides it when there is no message, so it costs nothing when unused. The power menu was never a small menu. It is a deliberate fullscreen prompt with a greeting, an avatar and one row of four large glyphs, and menu.rasi flattened all of it. It gets its own layout, the one place where a prompt earns its keep. The glyphs are drawn in Inconsolata Nerd Font Mono, which was verified to contain all four; the old theme asked for `feather`, which contains none of them and was relying on fallback. The emoji picker is a dense grid of glyphs, not a list, and wasted most of a single-column window. It gets grid.rasi, sized near the launcher's icons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursdocs: record phase 1 migration of rofi call sitesDanilo M.2-0/+68
Twelve call sites repointed, backups in /data/udt-backup. Also records three things found during the migration: rofipass was passing a -width flag that rofi 2.0.0 no longer has, the type-4 power menu reuses one directory variable for two different themes, and ddgr_search.py is a rofi script-mode plugin rather than a call site. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: drop the prompt label from the input barDanilo M.1-6/+4
The mode label ("Apps", "power") is noise on a desktop utility: it is always obvious which one was just opened. Removed in common.rasi so every layout inherits it, and the placeholder text is cleared for the same reason. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: anchor the launcher top-center and add a wallpaper bannerDanilo M.2-14/+42
Matches the launcher position already in use (north-anchored, 600px, single column) rather than the centered grid, and restores the wallpaper banner behind the input area from the old darknix theme. The wallpaper path cannot be committed: rofi does not expand a tilde inside a url(), and an absolute path would bake in a home directory. So launcher.rasi carries a placeholder and the installer generates the real file. The entry sits on a solid plate so it stays legible over a bright wallpaper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add symlink installerDanilo M.1-0/+28
Installs by symlink so the repo stays canonical and the working config cannot drift from it. accent.rasi is the exception: it points at the generated file in the wal cache, seeded with the committed placeholder on a fresh install. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add udt launcher layoutDanilo M.1-0/+32
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add udt menu layoutDanilo M.1-0/+28
No search bar: with a handful of fixed options, typing to filter is pointless and the bar only adds bulk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add udt list layoutDanilo M.1-0/+24
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add shared rofi styling common to all udt layoutsDanilo M.2-0/+117
Holds the identity every layout inherits: Noto Sans for UI text, Inconsolata Nerd Font Mono for monospace (both matching the existing Qt and GTK settings), one border radius, and one selected-element treatment of accent background with base-colored text. accent.rasi is committed as a mauve placeholder so the imports resolve before any wallpaper has been processed. On install it is replaced by a symlink to the generated file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: extract wallpaper accent without touching the pywal cacheDanilo M.1-0/+58
Calls pywal.backends.colorz.get() directly rather than running `wal -i`. That function returns a list and writes nothing, so the preset-driven cache that kitty, dunst and neovim read is left alone. `wal -i` has no isolation flag and would rewrite all of ~/.cache/wal, reintroducing the unreadable-terminal problem the preset was adopted to fix. Writes atomically, so a rofi launch concurrent with a wallpaper change cannot read a half-written theme. A missing or broken image falls back to mauve rather than leaving no accent at all. Verified across six wallpapers with colors.json byte-identical afterward. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add perceptual hue matching for Macchiato accentsDanilo M.1-0/+101
Matches in CIELAB rather than HLS: HLS hue is not perceptually uniform and mismatched obvious cases during prototyping, snapping orange to yellow and saturated red to flamingo. The candidate set is nine, not all fourteen. rosewater and flamingo are near-neutral tints that carry a hue angle but almost no chroma, so they captured saturated inputs; maroon, sapphire and lavender duplicate the hues of red, sky and mauve without adding visible range. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursfeat: add Catppuccin Macchiato palette for rofiDanilo M.1-0/+41
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hourschore: add GPLv2 license, README and gitignoreDanilo M.3-0/+378
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursdocs: add headless parse checks and correct the rofi versionDanilo M.1-17/+52
The plan claimed rofi 1.7.3, taken from a stale comment header in the user's config.rasi. The installed version is 2.0.0. Adds a `-dump-theme` parse check to the palette and each layout task. This catches syntax errors without a display, which the plan previously treated as impossible and deferred entirely to visual inspection. Every theme file in the plan was verified to parse cleanly on 2.0.0. Replaces the palette verification step, which built a throwaway wrapper theme via printf just to have something that draws. A palette defines variables and renders nothing, so there was nothing to look at; parsing is the real check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq
37 hoursdocs: correct accent pipeline premise and add implementation planDanilo M.2-39/+1217
Investigation while planning showed the spec's accent model could not work as written. wallp invokes pywal with --theme, not -i, so colors come from a fixed preset and never track the wallpaper: snapping would have mapped a constant to a constant. The obvious fix, switching to wallpaper-derived pywal, would have regressed a problem the user had already solved. Wallpaper colors land in kitty's sixteen ANSI slots, where nothing guarantees color4 stays legible against color0, which is what made neovim comments disappear. Rofi is not exposed to that, since it uses one accent against a fixed base. So extraction now calls pywal.backends.colorz.get() directly. It returns a list and writes nothing, leaving the preset cache that kitty, dunst and neovim read untouched. Verified across six wallpapers with colors.json byte-identical after. Also replaces HLS hue matching with CIELAB, after prototyping showed HLS snapping orange to yellow and red to flamingo, and narrows the candidate set to nine accents, dropping near-neutral tints and duplicate hues that captured saturated inputs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq