Skip to content

Theme Layout

Bobby Comet edited this page Aug 2, 2026 · 1 revision

Theme layout: start.sh and theme.json

Every theme Conky Studio installs or builds lives as a folder under ~/.config/conky/<Name>/ (and optionally ~/.conky/). Two files at the root of that folder matter most for the Manager and for day-to-day use:

File Role
start.sh How the HUD is launched and stopped (Conky + background pollers)
theme.json How the Manager names, describes, and lists the theme

Neither file is required for Conky itself to draw if you run conky -c conky.conf by hand, but Studio’s Manager, install flow, and generated themes all assume this layout.


Directory convention

~/.config/conky/<ThemeName>/
├── theme.json          # metadata for Manager/library
├── start.sh            # single entry point to run the HUD
├── conky.conf          # Conky config (window, lua-draw-hook, …)
├── render.lua          # Cairo draw + data glue (Studio codegen)
├── preview.png         # optional thumbnail in Manager
├── README.md           # optional; viewable/editable in Manager
├── LICENSE             # optional
├── images/             # assets referenced by the theme
├── fonts/              # optional; auto-installed on import
├── scripts/            # sensors, weather, custom, album-art helpers
└── .runtime-cache/     # created at run time (key=value caches, art)

Themes without theme.json still appear in the Manager if they have start.sh or conky.conf; metadata is then guessed from the folder name until you generate or edit theme.json.


start.sh — what it is for

Purpose: one command that starts the whole HUD cleanly: Conky plus any daemon-mode background scripts (GPU/CPU sensors, weather, public IP, Now Playing, album art, unwired Custom Script daemons, etc).

Studio generates start.sh at Build time (codegen/start_sh_gen.py). Hand-written themes can use the same pattern.

Why it exists

  1. Conky alone is not enough when data comes from external scripts that write cache files. Those scripts must keep running on a timer; ${execi} handles only the “Conky polls a one-shot command” case.
  2. Single instance. Launching the same theme twice should replace the old run, not stack two HUDs and two poller sets.
  3. Clean shutdown. Stopping the theme should kill Conky and the poller loops together.
  4. Manager/double-click. The Manager’s Start button runs start.sh (via QProcess.startDetached). Users can also run ~/.config/conky/<Name>/start.sh from a terminal or .desktop file with no Studio open.

What it does (generated behaviour)

  1. setsid re-exec
    First launch re-executes under setsid so Conky and every background loop share one process group. Killing that group stops everything.

  2. PID lock file
    Path like $XDG_RUNTIME_DIR/<theme-name>.pid (or /tmp/…). If a previous instance is still alive, it is sent TERM (then KILL) to the process group before the new instance continues.

  3. Runtime cache dir
    mkdir -p "$DIR/.runtime-cache" — where daemon scripts write *.cache and album-art images.

  4. chmod scripts
    Ensures scripts/*.sh are executable.

  5. Daemon families
    For each daemon-mode family the project actually needs:

    • one immediate run (script.sh &) so the first frame is not empty
    • one while true; do sleep N; script.sh; done background loop

    Interval N comes from the shortest poll_interval among nodes in that family.

    Included even when unwired: daemon Custom Script nodes (legacy pure-Lua themes still read sensors.cache / weather.cache from Custom Lua). Album Art is always treated as daemon-style (writes an image file, not a single stdout value).

  6. exec conky -c "$DIR/conky.conf"
    Replaces the shell with Conky so the lock PID is the session leader the Manager can track.

What it does not do

  • It does not draw anything itself.
  • It does not poll execi-mode sources (Conky’s ${execi N …} does that).
  • It does not install fonts or edit theme.json.

Stop behaviour

  • Manager → Stop (or a second Start of the same theme): uses the lock PID and kills the process group (killpg /same idea as inside start.sh).
  • Deleting the lock file after a crash is enough for the next Start to proceed; start.sh also overwrites a stale lock when the old PID is gone.

theme.json — what it is for

Purpose: a small metadata manifest so the Manager can show a library without scanning conky.conf or guessing from Lua.

Defined by model/theme_meta.py. Filename is always theme.json at the theme root.

Why it exists

  1. Library UI — name, author, version, description, resolution in the list and detail pane.
  2. Search/tags — optional tags[] for filtering later or in docs.
  3. Dependencies — optional requires[] (e.g. lua-cairo, tools a README might also mention) for pre-launch checks or documentation.
  4. Store/updates — optional store_id / sha256 when a theme came from a catalogue (not required for local builds).
  5. Stable identity — folder name can differ from display name; Manager prefers theme.json.

Typical fields

Field Meaning
name Display name in Manager
author Credit line
version Theme version string (not Conky Studio’s app version)
description Short blurb under the title
resolution Target/design resolution hint (e.g., 1920x1080)
requires List of human-oriented dependency tokens (default includes lua-cairo)
tags Optional keywords
created_with e.g., conky-studio
store_id / sha256 Optional; omitted from tidy hand-authored files when unset

Example:

{
  "name": "Night Ops",
  "author": "you",
  "version": "1.0.0",
  "description": "Compact system + weather strip",
  "resolution": "1920x1080",
  "requires": ["lua-cairo"],
  "tags": ["dark", "minimal"],
  "created_with": "conky-studio"
}

How Manager uses it

  • Scan (manager/scanner.py): each subdirectory of ~/.config/conky and ~/.conky that looks like a theme is listed. With theme.json, metadata is loaded from disk; without it, name is the folder name and description notes that metadata was guessed.
  • Install archive (manager/installer.py): after extract, prefers name from theme.json for the destination folder title when present.
  • Generate / Edit: Manager can create a starter theme.json or open an in-place JSON editor (validates JSON on Save).
  • Duplicate: copies the tree and updates name inside theme.json when possible.

What it does not do

  • It is not read by Conky or render.lua at draw time.
  • It does not control FPS, gaps, or node graph (those live in the Studio project / conky.conf / render.lua).
  • Changing theme.json does not require rebuilding the theme unless you also change assets or scripts.

How they work together

Action start.sh theme.json
Build from Studio Generated next to conky.conf / render.lua / scripts/ Written or updated as theme metadata for export/install
Install .zip / .tar.gz Made executable; used for Start Drives display name when present
Manager Start/Stop Executed/process-group killed Only for listing and detail text
Run without Studio ./start.sh from the theme folder Unused by Conky
Hand-made classic theme Optional but recommended if you use daemon scripts Optional; Manager still lists the folder

Rule of thumb:

  • start.sh = run the living theme (process tree + Conky).
  • theme.json = describe the theme in the library (identity and docs).

Related files

Path / module Role
codegen/start_sh_gen.py Builds start.sh from daemon families in the project
codegen/shell_gen.py Dual-mode (--key / full cache) scripts under scripts/
model/theme_meta.py ThemeMeta schema and load/save
manager/scanner.py Finds installed themes
manager/installer.py Extract, font install, duplicate, export zip
manager/process.py Start/Stop via lock PID and process group
ui/manager_tab.py Manager UI: list, Start/Stop, theme.json & README editors

See also: Theme Architecture & Codegen Pipeline, Node Reference — Sources (daemon vs execi), Legacy Import.

Clone this wiki locally