programs.trollshell options

programs.trollshell.enable

Whether to enable trollshell — hytte-based Wayland desktop shell.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.enableRecommendedServices

Enable the system daemons trollshell’s optional chips lean on (UPower, power-profiles-daemon, geoclue, plus the polkit agent and the agent-name D-Bus policy). Each is still individually overridable; this is a master switch for the lot. Turning it off leaves a working bar — the chips that back onto a missing daemon simply hide themselves.

Type: boolean

Default:

true

Declared by:

programs.trollshell.enableRecommendedSoftware

Install the optional GNOME desktop apps that pair with the GOA → evolution-data-server stack trollshell reads: GNOME Calendar (a read/write UI for the same calendars trollshell’s Calendar page shows read-only), GNOME Tasks (Endeavour, for the EDS task lists), and GNOME Contacts. Kept separate from enableRecommendedServices because these are heavier GUI apps rather than daemons — turn this off to keep the services + the gnome-control-center account-add UI while dropping the apps. (gnome-control-center itself stays under the services switch, since it’s the essential way to add an account.)

Type: boolean

Default:

true

Declared by:

programs.trollshell.enableSessionExtras

Whether to enable all of the session-integration extras below (fuzzel, the wallpaper daemon, cliphist, portals) as a group. Each is set with mkDefault, so you can still flip an individual one off. The wallpaper daemon is the one selected by programs.trollshell.wallpaper.backend (default swaybg), not hardcoded — set backend = “none” to opt out of daemon management entirely.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.package

The trollshell package to install.

Type: package

Default:

trollshell.packages.${system}.trollshell

Declared by:

programs.trollshell.cliphist.enable

Whether to enable clipboard history (text + images) via home-manager’s services.cliphist, which feeds the Clipboard drawer page.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.controlCenter.enable

Install the trollshell-control-center companion app alongside the shell. It’s the external settings/management window (launchable by its app-id, mov.vibec0re.trollshell.ControlCenter) that speaks to the running shell’s Control session-bus endpoint. Enabled by default; set false to drop it (the shell itself doesn’t depend on it).

Type: boolean

Default:

true

Declared by:

programs.trollshell.controlCenter.package

The trollshell-control-center package to install.

Type: package

Default:

trollshell.packages.${system}.trollshell-control-center

Declared by:

programs.trollshell.fuzzel.enable

Whether to enable the bundled fuzzel launcher config via home-manager’s programs.fuzzel. Bind Mod+D to fuzzel in niri yourself (etc/niri/binds.kdl).

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.nightlight.dayTemp

Daytime color temperature in kelvin (wlsunset -T <dayTemp>). 6500K is neutral daylight (wlsunset’s own default).

Type: signed integer

Default:

6500

Example:

6500

Declared by:

programs.trollshell.nightlight.latitude

Latitude in decimal degrees for wlsunset’s geo (sunrise/sunset) mode (wlsunset -l <latitude>). Optional. When set (together with longitude) it takes precedence over the live location fix, so use it to pin night light to a fixed place, or if you do not run GeoClue2. Leave both null to follow the live fix instead. With neither a fix nor these set, the toggle refuses to start the daemon and logs why. May be given as a float (52.52) or a string (“52.52”).

Type: null or floating point number or string

Default:

null

Example:

52.52

Declared by:

programs.trollshell.nightlight.longitude

Longitude in decimal degrees for wlsunset’s geo mode (wlsunset -L <longitude>). Optional, and only used together with latitude — a half-configured pair is ignored (see latitude). May be a float or a string.

Type: null or floating point number or string

Default:

null

Example:

13.405

Declared by:

programs.trollshell.nightlight.nightTemp

Nighttime color temperature in kelvin (wlsunset -t <nightTemp>). Lower is warmer; 4000K is a gentle warm-white.

Type: signed integer

Default:

4000

Example:

3500

Declared by:

programs.trollshell.plugins

Declarative plugins (#350, launch model #419), keyed by plugin id: each attr drops in without hand-writing a systemd unit. The option renders to a JSON launch-state file (trollshell/plugins.json under XDG config — per-user via home-manager, /etc/xdg via the NixOS module) that the running shell reads at startup, launching each enabled entry as a transient trollshell-plugin-<id> user unit via systemd-run --user (trollshell/src/plugin_launcher.rs; Restart=on-failure, PartOf=graphical-session.target — supervision and session lifetime stay systemd’s job, and the launch env is where #392’s key injection hooks in). Being an attrset of submodules (the standard named-instance pattern), entries merge per-field across modules — a second module can override one field of one plugin (plugins.pet.env.PET_NAME = lib.mkForce "nisse";) or disable it (plugins.pet.enable = false;). The launched plugin dials plugin.sock and registers itself; the control-center’s Plugins tab (#348) starts/stops the transient units live, while enablement stays declared here.

Each bundled plugin ships as its own package in this flake (#558), so package points straight at a hytte-plugin-<id> output — no out-of-tree derivation needed:

plugins.pet.package = trollshell.packages.${system}.hytte-plugin-pet;

The bundled ids are: audio-widget, bar-clock-demo, caw, clock-demo, departures, infobroker, pet, preem-demo, terminal, timer, usage, weather (each output named hytte-plugin-<id>). Their per-plugin runtime knobs go through env / secrets above.

Type: attribute set of (submodule)

Default:

{ }

Example:

{
  # A bundled plugin, wired from this flake's per-plugin package
  # (see the list of ids in the description below):
  pet = {
    package = trollshell.packages.${system}.hytte-plugin-pet;
    env.PET_NAME = "nisse";
  };
}

Declared by:

programs.trollshell.plugins.<name>.enable

Whether the shell launches this plugin at startup (#419). A disabled entry is still declared — written to the launch state as “enabled”: false, so it lists in the control-center’s Plugins tab and can be started manually — it just doesn’t auto-launch. Lets a downstream module switch a single entry off (plugins.pet.enable = false;) without removing its definition.

Type: boolean

Default:

true

Example:

false

Declared by:

programs.trollshell.plugins.<name>.package

The plugin’s package (its out-of-process binary, built on hytte-plugin — never linked into the shell). The shell launches it as a transient trollshell-plugin-<id> user unit via systemd-run --user (#419, trollshell/src/plugin_launcher.rs); once running it dials plugin.sock and speaks the Register handshake itself (trollshell/src/plugins.rs).

Type: package

Declared by:

programs.trollshell.plugins.<name>.env

Environment variables passed to the plugin binary at launch (rendered into the launch-state file’s per-plugin env map and applied as --setenv=K=V by the launcher, trollshell/src/plugin_launcher.rs). This is the non-secret sibling of secrets below and the idiom each bundled plugin reads its config through — so it is how the non-secret runtime knobs are exposed as nix options (#533): set the plugin’s env var here rather than in a shell profile. Values must be strings.

Do NOT put API keys here — the launch-state file is world-readable; use secrets (below) instead, which injects the key from the login keyring at spawn.

A few representative examples (each also readable from the environment directly; the nix option is just the declarative way to set it):

The full inventory — swept from source, all 12 bundled plugins including the ones with zero knobs — is published at https://vibec0re.github.io/trollshell/plugin-env.html (source: docs/plugin-env.md). An absolute URL rather than a relative one because this description is also rendered by nixos-option and man home-configuration.nix, where a relative plugin-env.html link would resolve to nothing.

Precedence for a plugin that also reads a config file (e.g. usage’s ~/.config/trollshell/usage.toml): environment (this option) wins over the file, which wins over the built-in default.

Type: attribute set of string

Default:

{ }

Example:

{
  PET_LLM_MODEL = "google/gemini-3.5-flash";
  PET_NAME = "nisse";
}

Declared by:

programs.trollshell.plugins.<name>.secrets

AI-provider key slots to inject into this plugin at launch (#392). For each slot the shell reads the key stored in your login keyring — managed by the control-center’s AI Keys tab, never written to disk or this config — and passes it to the plugin as the <SLOT>_API_KEY environment variable (e.g. “openrouter” → OPENROUTER_API_KEY), which is exactly the override hytte-ai-providers’ load_key reads first. So an LLM-backed plugin picks the key up with no per-plugin config: plugins.pet.secrets = [ "openrouter" ];. A slot with no stored key is simply skipped (the plugin runs keyless and uses its own fallback); a plugin that doesn’t list a slot never gets that key in its environment. Rotating a key in the control-center relaunches the running plugins that declare it.

Type: list of string

Default:

[ ]

Example:

[
  "openrouter"
]

Declared by:

programs.trollshell.portals.enable

Whether to enable the niri xdg-desktop-portal routing + backends via home-manager’s xdg.portal. You still set XDG_CURRENT_DESKTOP=niri:GNOME yourself.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.recorder.audioByDefault

Whether the screen-recording chip (#403, crates/hytte-services/src/recorder.rs) starts with audio capture armed. This is only the initial value of the in-shell audio toggle, read once at service start; the toggle in Settings still flips it live during a session. Off by default (recordings are silent unless you opt in). When true, sets TROLLSHELL_RECORD_AUDIO=1 for the session; that env var is the override, so leaving this at the default lets a hand-set TROLLSHELL_RECORD_AUDIO still win.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.stats.layout

How the System Stats drawer page arranges its five resource cards (CPU / Memory / Disks / GPU / Services). Sets TROLLSHELL_STATS_LAYOUT for the session, read once at shell startup.

This is the shell’s first purely-cosmetic layout knob (issue #508). The design principle is otherwise “composable, not configurable” — the shell is wired in Rust, not config — so most appearance choices are made in main.rs, not here. The Stats layout is the deliberate exception, blessed on the #508 thread, because the combined and split shapes both have real users.

An unrecognized value falls back to multicolumn (the enum type rejects one at evaluation time; the runtime fallback covers a hand-set env var).

Type: one of “combined”, “multicolumn”, “split”

Default:

"multicolumn"

Example:

"combined"

Declared by:

programs.trollshell.swaybg.enable

Whether to enable the bundled swaybg wallpaper user unit standalone, which reads its argument list from ~/.config/trollshell/swaybg.args (the Appearance drawer page writes it — per-output images and rotation supported). Gently deprecated in favor of programs.trollshell.wallpaper.backend = “swaybg” + enableSessionExtras: the extras bundle now starts the swaybg unit when backend is “swaybg” (the default). This option is still honored — set it true to run the swaybg unit without the rest of the bundle. Two wallpaper daemons can never run at once because backend selects exactly one, but if you set this true AND backend = “awww”, swaybg and awww would both start; don’t. Leave it false unless you specifically want swaybg without the bundle.

Type: boolean

Default:

false

Example:

true

Declared by:

programs.trollshell.systemd.enable

Run trollshell as a systemd user service.

Type: boolean

Default:

true

Declared by:

programs.trollshell.systemd.target

Systemd user target the shell service binds to.

Type: string

Default:

"graphical-session.target"

Example:

"niri-session.target"

Declared by:

programs.trollshell.wallpaper.backend

Which wallpaper daemon trollshell manages for the session, and what the Appearance picker tells to reload. One enum value drives the daemon wiring and the reloadCommand default together, so two daemons can never run at once — backend selection is structural, not an assertion.

The legacy programs.trollshell.swaybg.enable (home-manager) and a hand-set wallpaper.reloadCommand both still work and take precedence; they are gently deprecated in favor of this enum.

Type: one of “swaybg”, “awww”, “none”

Default:

"swaybg"

Example:

"awww"

Declared by:

programs.trollshell.wallpaper.reloadCommand

Shell command the Appearance picker runs (via sh -c) after writing ~/.config/trollshell/wallpaper.path, to tell your wallpaper daemon to reload. A {} in the command is replaced with the chosen path, shell-quoted. Sets TROLLSHELL_WALLPAPER_RELOAD_CMD for the session.

Use the {} placeholder, not a $VAR reference: this value is delivered through sessionVariables, which expands $-references at login (before the path exists), so awww img "$TROLLSHELL_WALLPAPER_PATH" would expand to awww img "". The path is still also exported as TROLLSHELL_WALLPAPER_PATH for daemons that read it directly.

Defaults follow wallpaper.backend: null for swaybg (restart the bundled swaybg unit — the shell’s built-in default) and none, and awww img {} for awww. Set it explicitly to override; an explicit value wins over the per-backend default.

Type: null or string

Default:

# per backend: null (swaybg/none) or "awww img {}" (awww)

Example:

"awww img {}"

Declared by:

programs.trollshell.weather.fallbackCity

City the weather widget falls back to when geolocation is unavailable. Sets TROLLSHELL_WEATHER_CITY for the session. Leave null to rely on geoclue (enabled system-side by the NixOS module).

Type: null or string

Default:

null

Example:

"Berlin"

Declared by:

programs.trollshell.weather.geoclue.enable

Enable geoclue2 auto-location for the weather widget (and future location-aware features).

Type: boolean

Default:

true

Declared by:

programs.trollshell.weather.geoclue.providerUrl

WiFi-positioning backend for geoclue. Mozilla Location Service (geoclue’s historical default) shut down in 2024; beaconDB is the community successor.

Type: string

Default:

"https://api.beacondb.net/v1/geolocate"

Declared by: