Files
feresaria/docs/configuration.md
T

416 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Configuration
Edit `~/.config/ferese/config.kdl` (or `$XDG_CONFIG_HOME/ferese/config.kdl`),
or open **Control Center → Settings**. Start with the [example](../packaging/config.kdl).
All supported configuration sections are listed below; [desktop widgets](desktop-widgets.md)
covers the complete clock and sticky-note fields separately.
## KDL syntax
Sections use nested braces, values follow their names, and booleans are `#true`
or `#false`. Multiple values represent arrays. Hyphenated keys are preferred;
underscore spellings remain accepted. Enum values retain their documented spelling.
A newline or semicolon ends each node. Comments use `//` or `/* ... */`.
For example:
```kdl
input {
repeat-rate 30
touchpad {
swipe-threshold 80
}
}
commands {
terminal "foot"
}
binding "Super+Enter" "spawn" "terminal"
binding "Swipe3Up" "toggle-overview"
binding "Swipe3Down" disabled=#true
output-profile "docked" {
output "HDMI-A-1" {
scale 1.5
position 0 0
}
}
```
Repeated `binding`, `window-rule`, `output-profile`, `output`, `note` and
`autostart` nodes describe lists of settings. Bindings accept positional
keys/action/argument; profiles, outputs and notes accept a positional name,
match or ID. Other fields can be properties or child nodes. Autostart accepts
its command as positional arguments. Duplicate fields are rejected.
The dotted paths in the reference tables below describe nested sections.
Settings preserves comments and custom fields when editing, while normalizing
indentation. Runtime configuration uses KDL only. KDL parsing requires Rust 1.95
or newer to build.
## Saving and validation
Settings saves automatically: text on Enter/focus loss, sliders when released.
Undo restores the previous save; Reload picks up external edits without merging
unfinished drafts. Wallpaper browsing needs `zenity`; a path can also be entered.
Settings keeps `config.kdl.settings-backup` before saving.
File edits reload automatically, including atomic editor saves. Invalid changes
keep the last working configuration. Appearance, wallpaper, motion, input,
bindings, rules, layouts, displays, widgets and login items update live.
```sh
feresectl reload-config # reload with error feedback
ferese --check-config PATH # validate without applying
ferese-settings --config PATH # edit a separate preview config
```
Defaults below are built-in defaults, not your personal or packaged overrides.
Dimensions are logical pixels unless noted; numbers must be finite. Optional
values are omitted, not `null`. Colors use `#RRGGBB` or `#RRGGBBAA`.
Live config is limited to 60 KiB.
## Layout
| `layout` key | Type / values | Default | Meaning |
| --- | --- | --- | --- |
| `mode` | `"scrolling"`, `"tree"` | `"scrolling"` | Workspace layout |
| `inner_gap` | number ≥ 0 | `10` | Between windows |
| `outer_gap` | number ≥ 0 | `4` | Around workspace edges |
| `smart_gaps` | boolean | `false` | Remove outer gaps for one tiled window |
| `scrolling` key | Type / values | Default | Meaning |
| --- | --- | --- | --- |
| `default_column_width` | proportion > 0; or `"full"` | `0.5` | Width of new columns |
| `focus_strategy` | `"minimal"`, `"center_on_focus"`, `"paged"` | `"minimal"` | Viewport movement on focus |
| `width_presets` | array of widths | `[0.3333333333333333, 0.5, 0.6666666666666666, "full"]` | Super+R cycle; empty uses defaults |
`minimal` scrolls only to reveal the focused window. `center_on_focus` centers
it. `paged` packs columns into viewport-sized pages: halves form pairs, thirds
form triples; mixed widths and client minimum sizes determine actual boundaries.
Changing default width preserves manually resized columns.
## Motion
| Section / key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `animations.enabled` | boolean | `true` | Enable motion |
| `animations.reduced_motion` | boolean | `false` | Disable animated motion |
| `animations.speed` | number > 0 | `1` | Higher is faster; `0.75` is slower |
| `animations.spring.mass` | number > 0 | `1` | Window-motion spring mass |
| `animations.spring.stiffness` | number > 0 | `700` | Spring stiffness |
| `animations.spring.damping` | number ≥ 0 | `53` | Spring damping |
| `animations.viewport_spring.mass` | number > 0 | `1` | Scrolling spring mass |
| `animations.viewport_spring.stiffness` | number > 0 | `320` | Scrolling stiffness |
| `animations.viewport_spring.damping_ratio` | number > 0 | `1` | `1` is critically damped |
## Appearance
Settings → Appearance offers six presets: **Ferese Blue** (default),
**Monochrome**, **Gruvbox**, **Dracula**, **Ayu Light**, and **Monokai**.
The two-row gallery previews each palette on a miniature desktop; a checkmark
identifies the active preset.
Ferese Blue uses the README logo's `#3D7BE6`. Each preset coordinates surfaces,
text, menu-bar colors, borders and the focus ring. Ayu Light also switches native
Settings controls to light styling. Presets preserve wallpaper, typography,
geometry and opacity settings; colors remain individually editable.
The community palettes are desktop adaptations with text shades adjusted for
readability. Sources: [Gruvbox](https://github.com/morhetz/gruvbox),
[Dracula](https://github.com/dracula/visual-studio-code),
[Ayu](https://github.com/ayu-theme/ayu-colors), and
[classic Monokai](https://github.com/microsoft/vscode/blob/main/extensions/theme-monokai/themes/monokai-color-theme.json).
Marketplace install counts informed the shortlist; they are not a measurement
of desktop users. Monochrome and Gruvbox replace similar blue palettes to keep
these six visually distinct.
| Section / key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `appearance.corner_radius` | number ≥ 0 | unset | Legacy fallback for shell radius |
| `appearance.inactive_dim.enabled` | boolean | `false` | Dim unfocused windows |
| `appearance.inactive_dim.amount` | number 0–1 | `0.15` | Darkening strength |
| `appearance.inactive_dim.duration_ms` | number ≥ 0 | `150` | Dimming and focus-ring transition; 0 snaps |
| `theme.typography.font_family` | string | system sans-serif | Shell, Settings and overview font |
| `theme.background.path` | string | bundled Ferese wallpaper | Wallpaper image path; an existing selection overrides the default |
| `theme.background.mode` | `"fill"`, `"fit"` | `"fill"` | Crop or letterbox |
| `theme.material.style` | `"solid"`, `"translucent"` | `"solid"` | Shell background material |
| `theme.material.blur_radius` | number ≥ 0 | `12` | Translucent backdrop blur, capped at 32; 0 disables |
| `theme.colors` key | Default | Meaning |
| --- | --- | --- |
| `surface_base` | `"#111821"` | Material/card base color |
| `text_primary` | `"#F4F7FB"` | Main text |
| `text_muted` | `"#8793A2"` | Secondary text |
| `accent` | `"#3D7BE6"` | Active controls and solid focus ring |
| `border` | `"#FFFFFF18"` | Unfocused window border |
| `shadow` | `"#00000055"` | Window shadow color |
Ferese derives the text and icon color for filled accent controls from the
configured theme. It keeps the configured text color when it reaches a 4.5:1
contrast ratio; otherwise it chooses black or white. The same rule is shared by
native dialogs, settings selections, and notification badges. Hover, pressed,
and disabled accent-button states use the same policy. Small filled controls
resolve accent transparency against their theme surface so wallpaper cannot
make their labels unreadable. No separate per-application color setting is needed.
The target follows [normal-text contrast guidance](https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html).
| `theme.geometry` key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `border_width` | number ≥ 0 | `1` | Window border thickness |
| `focus_ring_width` | number ≥ 0 | `2` | Focused border thickness |
| `window_radius` | number ≥ 0 | `14` | Managed-window corners, independent of the shell |
| `shell_radius` | number ≥ 0 | `14` | All shell surfaces, cards, widgets and interaction backgrounds; 0 makes them square |
| `top_bar_height` | number > 0 | `28` | Menu-bar height |
| `top_bar_margin_top` | integer ≥ 0 | `0` | Space above bar |
| `top_bar_window_gap` | integer ≥ 0 | `0` | Clearance below bar |
| `top_bar_margin_horizontal` | integer ≥ 0 | `0` | Bar side margins |
| `top_bar_radius` | number ≥ 0 | unset | Legacy fallback for shell radius |
| `panel_padding` | number ≥ 0 | `12` | Bar inner padding |
| `control_gap` | number ≥ 0 | `12` | Right-side control spacing |
| Section / key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `theme.surface.bar.background` | color | `"#1C202EF2"` | Shell fallback background; compositor materials use `surface_base` |
| `theme.surface.bar.opacity` | number 0–1 | omitted | Translucent bar background opacity, including blur; defaults to `0.78`. Text/icons stay opaque; 0 and 1 skip blur. Fallback retains background alpha |
| `theme.surface.bar.text_primary` | color | `"#F0F3FA"` | Bar text/icons |
| `theme.surface.bar.text_muted` | color | `"#AAB4C7"` | Inactive bar foreground |
| `theme.surface.popover.opacity` | number 0–1 | `0.96` | Shell popover fill alpha |
| `theme.shadow.soft.offset_y` | number | `4` | Window shadow vertical offset |
| `theme.shadow.soft.blur` | number ≥ 0 | `18` | Window shadow softness |
| `theme.shadow.soft.opacity` | number 0–1 | `0.20` | Window shadow strength |
Solid materials omit blur; translucent materials blur behind the surface color.
True fullscreen removes decorations. Focus transitions never scale the content.
Optional `theme.focus_ring.gradient` and `theme.border.gradient` use the same
keys: required `from` and `to` colors, and `angle` (number, default `0`). Angles
are clockwise: 0 is left-to-right, 90 top-to-bottom. Omit the gradient section
for solid `accent` or `border` colors.
```kdl
theme {
focus-ring {
gradient {
from "#e5c890"
to "#b98d58"
angle 135.0
}
}
}
```
## Input
| `input` key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `focus_follows_mouse` | boolean | `false` | Focus windows under the pointer without raising them; click to raise |
| `xkb_layout` | nonempty string | `"us"` | XKB layout |
| `xkb_variant` | string | `""` | XKB variant |
| `xkb_options` | string array | `[]` | XKB options |
| `repeat_rate` | integer > 0 | `25` | Repeats per second |
| `repeat_delay_ms` | integer ≥ 0 | `600` | Delay before repeat |
The touchpad device keys are booleans, all defaulting to `true`: `tap`,
`natural_scroll` and `disable_while_typing`. These apply to DRM devices; nested
previews use the host's physical input settings.
Three-finger swipes navigate on release: up goes to the next workspace on the
current monitor, down to the previous; left focuses the window to the right,
and right focuses the window to the left. Workspace swipes skip workspaces owned
by other monitors and stop at the first/last workspace. Cancelled, short and
diagonal swipes do nothing. Navigation pauses while locked, during
window grabs, or when an application inhibits shortcuts.
Assign swipes in **Settings → Shortcuts** using the same actions and arguments as
keyboard bindings. Choose a "Customize swipe" button to add an override. The
gesture keys are `Swipe3Up`, `Swipe3Down`, `Swipe3Left`, and `Swipe3Right`; 4 or 5
fingers are also supported. Changes reload live:
```kdl
binding keys="Swipe3Up" action="toggle-overview"
binding keys="Swipe3Left" action="move" argument="left"
binding keys="Swipe3Down" disabled=#true
```
`spawn` uses a named entry from `commands`, just like keyboard shortcuts. To
disable a direction in Settings, set its action to `none` and leave Argument
empty. In KDL, `disabled=#true` removes the default binding. Swipes do not use
keyboard modifiers or physical key matching. The trigger is automatically
recognized from its name. Gesture navigation uses native touchpad events in a
hardware session.
Adjust recognition distance in **Settings → Keyboard & mouse**, or with
`swipe-threshold 80` under `input.touchpad` (integer 16–1000 logical pixels).
## Commands and bindings
`commands` maps arbitrary names to nonempty argument arrays. The built-in
`terminal "foot"` can be overridden. Commands run directly, without a shell.
| `binding` key | Type / values | Default |
| --- | --- | --- |
| `keys` | chord or gesture, e.g. `"Super+Enter"`, `"Swipe3Up"` | required |
| `match` | `"keysym"`, `"physical"` | `"keysym"` |
| `action` | action name below | required unless disabled |
| `argument` | string | required only for actions listed below |
| `disabled` | boolean | `false` |
Modifiers: `Super`/`Logo`/`Mod4`, `Ctrl`/`Control`, `Alt`, `Shift`.
Keys use XKB keysyms (`Enter`, letters, `[`/`]`) or physical XKB names (`AD06`).
A binding replaces the same normalized chord/match mode. Duplicate bindings are
invalid. A disabled binding must omit `action` and `argument`.
| Actions | Argument |
| --- | --- |
| `spawn` | Name in `commands` |
| `focus`, `move`, `resize` | `"left"`, `"right"`, `"up"`, `"down"` |
| `workspace`, `move-to-workspace` | Workspace number string, 1–255 |
| `workspace-next`, `workspace-previous` | None; next/previous workspace on this monitor |
| `none` | None; ignore this trigger |
| `close`, `exit`, `toggle-maximized`, `toggle-fullscreen`, `toggle-layout`, `cycle-column-width`, `center-column`, `consume`, `expel`, `toggle-floating`, `toggle-overview` | None |
```kdl
commands {
terminal "foot"
}
binding keys="Super+Enter" action="spawn" argument="terminal"
```
Defaults: Super+Enter terminal; Super+Q close; Super+H/J/K/L focus;
Super+Shift+H/J/K/L move; Super+Ctrl+H/J/K/L resize; Super+1–9 workspace;
Super+Shift+1–9 move to workspace; Super+R width cycle; Super+C center;
Super+[/] consume/expel; Super+F maximize; Super+Shift+F fullscreen;
Super+M layout; Super+Shift+Space floating; Super+Tab overview;
Super+Shift+S area screenshot; Print Screen whole-screen screenshot;
Super+Shift+E immediate logout.
The screenshot shortcut runs `ferese-screenshot`: drag to select an area, or
press Escape to cancel. Captures open in Satty for annotation. Press Enter to
save the edited PNG under your Pictures directory in `Screenshots` and copy it
to the clipboard; Escape discards the capture. It requires `grim`, `slurp`,
`satty`, and `wl-copy` (from `wl-clipboard`). Override the `screenshot` command
to use another screenshot tool.
Print Screen runs `ferese-screenshot --full` and captures all enabled outputs
without a selector. Fn+PrtSc works when the keyboard emits the Print Screen key;
Fn is handled by the keyboard firmware. Override `screenshot-full` to customize
this command. Both modes open Satty with the same save and copy workflow.
## Window rules
| `window-rule` key | Type | Default / meaning |
| --- | --- | --- |
| `app_id` | nonempty string | Optional exact match; case-insensitive, `.desktop` suffix ignored |
| `title` | nonempty string | Optional exact, case-sensitive match |
| `transient` | boolean | Optional parent-dialog match |
| `workspace` | integer > 0 | Leave placement unchanged |
| `floating` | boolean | Leave placement unchanged |
| `width`, `height` | numbers > 0 | Application-chosen floating size |
| `fullscreen` | boolean | Leave fullscreen state unchanged |
At least one matcher is required; supplied matchers must all match. Rules apply
in order, with later fields overriding earlier ones. Dimensions imply floating
when `floating` is omitted. Floating apps without dimensions choose their own
size and open centered on the output. Title changes do not trigger new rules;
config rule changes apply to existing windows.
```kdl
window-rule app-id="dev.ferese.Settings" floating=#true
```
## Displays
`output-profile` has a required unique nonempty `name` and one or more
`output-profile → output` entries. The first profile whose listed monitors
are connected wins. Find connector names and persistent identities using
`feresectl get-outputs`.
| `output-profile → output` key | Type | Default |
| --- | --- | --- |
| `match` | nonempty connector or persistent identity string | required; unique within profile |
| `enabled` | boolean | `true` |
| `mode` | `"WIDTHxHEIGHT"` or `"WIDTHxHEIGHT@HZ"` | Preferred mode |
| `scale` | number > 0 | `1` |
| `transform` | enum below | `"normal"` |
| `position` | `[integer, integer]` | Automatic horizontal placement |
Transforms: `normal`, `rotate_90`, `rotate_180`, `rotate_270`, `flipped`,
`flipped_90`, `flipped_180`, `flipped_270`. Unspecified connected displays stay
enabled with defaults. Disabling every usable output is rejected.
```kdl
output-profile name="docked" {
output match="HDMI-A-1" scale=1.5 {
position 0 0
}
}
```
With a usable external display, closing the lid disables internal panels.
Workspaces move to a remaining display and return when their original output
returns. Ferese does not change the system's suspend policy.
## Status controls
| `status` key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `battery_percentage` | boolean | `true` | Show percentage beside icon |
| `low_battery_threshold` | integer 0–100 | `20` | Warning-color threshold |
| `settings_command` | argument array | `["ferese-settings"]` | Settings launcher; `[]` hides the action |
## Login items and locking
| `autostart` key | Type | Default | Meaning |
| --- | --- | --- | --- |
| `command` | nonempty argument array | required | Foreground process, not a self-daemonizing command |
| `enabled` | boolean | `true` | Start service |
| `restart` | boolean | `true` | Restart after exit, with a five-second retry delay |
| `nested` | boolean | `false` | Also run in nested previews |
Unchanged services keep running on reload; removed/disabled items stop. To lock
after five minutes and before sleep:
```kdl
autostart {
command "swayidle" "-w" "timeout" "300" "ferese-lock" "before-sleep" "ferese-lock" "lock" "ferese-lock"
}
```
`ferese-lock` is the native PAM-authenticated locker. It follows your wallpaper,
colors, font and shell corner radius. Its command returns successfully only after
the compositor confirms the lock; the UI keeps running until authentication
succeeds. `--foreground` keeps the command attached to its UI process.
Use `ferese-lock --preview` for an ordinary window that never locks or checks a
password. See [Native locker](locking.md) for setup and verification. Test real
unlock in a nested compositor before enabling automatic locking. A crashed
locker leaves the session locked; recovery requires ending that session from
another TTY.
## Optional session protocols
These are launch-time environment switches, not KDL keys. Enable only for
trusted clients: `FERESE_ENABLE_INPUT_METHOD=1`,
`FERESE_ENABLE_SHORTCUT_INHIBIT=1`, `FERESE_ENABLE_SCREENCOPY=1`.
The installed session launcher enables screencopy for screenshots unless
`FERESE_ENABLE_SCREENCOPY=0` is explicitly set in its environment.
Text input is available by default; Ctrl+Alt+Escape releases an active shortcut
inhibitor. Use `feresectl --help` for runtime control commands.
## Notifications
Settings → Notifications controls popups, Do Not Disturb, and the default timeout. See [Notifications](notifications.md) for KDL options and app behavior.
A single-output session starts with workspace 1. Numbered workspace shortcuts create
workspaces on demand; switching forward past the last workspace also creates the
next one when the current workspace contains windows. Empty workspaces are
cleaned up automatically, keeping at most one empty workspace in addition to
any empty workspace currently shown on another display. Additional displays
receive their own workspace.
Shell rounding is controlled in Settings → Appearance → Shell corner radius.
Small controls cap the radius to fit their size. Window rounding remains under
Settings → Windows. `theme.geometry.shell_radius` takes precedence over the old
`appearance.corner_radius` and then `theme.geometry.top_bar_radius` keys; when
none are set, the shell uses 14 px. Legacy clock/note radius fields no longer
override shell rounding.