Files
feresaria/README.md
T

369 lines
13 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.
# Ferese
Ferese is a Wayland scrolling compositor written in Rust with
Smithay. Scrolling columns are the default, tree tiling remains available as an
optional per-workspace mode, and geometry changes use timestamp-driven
animation. See the
[window-manager specification](docs/ferese-window-manager-spec.md) for the
current architecture and milestones.
For a versioned installation alongside Plasma in SDDM, see
[installation and recovery](docs/installation.md). `Super+Shift+E` or
`feresectl exit` logs out immediately; save your work first.
## Development
Install the native dependencies required by Smithay's winit and GLES backends,
then run:
```bash
cargo run -p ferese
```
Pass a client and its arguments after `--` to launch it inside Ferese:
```bash
cargo run -p ferese -- foot
```
Set `RUST_LOG=ferese=debug` for detailed compositor logging.
`Super+F` toggles decorated maximization inside the workspace (bar and outer
gaps remain visible). In scrolling mode this expands the column to full width,
keeps it in the strip, and restores its previous width when toggled off. New
windows open to its right and scroll into focus.
`Super+Shift+F` toggles true fullscreen (no bar or window
decorations). Leaving fullscreen restores the previous maximized/tiled state.
Set `FERESE_TRACE_PERFORMANCE=1` to emit five-second per-output summaries under
the `ferese::render` tracing target. Summaries include rendered frames, damaged
pixels, average and longest render time, and DRM missed-deadline totals.
The native-client soak runner and its nested/DRM procedure are documented in
[docs/native-soak-testing.md](docs/native-soak-testing.md).
The M7 semantic-effects probe must use a compositor-created private connection.
Build it, then grant only the `effects` capability to that launched process:
```bash
cargo build -p ferese-effects-probe
cargo run -p ferese -- --grant-effects -- target/debug/ferese-effects-probe
```
Add `--preview` to keep a solid popover visible in the nested compositor:
```bash
cargo build -p ferese-effects-probe
cargo run -p ferese -- --backend nested --grant-effects -- \
target/debug/ferese-effects-probe --preview
```
Press `Super+Enter` in the Ferese window to open `foot`, then move or update the
terminal beneath the popover to inspect stacking, rounded clipping, and shadows. Stop the preview with `Ctrl+C` in the host terminal.
To verify that the private global is absent from the public Wayland socket:
```bash
cargo run -p ferese -- target/debug/ferese-effects-probe --expect-hidden
```
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.
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.
Use `--preview --regions` with the effects probe to inspect two cards over a
patterned background, including the sharp gap between them.
```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 an edge-to-edge 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, where workspace indicators become available.
The active workspace's window list appears on the left, with click-to-focus
and a highlighted active window; status controls and day/time sit on the
right. The 28px bar has square screen edges, 19px icons, and no border or drop
shadow. Window spacing uses the workspace outer gap; `top_bar_window_gap` under
`[theme.geometry]` adds optional extra space (default 0). Solid and translucent
shell surfaces also omit outlines. The dark startup fallback matches the material palette.
The shell decodes wallpaper in parallel with startup and prefers 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.
Keyboard and direct-session touchpad settings are applied at startup:
```toml
[input]
focus_follows_mouse = false
xkb_layout = "us"
xkb_variant = ""
xkb_options = []
repeat_rate = 25
repeat_delay_ms = 600
[input.touchpad]
tap = true
natural_scroll = true
disable_while_typing = true
```
Touchpad settings apply to libinput devices in the direct DRM session. In the
nested backend, the host compositor remains responsible for physical touchpad
configuration.
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
and on hotplug; live configuration reload remains deferred.
Commands are argv arrays and are started directly, without a shell. The
default `Super+Enter` binding runs the built-in `terminal = ["foot"]` command:
```toml
[commands]
terminal = ["foot", "--app-id", "terminal"]
[[bindings]]
keys = "Super+Enter"
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:
```toml
[[bindings]]
keys = "Super+Q"
disabled = true
```
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.
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:
```toml
[[window_rules]]
app_id = "org.example.Editor"
workspace = 3
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.
`feresectl` controls the running compositor through the same-user socket at
`$XDG_RUNTIME_DIR/ferese/control.sock`. For example:
```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
```
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.
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:
```bash
FERESE_ENABLE_INPUT_METHOD=1 cargo run -p ferese
```
`Ctrl+Alt+Escape` always releases an active client shortcut inhibitor.
Keyboard-shortcut inhibition is hidden unless a trusted VM or remote-desktop
session explicitly enables it:
```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.