-
-
Notifications
You must be signed in to change notification settings - Fork 1
Legacy Importer Internals
Project → Import Legacy Theme… builds a Studio project graph from a theme folder. Conversion is semantic, not a pixel-perfect clone. This page documents how that mapping works.
Source of truth in code: conkystudio/importer/legacy_parser.py (UI entry: main_window._import_legacy_theme). Related behaviour also lives in visuals.py / sources_external.py / lua_gen.py / builder.py / start_sh_gen.py for Custom Lua inputs, Custom Script bodies, and daemon loops.
| Node | Meaning after import |
|---|---|
| Custom Lua | Self-contained Cairo/HUD code. Studio does not turn it into Arc/Bar nodes and does not auto-rewrite its internal sensor logic onto graph wires. |
| Custom Script | Self-contained shell (path and/or Inline script). May run as daemon and write its own cache; Custom Lua may read that cache directly. |
| Native sources / visuals | Used when TEXT ${…} mapping is clear (CPU bar, hostname text, …). |
Graph nodes you add later are extra layers. To feed them into Custom Lua, wire Input 1–12 and edit the Lua text to use in1…in12.
theme folder (dialog lists files + hidden; Accept = folder, or parent of a selected file)
├── conf / conkyrc → Canvas + palette (colorN / font) + lua_load paths
├── TEXT section → cursor layout + text / bar / line / exec nodes
├── *.lua (lua_load) → Custom Lua visual node(s) + path rewrites
└── scripts / images → Custom Script sources (path + optional script_body),
asset_paths on Custom Lua, daemon flags, warnings
↓
Project (nodes + edges + warnings)
↓
_layout_import_graph + _collapse_warnings
↓
Studio canvas load → Build (same codegen as native) → user polish
Import produces a graph; Build writes start.sh / conf / Lua the same way as native projects.
-
Folder dialog — non-native Qt dialog, files and hidden entries visible (
ShowDirsOnly = false,QDirfilters includeHidden). Selecting a file uses its parent directory as the theme root. -
import_legacy_theme(theme_dir)— parse + graph. -
load_project— open in Studio. -
builder.build_projectinto a sanitized name under the install root (spaces/parens from"name (imported)"are normalized). - Failures are caught in stages (dialog / parse / canvas / build) with traceback dialogs instead of aborting the process.
Parsed from the Lua-style conky.config = { ... } (and classic settings where present):
| Conf concept | Studio target |
|---|---|
minimum_width / height (and related; Lua locals like WIDTH resolved when possible) |
Canvas width / height |
alignment, gap_x, gap_y
|
Canvas placement |
update_interval |
Influences FPS / timing defaults where mapped |
default_color, color0–color9 / colourN
|
Import palette used by ${color…} in TEXT |
font / default_font
|
Default cursor font family / size for TEXT |
lua_load |
Resolved relative to the theme dir; may be one path or a list |
own_window_* |
Not always 1:1; Build applies session-aware window types later |
lua_load resolution: relative paths, HOME concatenations, and sibling .lua files under the theme are collected. Multiple loads can become multiple Custom Lua nodes.
TEXT is walked line by line with a virtual cursor (x, y, font, colour) — the same mental model as Conky’s ${goto} / ${voffset} layout, not a full typesetting engine.
Cursor colour/font start from the conf palette and default font, not hard-coded white/Sans.
| Directive | Behaviour |
|---|---|
${goto N} |
Set cursor x to N |
${offset N} |
Add N to x |
${voffset N} |
Add N to y |
${alignc} / ${alignc N}
|
Centre-ish x using canvas width (+ optional offset) |
${alignr} / ${alignr N}
|
Right-side x (canvas width − offset) |
${font …} |
Update cursor font family / size |
${color…} / ${colour…}
|
Update cursor colour from palette index, #hex, or default |
${hr} / ${stippled_hr}
|
visual.hline at cursor; advances y slightly |
| blank lines | Advance y by font size + spacing |
Literal runs of text become visual.text nodes at the current cursor with the active font/colour. Placeholders like {{VALUE:id}} may be turned into String Format logic + a text visual when mixed with surrounding text.
${if_running…}, ${if_match…}, ${endif} are stripped. Content is kept; branching is not reconstructed. A warning is recorded when any conditional was removed.
Identical type + props share one source node (get_or_create_source), so a TEXT-heavy theme does not spawn dozens of CPU boxes. Unknown registered types fall back to a Custom Script placeholder + warning instead of crashing the canvas.
| Directive (examples) | Studio source / visual |
|---|---|
${cpu} / ${cpu N}
|
source.cpu_percent (core mapped when possible) |
${mem} / ${memperc}
|
source.ram_percent |
${fs_used_perc PATH} |
source.disk_percent |
${fs_bar … PATH} |
Disk source + visual.bar
|
${battery} / ${battery_percent}
|
source.battery_percent |
${downspeed} / ${downspeedf}
|
source.net_down |
${upspeed} / ${upspeedf}
|
source.net_up |
${uptime} / ${uptime_short}
|
source.uptime |
${nodename} |
source.hostname |
${kernel} |
source.kernel |
${processes} |
source.process_count |
${time FORMAT} |
source.datetime |
${cpubar} / ${membar}
|
Matching source + visual.bar
|
${cpugraph} / ${memgraph}
|
Matching source + visual.history_graph
|
Unknown or exotic directives (${top}, swap bars, etc.) are counted and appear in one summary warning (or a short placeholder text node), not one warning per occurrence.
| Form | Import rule |
|---|---|
${execi INTERVAL CMD} |
Interval + command extracted |
${execpi} / ${texeci}
|
Same family as execi |
${exec CMD} |
Treated as rare/once-style; Custom Script with a long interval + warning |
${execbar … CMD} |
Source (family/native/custom) + visual.bar
|
Classification of CMD (_classify_known_script):
-
Native — known patterns →
get_or_create_sourcefor a built-in type. -
Family — known script families (weather, playerctl, …) → family source with
poll_mode: execiand interval. -
Else — Custom Script:
script_pathset; small file contents copied intoscript_body(Inline script) so Properties can edit without an external editor.
TEXT may embed a {{VALUE:id}} placeholder so a following text visual can be wired. Unknown scripts are never dropped silently.
| Flag / args | Result |
|---|---|
path, -p x,y, -s W×H
|
Position/size parsed when present |
-n (no cache) |
Often mapped to Album Art-style node + warning with original path |
| normal image |
visual.image_icon if a matching file is found under the theme tree |
| missing file | Node still created with empty/partial path + warning to re-attach |
Pure-Lua themes: images are usually drawn inside Custom Lua. Import attaches asset_paths on that node; Build copies them into assets/ and images/ and rewrites Lua paths toward ASSETS_DIR / CACHE_DIR. Separate Image nodes are not auto-created for that case (they would be a second independent drawing layer). Use Input 1–12 only for numeric/text data you choose to wire.
Scope boundary (by design): the importer does not decompile Cairo into Arc/Bar/Star nodes, and does not force Studio sources to drive the imported draw code.
| Input | Output |
|---|---|
Bodies from lua_load
|
One or more visual.custom_lua nodes |
Surface create/destroy / require 'cairo' / conky_window size |
Stripped or rewritten toward Studio’s shared cr / W / H
|
| Asset / cache paths inside Lua | Rewritten toward THEME_DIR / ASSETS_DIR / CACHE_DIR when patterns match |
| Scripts only referenced from Lua | Discovered and turned into Custom Script nodes when possible |
| Click regions in Lua | Clickable markers / commands when patterns are recognized |
Internal vitals (safe_number('${cpu}'), sensors.cache, …) |
Left as written — edit the Lua text to change behaviour |
Each Custom Lua node has bindable Input 1–12. Codegen injects:
local in1 = … -- SRC['…'] when wired, else nil
-- …
local in12 = …before the user’s Cairo body. Unwired slots are nil (not 0) so code can do:
local cpu = tonumber(in1) or safe_number('${cpu}', 0)Wire Studio sources or logic only when you intentionally edit the Lua to read those locals. Import does not auto-patch Batman/Skyrim-style HUDs onto the graph.
Heavy hand-written themes remain mostly Custom Lua after import — editable as a text escape hatch, with companion scripts as separate Custom Script nodes.
- Shell scripts in the theme tree are listed; paths are recorded on Custom Script nodes.
-
script_body(Inline script) is preloaded for files under a size limit so the Properties panel can edit them like Custom Lua code. - At Build, non-empty Inline script wins over Script path; body is written under
scripts/(shebang added if missing). -
Self-caching scripts (
CACHE_FILE,sensors.cache,weather.cache, …) run under their original basename with no stdout wrapper, so the cache name the Lua expects stays intact. - Cache directory lines in scripts are patched toward the theme’s
.runtime-cachelayout when recognized. - Companion
.conffiles next to scripts (e.g.sensors.conf,weather.conf) are copied intoscripts/when present. -
Unwired daemon Custom Scripts still appear in
start.shpoll loops: pure-Lua HUDs read their caches directly, so the graph may have no edge into those sources.
| Step | Rule |
|---|---|
_layout_import_graph |
Sources in a left column; logic beside them; visuals near draw x/y or cx/cy
|
_collapse_warnings |
Drop noisy “unrecognised” spam; dedupe identical lines; cap list length |
| Ignored TEXT directives | One summary line listing ${name}×count
|
| Escape-hatch note | One summary line stating Custom Lua/Script keep their own logic |
| Situation | Rule |
|---|---|
Unknown ${…} var |
Counted in summary warning; optional placeholder text for top*
|
| Nested complex TEXT | Approximate positions |
| Pure Cairo art | Custom Lua only (+ optional Input 1–12 if you edit the code) |
| Absolute paths to another machine | Survives as strings until path rewrite or manual edit |
| Pixel parity | Target useful migration, then polish in Studio |
| “Why doesn’t wiring a Bar change the Batman HUD?” | Because the HUD is the Custom Lua node; Bars are separate layers unless you wire Inputs and change the Lua |
Approximations appear in ImportResult.warnings — read them after import.
- Fix Canvas size/alignment if needed.
- Treat Custom Lua and Custom Script as the theme’s brain: edit their text for behaviour.
- Confirm Build produces daemon loops for sensors/weather-style scripts; check
.runtime-cacheafter./start.sh. - Optionally wire Custom Lua Input 1–12 and edit the Lua to consume them.
- Re-attach Image nodes only if you want Studio features as an extra layer.
- Live Preview / Build & Install (same pipeline as native).
See also Legacy Import (user-facing summary) and Theme Architecture & Codegen Pipeline.