How it works
Fenn starts your program, the two of you trade JSON lines, and Fenn draws whatever views you send.
The loop
- Fenn looks for plugin folders when it starts, runs each plugin's program in that plugin's own folder, and sends it a
hellomessage. - Your program sends views: trees of components such as
row,text,buttonandring. Send a new tree whenever something changes; the latest one replaces the previous one. - When the user interacts with a control, Fenn sends an
eventwith that control'sid. - A plugin has a tile in the grid and, if it wants one, a full page that opens when the tile is clicked.
- Your program can also put a badge in the collapsed pill, light its tile, open the notch, copy text or open a URL.
| Direction | Channel | Carries |
|---|---|---|
| Fenn to plugin | stdin | hello, event, hotkey, files, layout, theme, shutdown |
| Plugin to Fenn | stdout | tile, page, badge, active, show, copy, open, log |
| Plugin to log | stderr | Anything. It goes to Fenn's log and shows on the tile if the plugin stops. |
Every message is one JSON object on one line, in UTF-8.
Live and poll modes
live (default)Fenn starts your program once and keeps it running. Use it for timers, sockets, animation, or anything that keeps state. If the program exits, Fenn restarts it up to three times a minute.
pollFenn runs your program, reads what it printed, and waits. It runs it again after
interval seconds, or right away when the user clicks something. Each run gets 30 seconds.In poll mode, the event that caused the run is in the FENN_EVENT environment variable. A whole poll plugin can be six lines of PowerShell:
powershell
# plugin.toml: mode = "poll", interval = 30,
# run = ["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "battery.ps1"]
$b = Get-CimInstance Win32_Battery
@{ type = 'ring'; value = $b.EstimatedChargeRemaining / 100
label = "$($b.EstimatedChargeRemaining)%"; tooltip = 'Battery' } |
ConvertTo-Json -CompressIf you print a single component (anything whose
type isn't a message type), Fenn uses it as the tile. In poll mode the output can be one JSON document, even pretty-printed, or one message per line.When things go wrong
- A line that isn't valid JSON, or a message with a missing field, is skipped and logged with the reason, for example
bad "button" view: missing field id. - If a live plugin exits, Fenn restarts it after two seconds, up to three times a minute. After that the tile shows Stopped · click to restart, and hovering over it shows the error and the last lines of stderr.
- Fenn draws unknown component types as nothing, so a plugin written for a newer Fenn still works in an older one.