Add desktop widgets and streamline documentation
This commit is contained in:
1 parent
c63af64d87
commit
8dc895448d
25 files changed
+2724
-3686
No files matched your search
+213
-379
@@ -1,327 +1,171 @@
|
||||
# Configuration and session reference
|
||||
# Configuration
|
||||
|
||||
## Live configuration
|
||||
Edit `~/.config/ferese/config.toml` (or `$XDG_CONFIG_HOME/ferese/config.toml`),
|
||||
or open **Control Center → Settings**. Start with the [example](../packaging/config.toml).
|
||||
All supported configuration sections are listed below; [desktop widgets](desktop-widgets.md)
|
||||
covers the complete clock and sticky-note fields separately.
|
||||
|
||||
`ferese-settings` opens the native settings application, also available from
|
||||
Control Center → Settings after installation. It includes appearance presets,
|
||||
wallpaper selection, menu bar geometry, window behavior, motion, keyboard/mouse,
|
||||
custom shortcut editing, login items, and existing display profiles. Changes save
|
||||
automatically; text fields save on Enter or when leaving the field. Sliders save
|
||||
when released. Settings also refreshes after external config edits, preserving
|
||||
active drafts. Display profiles, touchpad options, and login items update live.
|
||||
Wallpaper browsing uses Zenity's native GTK file chooser (`zenity` must be
|
||||
installed); entering an image path directly remains available.
|
||||
## Saving and validation
|
||||
|
||||
The app validates changes with `ferese --check-config PATH` before atomically
|
||||
replacing your file, preserves comments and unrelated keys, and keeps a
|
||||
`config.toml.settings-backup`. Undo restores the previous save; external edits
|
||||
require Reload before saving. Search filters settings categories. To preview
|
||||
against a disposable config without changing your desktop config:
|
||||
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.toml.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
|
||||
cargo build -p ferese -p ferese-settings --locked
|
||||
target/debug/ferese-settings --config /tmp/ferese-settings-preview.toml
|
||||
feresectl reload-config # reload with error feedback
|
||||
ferese --check-config PATH # validate without applying
|
||||
ferese-settings --config PATH # edit a separate preview config
|
||||
```
|
||||
|
||||
The GUI is not a replacement for every advanced config option: adding display
|
||||
profiles, arranging outputs, new shortcut definitions, and window rules remain
|
||||
in `config.toml`. Theme presets update palette and focus-gradient colors without
|
||||
replacing custom rules, bindings, wallpaper, or layout settings.
|
||||
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.
|
||||
|
||||
New installations float Settings by default. To do the same in an existing
|
||||
config, add a `[[window_rules]]` entry with `app_id = "dev.ferese.Settings"`
|
||||
and `floating = true`.
|
||||
## Layout
|
||||
|
||||
Saving `~/.config/ferese/config.toml` (or `$XDG_CONFIG_HOME/ferese/config.toml`)
|
||||
reloads it automatically. Atomic editor saves are supported and bursts are
|
||||
debounced. Invalid edits keep the last working compositor and shell config;
|
||||
the rejection is logged. Idle watching does not reread the file.
|
||||
| `[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 |
|
||||
|
||||
Use `feresectl reload-config` to reload manually and report validation errors.
|
||||
Live sources are limited to 60 KiB for safe delivery over the private protocol.
|
||||
| `[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 |
|
||||
|
||||
Appearance, fonts, wallpaper, animations, keybindings, keyboard layout/repeat,
|
||||
gaps, scrolling focus policy/default widths, and bar geometry reload live.
|
||||
Wallpaper decoding stays off the render thread and keeps the old image until
|
||||
the replacement is ready. Layout-mode changes convert existing workspaces;
|
||||
default-width changes update columns using the previous default, preserving
|
||||
custom widths. Changed window rules are reapplied to existing matching windows.
|
||||
Output profiles and touchpad changes apply immediately. Display changes retain
|
||||
output/workspace identity; configurations with no usable output are rejected.
|
||||
The compositor and shell need one initial update/restart to enable this feature.
|
||||
`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.
|
||||
|
||||
## Session services and locking
|
||||
## Motion
|
||||
|
||||
`[[autostart]]` entries run after the compositor's public socket is ready:
|
||||
| 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 |
|
||||
|
||||
```toml
|
||||
[[autostart]]
|
||||
command = ["awari"]
|
||||
enabled = true
|
||||
restart = true
|
||||
## Appearance
|
||||
|
||||
[[autostart]]
|
||||
command = ["swayidle", "-w", "timeout", "600", "ferese-lock", "before-sleep", "ferese-lock", "lock", "ferese-lock"]
|
||||
restart = true
|
||||
```
|
||||
| Section / key | Type | Default | Meaning |
|
||||
| --- | --- | --- | --- |
|
||||
| `appearance.corner_radius` | number ≥ 0 | `14` | Shell material/card 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 | omitted | Wallpaper image path |
|
||||
| `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 |
|
||||
|
||||
Services are session-owned, reaped, and restarted with a five-second retry delay.
|
||||
They receive the correct public Wayland display without private shell privileges.
|
||||
Nested previews skip them unless `nested = true` is explicitly configured.
|
||||
Autostart changes reconcile live: unchanged commands keep their processes,
|
||||
new/enabled items start, and disabled/removed commands stop without blocking rendering.
|
||||
Run foreground daemons here, not commands that fork themselves into the background.
|
||||
| `[theme.colors]` key | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `surface_base` | `"#111821"` | Material/card base color |
|
||||
| `text_primary` | `"#F4F7FB"` | Main text |
|
||||
| `text_muted` | `"#7F8A98"` | Secondary text |
|
||||
| `accent` | `"#5B8CFF"` | Active controls and solid focus ring |
|
||||
| `border` | `"#FFFFFF18"` | Unfocused window border |
|
||||
| `shadow` | `"#00000055"` | Window shadow color |
|
||||
|
||||
Ferese implements `ext-session-lock-v1`. While locked, only lock surfaces over an
|
||||
opaque fallback are rendered, normal input/shortcuts and IPC are blocked, and
|
||||
screencopy is unavailable. DRM confirmation waits for safe page flips on active
|
||||
outputs. A missing/crashed locker leaves the session locked; it is not an unlock.
|
||||
`ferese-lock` runs swaylock/swaylock-effects with optional
|
||||
`~/.config/ferese/swaylock.conf`, waiting for lock confirmation before daemonizing.
|
||||
The compositor authenticates no passwords itself; authentication belongs to the locker.
|
||||
Validate password unlock in a disposable nested session before enabling automatic
|
||||
locking on a primary session. Crash recovery currently requires ending that session
|
||||
from another VT; there is deliberately no unauthenticated IPC unlock.
|
||||
| `[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 |
|
||||
| `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 | `0` | Bar corners |
|
||||
| `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 | Material opacity defaults to `0.78`; 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 |
|
||||
|
||||
## Configuration reference
|
||||
Solid materials omit blur; translucent materials blur behind the surface color.
|
||||
True fullscreen removes decorations. Focus transitions never scale the content.
|
||||
|
||||
Ferese reads `$XDG_CONFIG_HOME/ferese/config.toml`, or
|
||||
`~/.config/ferese/config.toml` when `XDG_CONFIG_HOME` is unset. New scrolling
|
||||
columns use half the viewport by default. To make every newly opened column use
|
||||
the full viewport width:
|
||||
|
||||
```toml
|
||||
[scrolling]
|
||||
default_column_width = "full"
|
||||
```
|
||||
|
||||
`default_column_width = 1.0` is equivalent. `Super+M` switches the active
|
||||
workspace between scrolling and tree modes.
|
||||
|
||||
Outer gaps remain visible with one window by default. To intentionally remove
|
||||
them for a lone tiled window:
|
||||
|
||||
```toml
|
||||
[layout]
|
||||
outer_gap = 4.0
|
||||
smart_gaps = true
|
||||
```
|
||||
|
||||
Managed-window borders use theme tokens and overlay the window edge without
|
||||
adding inner padding or changing client geometry:
|
||||
|
||||
```toml
|
||||
[theme.colors]
|
||||
border = "#FFFFFF18"
|
||||
accent = "#5B8CFF"
|
||||
shadow = "#00000055"
|
||||
|
||||
[theme.geometry]
|
||||
border_width = 1.0
|
||||
focus_ring_width = 2.0
|
||||
window_radius = 14.0
|
||||
|
||||
[theme.shadow.soft]
|
||||
offset_y = 4.0
|
||||
blur = 18.0
|
||||
opacity = 0.20
|
||||
|
||||
[theme.material]
|
||||
style = "solid" # solid or translucent
|
||||
blur_radius = 12.0 # logical pixels; translucent only, 0 disables blur
|
||||
|
||||
[appearance.inactive_dim]
|
||||
enabled = true # opt-in; disabled by default
|
||||
amount = 0.15 # dark tint over unfocused windows, 0–1; 0 disables
|
||||
duration_ms = 150 # 0 snaps immediately; reduced motion also snaps
|
||||
```
|
||||
|
||||
Inactive dimming follows window focus with a smooth, interruption-safe fade.
|
||||
Focus-ring paint (including gradients) and width use the same `duration_ms`,
|
||||
even when dimming is disabled. Focus changes never scale or move the window.
|
||||
Shell buttons fade their hover tint over 120 ms. Both transitions respect
|
||||
`animations.speed`, `animations.enabled`, and `animations.reduced_motion`;
|
||||
click actions remain immediate and settled hover states do not animate.
|
||||
It keeps window opacity intact, respects animated geometry and rounded corners,
|
||||
and leaves shell bars/popovers untouched. Overview temporarily removes dimming.
|
||||
|
||||
Material roles use the configured surface color and role-specific shadows.
|
||||
Solid is the default. Translucent adds backdrop blur behind the same surface
|
||||
color, without grain, glossy lighting, saturation boosts, or inset highlights.
|
||||
The radius is clamped to 32 logical pixels. A shader/allocation failure falls
|
||||
back to a plain translucent fill. Shell popovers report rounded card regions;
|
||||
their outer padding and gaps stay transparent. Each surface shares one capture
|
||||
across its cards, so cards do not sample already blurred neighboring cards.
|
||||
|
||||
```toml
|
||||
[appearance]
|
||||
corner_radius = 14.0
|
||||
```
|
||||
|
||||
Shell shadows use restrained logical-pixel presets: panel `1/5/4%`, popover
|
||||
and menu `2/8/7%`, HUD `1/4/4%`, and notification/modal `3/10/9%`
|
||||
(vertical offset / blur / opacity). Private effects capabilities
|
||||
remain required; public background-effect requests cannot select these materials.
|
||||
|
||||
Fullscreen windows are borderless and shadowless. Other managed windows use GPU
|
||||
rounded clipping, matching rounded focus rings, and an analytic soft shadow.
|
||||
These effects overlay or surround the allocation without adding client padding.
|
||||
|
||||
Scrolling keeps windows in stable workspace coordinates and animates the
|
||||
viewport only when focus must be revealed. Set
|
||||
`focus_strategy = "center_on_focus"` under `[scrolling]` to center focused
|
||||
columns instead.
|
||||
|
||||
Use `focus_strategy = "paged"` to pack consecutive columns into viewport-sized
|
||||
pages. Half-width columns form pairs, thirds form triples, and full-width
|
||||
columns occupy their own page. Mixed widths and client minimum sizes use their
|
||||
actual allocated widths, including gaps. Focusing within a page keeps it still;
|
||||
crossing a page boundary scrolls to that page. Explicit centering remains in
|
||||
effect until focus changes or the output resizes.
|
||||
|
||||
Scrolling controls use `Super+R` to cycle configured width presets, `Super+C`
|
||||
to center the focused column, `Super+[` to consume the focused window into an
|
||||
adjacent column, and `Super+]` to expel it. `Super+Ctrl+H/J/K/L` resizes in the
|
||||
corresponding direction.
|
||||
|
||||
`Super+Tab` toggles the compositor overview. Its live window previews retain
|
||||
their client surfaces, `Super+H/J/K/L` moves the selection using the presented
|
||||
preview geometry, and clicking a preview activates it without forwarding the
|
||||
selection click to the application.
|
||||
|
||||
The shell provides a configurable libcosmic menu bar backed
|
||||
by the private shell-control connection. Build and preview it nested with:
|
||||
|
||||
```bash
|
||||
cargo build --release -p ferese -p ferese-shell
|
||||
target/release/ferese --backend nested --grant-effects --grant-shell-control -- \
|
||||
target/release/ferese-shell
|
||||
```
|
||||
|
||||
The Ferese mark enters overview. A workspace selector sits on the left;
|
||||
status controls and day/time sit on the right. Bar geometry, spacing, colors
|
||||
and material style are configurable and reload live.
|
||||
|
||||
The compositor decodes wallpaper in parallel with startup. Small shell surfaces prefer the lightweight
|
||||
software renderer, with GPU rendering available as a fallback. Set `ICED_BACKEND=wgpu` to explicitly use GPU
|
||||
rendering for shell content. Use release builds when evaluating startup and
|
||||
animation performance; debug image processing is considerably slower.
|
||||
|
||||
Resize presentation configures the destination once and coordinates the
|
||||
matching client commits with the workspace motion (300 ms maximum wait).
|
||||
Application content stays at native pixel size; animated bounds crop/reveal
|
||||
it rather than stretching text. A resize-only previous-frame snapshot fades
|
||||
out over 80 ms, with a 64 MiB total snapshot budget and automatic release.
|
||||
All monitors share one elapsed-time animation clock, and window content,
|
||||
clips, borders and shadows use the same physical-pixel edges.
|
||||
|
||||
Window borders and focus rings use solid colors by default. Optional linear
|
||||
gradients can be configured independently:
|
||||
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.
|
||||
|
||||
```toml
|
||||
[theme.focus_ring.gradient]
|
||||
from = "#e5c890"
|
||||
to = "#b98d58"
|
||||
angle = 135.0
|
||||
|
||||
# Optional unfocused-window gradient:
|
||||
[theme.border.gradient]
|
||||
from = "#3e3e43"
|
||||
to = "#242429"
|
||||
angle = 90.0
|
||||
```
|
||||
|
||||
Angles are clockwise in window coordinates: 0 is left-to-right and 90 is
|
||||
top-to-bottom. Both endpoints accept `#RRGGBB` or `#RRGGBBAA`. Remove either
|
||||
gradient section to restore its solid `theme.colors.accent` or `border` color.
|
||||
Gradients share the existing rounded-border shader and add no animation or
|
||||
extra render pass. Configuration changes reload live.
|
||||
## Input
|
||||
|
||||
Overview has a horizontally scrollable workspace strip with live window
|
||||
thumbnails and an accent outline on the workspace shown by each output.
|
||||
Click a workspace to change the window grid without leaving overview; click
|
||||
a window to focus it and exit, or press Escape to dismiss. Only the workspace
|
||||
strip has a tinted surface; the window grid sits directly over the wallpaper.
|
||||
Strip labels use `[theme.typography].font_family` and rasterize at output scale.
|
||||
The strip fades independently and preserves its opacity on rapid reversals,
|
||||
including when the selected workspace is empty.
|
||||
| `[input]` key | Type | Default | Meaning |
|
||||
| --- | --- | --- | --- |
|
||||
| `focus_follows_mouse` | boolean | `false` | Focus windows under the pointer |
|
||||
| `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 |
|
||||
|
||||
Ferese renders `[theme.background]` wallpapers directly: `path` selects the
|
||||
image and `mode = "fill"` or `"fit"` controls crop/letterboxing. One decoded
|
||||
image and one texture per GPU context serve every output; resizing requires
|
||||
no image reload or full-screen shell buffers. The launched shell receives
|
||||
`FERESE_COMPOSITOR_WALLPAPER=1` to disable its redundant wallpaper surfaces.
|
||||
When no valid image path is configured, the shell's existing fallback remains.
|
||||
`[input.touchpad]` has three boolean keys, 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.
|
||||
|
||||
Keyboard and direct-session touchpad settings reload live:
|
||||
## Commands and bindings
|
||||
|
||||
```toml
|
||||
[input]
|
||||
focus_follows_mouse = false
|
||||
xkb_layout = "us"
|
||||
xkb_variant = ""
|
||||
xkb_options = []
|
||||
repeat_rate = 25
|
||||
repeat_delay_ms = 600
|
||||
`[commands]` maps arbitrary names to nonempty argument arrays. The built-in
|
||||
`terminal = ["foot"]` can be overridden. Commands run directly, without a shell.
|
||||
|
||||
[input.touchpad]
|
||||
tap = true
|
||||
natural_scroll = true
|
||||
disable_while_typing = true
|
||||
```
|
||||
| `[[bindings]]` key | Type / values | Default |
|
||||
| --- | --- | --- |
|
||||
| `keys` | chord string, e.g. `"Super+Enter"` | required |
|
||||
| `match` | `"keysym"`, `"physical"` | `"keysym"` |
|
||||
| `action` | action name below | required unless disabled |
|
||||
| `argument` | string | required only for actions listed below |
|
||||
| `disabled` | boolean | `false` |
|
||||
|
||||
Touchpad settings apply to libinput devices in the direct DRM session. In the
|
||||
nested backend, the host compositor remains responsible for physical touchpad
|
||||
configuration.
|
||||
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`.
|
||||
|
||||
The direct DRM backend selects the first output profile whose listed monitors
|
||||
are all connected. Match either the connector name reported by `get-outputs`
|
||||
or its persistent EDID-derived identity:
|
||||
|
||||
```toml
|
||||
[[output_profiles]]
|
||||
name = "docked"
|
||||
|
||||
[[output_profiles.outputs]]
|
||||
match = "HDMI-A-1"
|
||||
mode = "[email protected]"
|
||||
scale = 1.6
|
||||
position = [0, 0]
|
||||
|
||||
[[output_profiles.outputs]]
|
||||
match = "eDP-1"
|
||||
enabled = false
|
||||
|
||||
[[output_profiles]]
|
||||
name = "laptop"
|
||||
|
||||
[[output_profiles.outputs]]
|
||||
match = "eDP-1"
|
||||
mode = "2880x1800@120"
|
||||
scale = 1.6
|
||||
position = [0, 0]
|
||||
```
|
||||
|
||||
Unspecified connected outputs remain enabled with their preferred mode, scale
|
||||
`1.0`, normal transform, and automatic horizontal placement. Supported
|
||||
transforms are `normal`, `rotate_90`, `rotate_180`, `rotate_270`, `flipped`,
|
||||
and their rotated flipped variants. Output configuration is applied at startup,
|
||||
on hotplug, and live reload, including modes, scale, transform, and position.
|
||||
|
||||
On DRM, closing the laptop lid disables internal panels when a usable external
|
||||
output is available. With no usable external output, the panel stays enabled;
|
||||
Ferese does not change the system's suspend policy. Workspaces are evacuated
|
||||
to a remaining output without merging their windows, and return to their
|
||||
original output when the lid reopens or a disconnected monitor returns.
|
||||
Normal use of an evacuated workspace does not cancel its automatic return.
|
||||
|
||||
Commands are argv arrays and are started directly, without a shell. The
|
||||
default `Super+Enter` binding runs the built-in `terminal = ["foot"]` command:
|
||||
| Actions | Argument |
|
||||
| --- | --- |
|
||||
| `spawn` | Name in `[commands]` |
|
||||
| `focus`, `move`, `resize` | `"left"`, `"right"`, `"up"`, `"down"` |
|
||||
| `workspace`, `move-to-workspace` | Workspace number string, 1–255 |
|
||||
| `close`, `exit`, `toggle-maximized`, `toggle-fullscreen`, `toggle-layout`, `cycle-column-width`, `center-column`, `consume`, `expel`, `toggle-floating`, `toggle-overview` | None |
|
||||
|
||||
```toml
|
||||
[commands]
|
||||
terminal = ["foot", "--app-id", "terminal"]
|
||||
terminal = ["foot"]
|
||||
|
||||
[[bindings]]
|
||||
keys = "Super+Enter"
|
||||
@@ -329,115 +173,105 @@ action = "spawn"
|
||||
argument = "terminal"
|
||||
```
|
||||
|
||||
A configured binding replaces the built-in binding with the same normalized
|
||||
chord and match mode. Disable a default explicitly with no action:
|
||||
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+E immediate logout.
|
||||
|
||||
```toml
|
||||
[[bindings]]
|
||||
keys = "Super+Q"
|
||||
disabled = true
|
||||
```
|
||||
## Window rules
|
||||
|
||||
Bindings follow the active layout by default. To bind a keyboard position
|
||||
instead, set `match = "physical"` and use an XKB physical key name such as
|
||||
`AD06`. Invalid chords, actions, arguments, duplicate bindings, and missing
|
||||
command references stop startup with an error.
|
||||
| `[[window_rules]]` 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 |
|
||||
|
||||
Initial window rules match `app_id`, exact title, and/or transient status. All
|
||||
matching rules are applied in declaration order; later rules override only the
|
||||
fields they specify. Width or height implies floating placement when `floating`
|
||||
is omitted:
|
||||
|
||||
With `floating = true` and no explicit dimensions, the application chooses its
|
||||
initial size and Ferese centers that size on its workspace's output. Small
|
||||
dialogs are not forced into a workspace-sized container.
|
||||
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.
|
||||
|
||||
```toml
|
||||
[[window_rules]]
|
||||
app_id = "org.example.Editor"
|
||||
workspace = 3
|
||||
app_id = "dev.ferese.Settings"
|
||||
floating = true
|
||||
width = 900.0
|
||||
height = 600.0
|
||||
fullscreen = false
|
||||
```
|
||||
|
||||
Rules are finalized on the first toplevel commit, before its buffer is
|
||||
presented, and are not re-applied when an application later changes its title.
|
||||
## Displays
|
||||
|
||||
`feresectl` controls the running compositor through the same-user socket at
|
||||
`$XDG_RUNTIME_DIR/ferese/control.sock`. For example:
|
||||
`[[output_profiles]]` has a required unique nonempty `name` and one or more
|
||||
`[[output_profiles.outputs]]` entries. The first profile whose listed monitors
|
||||
are connected wins. Find connector names and persistent identities using
|
||||
`feresectl get-outputs`.
|
||||
|
||||
```bash
|
||||
cargo run -p feresectl -- focus left
|
||||
cargo run -p feresectl -- workspace 2
|
||||
cargo run -p feresectl -- get-workspaces
|
||||
cargo run -p feresectl -- get-outputs
|
||||
| `[[output_profiles.outputs]]` 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.
|
||||
|
||||
```toml
|
||||
[[output_profiles]]
|
||||
name = "docked"
|
||||
|
||||
[[output_profiles.outputs]]
|
||||
match = "HDMI-A-1"
|
||||
scale = 1.5
|
||||
position = [0, 0]
|
||||
```
|
||||
|
||||
The v0 IPC slice also supports `move`, `resize`, `move-to-workspace`,
|
||||
`toggle-floating`, `toggle-maximized`, `toggle-fullscreen`, `toggle-layout`, `cycle-column-width`,
|
||||
`center-column`, `consume`, `expel`, `close`, `get-focused-window`, and
|
||||
`get-outputs`. Requests use versioned, 1 MiB-limited length-prefixed JSON. The
|
||||
runtime directory and socket are restricted to modes `0700` and `0600`, and the
|
||||
server rejects peers whose effective UID differs from the compositor's. IPC has
|
||||
a bounded request queue and accepts at most 64 concurrent client connections.
|
||||
`get-outputs` includes disabled-but-connected monitors, connector and persistent
|
||||
identity matchers, current and available modes with refresh rates, fractional
|
||||
scale, transform, logical position and size, and physical dimensions.
|
||||
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.
|
||||
|
||||
Text-input-v3 is available to applications by default. Input-method-v2 is
|
||||
hidden unless the session explicitly opts in, because an input method can
|
||||
request privileged keyboard access. Enable it only when launching a trusted
|
||||
IME for the session:
|
||||
## Status controls
|
||||
|
||||
```bash
|
||||
FERESE_ENABLE_INPUT_METHOD=1 cargo run -p ferese
|
||||
| `[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:
|
||||
|
||||
```toml
|
||||
[[autostart]]
|
||||
command = ["swayidle", "-w", "timeout", "300", "ferese-lock", "before-sleep", "ferese-lock", "lock", "ferese-lock"]
|
||||
```
|
||||
|
||||
`Ctrl+Alt+Escape` always releases an active client shortcut inhibitor.
|
||||
`ferese-lock` uses swaylock/swaylock-effects and optional
|
||||
`~/.config/ferese/swaylock.conf`. Test unlock in a nested preview before enabling
|
||||
automatic locking. A crashed locker leaves the session locked; recovery requires
|
||||
ending the session from another TTY.
|
||||
|
||||
Keyboard-shortcut inhibition is hidden unless a trusted VM or remote-desktop
|
||||
session explicitly enables it:
|
||||
## Optional session protocols
|
||||
|
||||
```bash
|
||||
FERESE_ENABLE_SHORTCUT_INHIBIT=1 cargo run -p ferese
|
||||
```
|
||||
|
||||
The emergency `Ctrl+Alt+Escape` binding remains available while inhibition is
|
||||
active.
|
||||
|
||||
Screen capture is hidden by default. A session that has already made an
|
||||
explicit capture-policy decision can expose screencopy-v1 to its clients with:
|
||||
|
||||
```bash
|
||||
FERESE_ENABLE_SCREENCOPY=1 cargo run -p ferese
|
||||
```
|
||||
|
||||
The current M5 implementation supports one-shot output and region capture into
|
||||
ARGB8888 shared-memory buffers. Cursor overlays are included only when the
|
||||
capture client requests them.
|
||||
|
||||
### Direct DRM session
|
||||
|
||||
Run the hardware backend from a spare TTY, outside another graphical session:
|
||||
|
||||
```bash
|
||||
RUST_LOG=ferese=debug cargo run -p ferese -- --backend=drm -- foot
|
||||
```
|
||||
|
||||
Do not run that command from a terminal inside the active desktop: the direct
|
||||
backend requests control of the seat and primary DRM device. Use
|
||||
Ctrl+Alt+F1–F12 to switch virtual terminals.
|
||||
|
||||
M4 validation requires the direct session to:
|
||||
|
||||
- start `foot` and render the same animated tiling workload as the nested path;
|
||||
- retain keyboard and pointer input;
|
||||
- pause when switching away and redraw after switching back; and
|
||||
- log page-flip timing and any missed presentation deadlines on the reference
|
||||
integrated GPU.
|
||||
|
||||
The direct path creates an independent render pipeline per connected output and
|
||||
rescans connectors on hotplug. Physical unplug/replug acceptance testing on the
|
||||
reference hardware is still pending.
|
||||
These are launch-time environment switches, not TOML keys. Enable only for
|
||||
trusted clients: `FERESE_ENABLE_INPUT_METHOD=1`,
|
||||
`FERESE_ENABLE_SHORTCUT_INHIBIT=1`, `FERESE_ENABLE_SCREENCOPY=1`.
|
||||
Text input is available by default; Ctrl+Alt+Escape releases an active shortcut
|
||||
inhibitor. Use `feresectl --help` for runtime control commands.
|
||||
Reference in new issue
Block a user