# conky-theme-udt A fullscreen Conky dashboard for Hyprland, drawn with Cairo from Lua, living on a special workspace that `SUPER+S` toggles. Colours come from [unified-desktop-theme](../unified-desktop-theme): this repo holds `conky.conf.in`, and UDT's `bin/udt-palette` renders it into `conky.conf` using the current scheme's `[conky]` roles. Switching scheme recolours the dashboard. ## Install Rendering and linking are automatic: cd ../unified-desktop-theme && ./install.sh That renders `conky.conf` from `conky.conf.in` and symlinks it, along with `dashboard.lua`, `lib/` and `widgets/`, into `~/.config/conky/`. Re-running it after a scheme change re-renders the colours. The Hyprland side is **not** installed by that script and is still yours to do. Until you do it, the dashboard opens as an ordinary floating window on whatever workspace is current, with no keybind, because the window rules that place it are not loaded. Two things are needed, both described in [`hypr/README.md`](hypr/README.md): symlinking `hypr/dashboard.lua` into `~/.config/hypr/sections/` and requiring it from `hyprland.lua`, and changing the bare `hl.exec_cmd("conky")` in `sections/autostart.lua` so it loads this config. Both are deliberately left as your choice rather than done for you. ## Changing the layout Edit the `layout` table at the top of `dashboard.lua`. `col`/`row` are grid cells and `w`/`h` span them; cell size is derived from the screen, so the same table works on differently shaped monitors. local layout = { { widget = 'clock', col = 1, row = 1, w = 1, h = 2 }, } Reordering widgets is an edit to that table and nothing else: a widget is handed a rectangle and draws inside it, so it cannot care where it is. Adding one is a file in `widgets/` exporting `draw(cr, rect, colors)` plus a row in the table. `COLS` and `ROWS` above the table set the grid. Cards snap to it; there is no absolute pixel placement, deliberately, because cells keep aligning when the grid or the screen changes. ## Writing a widget A widget module exports one function, `draw(cr, rect, colors)`. `lib/card.lua` carries the primitives it should use rather than reaching for Cairo directly: - `card(cr, rect, colors)` draws the rounded card and returns the padded inner rect to lay out against. - `font(cr, family, size, bold)` and `rgba(cr, colour)` set the state. - `text(cr, x, y, s)` draws at a baseline, `text_right(cr, x, y, s)` aligns to a right edge, `label(cr, x, y, s, colors)` draws a small-caps section label. - `measure(cr, s)` returns the **ink** size, what the glyphs actually cover. Use it to centre or right-align. - `advance(cr, s)` returns the **x_advance**, how far the cursor moves after drawing. Use it to step along a run of text. `measure` and `advance` are not interchangeable, and conflating them was a real bug here: ink width ignores leading and trailing spaces, so `' / '` measures 6px of ink against a 14px advance, and stepping a cursor by the ink width renders the date as `16 /SEP /2026`. ## Development Run it in the foreground to see Lua output, which is the only debugging channel: conky -c ~/.config/conky/conky.conf Conky has no hot-reload, so kill any running instance first (`pkill -x conky`) rather than ending up with two. Run the parser and layout checks: lua test/test_data.lua && lua test/test_layout.lua Screenshot it. `grim` captures screen coordinates, not a window, so the dashboard's workspace has to be the active one first, and the toggle needs the Lua dispatch form because this Hyprland config is Lua (the plain `togglespecialworkspace dash` form fails with `')' expected near 'dash'`): hyprctl dispatch 'hl.dsp.workspace.toggle_special("dash")' sleep 1 grim -g "$(hyprctl clients -j | jq -r '.[]|select(.class=="conky-dash")|"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')" /tmp/dash.png hyprctl dispatch 'hl.dsp.workspace.toggle_special("dash")' Before the Hyprland section is installed there is no `special:dash` to toggle, so the window is simply wherever it opened and the `grim` line alone captures it. ## Gotchas worth knowing **Cairo on Wayland needs `conky_surface()`.** Under `out_to_wayland`, `conky_window.drawable` and `.visual` are both `nil`, so the `cairo_xlib_surface_create` idiom used by essentially every Conky-Lua tutorial cannot work here. **A Lua error is a blank screen and nothing else.** No stderr, no log. The draw runs inside `pcall` and paints the caught error on the surface, which is the only reason a mistake is visible at all. **`own_window_type` must be `normal`.** A `desktop`-type window is a layer-surface at level 0 and Hyprland cannot assign it to a workspace. **Lua cannot read the palette through `conky_parse`.** `conky_parse('${color3}')` comes back as an **empty string**: conky's colour variables emit renderer escape codes into the text stream rather than evaluating to hex, and `${default_shade_color}` is not a variable at all. `conky.config` is not exposed to Lua either. What Lua does get is `conky_config`, the config file's path, so `dashboard.lua` opens that file and parses the hex out of it. **Cairo has no Black font weight.** `CAIRO_FONT_WEIGHT_BOLD` is the maximum, so the heavy clock numerals ask for the family `Noto Sans Black` at normal weight. **Sensors are globbed by hwmon `name`, never by index.** Indices drift across kernel and hardware reorders, and a stale one silently reports a different chip. ## License GPLv2 only. See `LICENSE`. ## Development Approach This project is developed using AI-assisted tools. Code is generated with the help of AI based on human-provided specifications, design decisions, and iterative feedback. All contributions are reviewed, tested, and curated by the maintainer before being included in the codebase. AI is used as a productivity and exploration tool, while human oversight remains central to all decisions. The goal is to combine the flexibility of AI-assisted development with standard open-source practices such as transparency, review, and accountability.