Add panel-wide styles and the Morph hub (#26)
Panel appearance now applies to the whole panel, with seven styles: Floating, Capsules, Notch, Edge to edge, Fused islands, Adaptive and Morph. - Share composition, geometry, and motion through the renderer-independent `ferese-panel` crate, including native materials, input regions, and Settings previews. - Add the Morph hub with media, calendar, notifications, controls, workspace previews, hover feedback, and attached mode. Keep recording and low-battery status visible and respect window clearance. - Cache workspace preview geometry, draw thumbnails directly, centralize Morph transitions, and keep rendering settings local to each shell instance. - Put Record Screen in the Morph header and show the display control only when an external monitor is connected. Update panel documentation, the desktop screenshot, and native check style names. Local validation included 660 compositor tests, 191 shell tests, isolated preview-cache checks, GPU Morph captures at 1×/1.25×/1.5×, formatting, and Clippy with warnings denied. The final header change passed all 23 Morph tests. Release workflow jobs are skipped for this PR.
This commit is contained in:
1 parent
42c3b290dd
commit
e22f0ebef9
131 files changed
+12562
-1634
No files matched your search
+58
-176
@@ -40,15 +40,16 @@ output-profile "docked" {
|
||||
```
|
||||
|
||||
Lists use repeated `panel`, `group`, `item`, `binding`, `window-rule`,
|
||||
`output-profile`, `output`, `note`, and `autostart` nodes. Bindings take their keys,
|
||||
action, and argument positionally; profiles, outputs, and notes take a positional
|
||||
name, match, or ID. Panels, groups, and items use positional IDs, while autostart
|
||||
`output-profile`, `output`, and `autostart` nodes. Bindings take their keys,
|
||||
action, and argument positionally; profiles and outputs take a positional
|
||||
name or match. Panels, groups, and items use positional IDs, while autostart
|
||||
commands use positional arguments. Other fields can be properties or child nodes,
|
||||
but 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.
|
||||
Settings preserves comments and untouched configuration content when editing,
|
||||
while normalizing indentation. Panel item annotations belong in an explicit
|
||||
`metadata` section; unrecognized built-in options are rejected.
|
||||
|
||||
The Settings sidebar groups pages under Desktop, Interaction, and System, with
|
||||
Motion under Windows and Shortcuts under Keyboard & mouse. Search includes both
|
||||
@@ -57,10 +58,10 @@ views and opens the matching setting directly.
|
||||
## Saving and validation
|
||||
|
||||
Settings saves text when you press Enter or leave the field, and sliders when
|
||||
you release them. Undo restores the previous save. Reload reads external edits
|
||||
without merging unfinished drafts. Wallpaper browsing needs `zenity`, but you
|
||||
can also enter a path directly.
|
||||
Settings keeps `config.kdl.settings-backup` before saving.
|
||||
you release them, keeping `config.kdl.settings-backup` before each save. Use
|
||||
Undo to restore the previous save, or Reload to read external edits without
|
||||
merging unfinished drafts. To browse for a wallpaper, install `zenity`; you can
|
||||
also enter its path directly.
|
||||
|
||||
File edits reload automatically, including atomic editor saves, so changes to
|
||||
appearance, wallpaper, motion, input, bindings, rules, layouts, displays,
|
||||
@@ -93,10 +94,10 @@ cancels pending pairing. Passwords are sent to NetworkManager, not saved in KDL;
|
||||
pairing keys are managed by BlueZ. These controls affect the system even when
|
||||
Settings is opened with 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.
|
||||
The tables below give built-in defaults; your configuration or the packaged
|
||||
example may override them. Dimensions use logical pixels unless noted, and
|
||||
numbers must be finite. Omit optional values rather than writing `null`, use
|
||||
`#RRGGBB` or `#RRGGBBAA` for colors, and keep the live config within 60 KiB.
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -186,6 +187,10 @@ immediate. Reduced motion takes precedence over `enabled #true`; setting
|
||||
`speed 0` is invalid. These settings control Ferese's animations, not animations
|
||||
inside other applications.
|
||||
|
||||
Morph animates its shape with its own spring and fades between views, while
|
||||
following the shared speed and reduced-motion policy; see the
|
||||
[panel guide](panel-configuration.md#morph) for its states and size controls.
|
||||
|
||||
Shell animations sample motion on each surface's redraw, paced by its Wayland
|
||||
frame callbacks. They request animation frames only while moving.
|
||||
Menus, modals, notifications and hover fades use this path instead of a fixed
|
||||
@@ -326,6 +331,7 @@ is set.
|
||||
| `theme.colors` key | Default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `surface-base` | `"#111821"` | Material/card base color |
|
||||
| `surface-raised` | `"#1E2530"` | Raised surfaces, including the Morph hub |
|
||||
| `text-primary` | `"#F4F7FB"` | Main text |
|
||||
| `text-muted` | `"#8793A2"` | Secondary text |
|
||||
| `accent` | `"#3D7BE6"` | Active controls and solid focus ring |
|
||||
@@ -339,14 +345,14 @@ Filled controls choose a contrasting text color automatically.
|
||||
| `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 and interaction backgrounds; fractional radii are preserved; 0 makes them square |
|
||||
| `control-gap` | number ≥ 0 | `12` | Right-side control spacing |
|
||||
| `shell-radius` | number ≥ 0 | `14` | Shell surfaces and controls, apart from panel shapes; fractional radii are preserved; 0 makes them square |
|
||||
| `control-gap` | number ≥ 0 | `12` | Shared control spacing token; panel spacing belongs to its groups |
|
||||
|
||||
| Section / key | Type | Default | Meaning |
|
||||
| --- | --- | --- | --- |
|
||||
| `theme.surface.bar.background` | color | `"#1C202EF2"` | Shell fallback background; compositor materials use `surface-base` |
|
||||
| `theme.surface.bar.text-primary` | color | `"#F0F3FA"` | Bar text/icons |
|
||||
| `theme.surface.bar.text-muted` | color | `"#AAB4C7"` | Inactive bar foreground |
|
||||
| `theme.surface.bar.background` | color | `"#111821"` | Regular panel background color; Morph uses `surface-raised` |
|
||||
| `theme.surface.bar.text-primary` | color | `"#F4F7FB"` | Panel text/icons |
|
||||
| `theme.surface.bar.text-muted` | color | `"#8793A2"` | Inactive panel foreground |
|
||||
| `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 |
|
||||
@@ -808,116 +814,43 @@ intentionally turning off the last working one.
|
||||
|
||||
## Panel composition
|
||||
|
||||
Ferese shows one panel on each output, at the top by default. You can use the
|
||||
default arrangement or define a `panel` block with its own geometry, surface
|
||||
defaults, ordered groups, and item settings.
|
||||
Ferese uses one panel configuration across all outputs, with each output laying
|
||||
out its own workspace controls and focused-window title. Open **Settings →
|
||||
Panel & Shell** to choose a style and position, then **Edit panel** to arrange
|
||||
items in Start, Center and End groups. The composition preview stays visible
|
||||
while you edit, and changes save automatically.
|
||||
|
||||
In Settings → **Panel & Shell**, **Panels** contains the position, background,
|
||||
size, spacing, and corner-radius controls. Choose **Edit panel** to open
|
||||
**Arrange**, where you can organize groups and items while the composition preview
|
||||
stays visible above the independently scrolling editor and inspector.
|
||||
**Back to Panels** returns to the panel controls.
|
||||
Choose style, opacity and corners for the whole panel; groups control layout and
|
||||
spacing. The available styles are Floating, Capsules, Notch, Edge to edge,
|
||||
Fused islands, Adaptive and Morph. Capsules and Fused islands join neighboring
|
||||
**groups within a zone**, so a zone with one group remains a single island.
|
||||
Adaptive follows window state independently on each output, while Morph combines
|
||||
the panel into a centered hub with expandable workspace, media and status views.
|
||||
|
||||
Use **Position** to choose Top or Bottom, or set `edge "top"` or `edge "bottom"`
|
||||
inside the KDL panel block. Menus and notifications open toward the desktop, with
|
||||
window clearance and **Edge margin** following that screen edge. Panel dimensions
|
||||
live in a separate `geometry` block, so appearance changes do not resize the
|
||||
panel. Its fields are `height` (24–128), `edge-margin`, `side-margins`, and
|
||||
`window-clearance` (0–4096), plus `inner-padding` (0–64); their defaults are 28, 0,
|
||||
0, 0, and 12 logical pixels respectively.
|
||||
|
||||
Each group has an **Add item** menu. Select a control to open its inspector, where
|
||||
you can change visibility, overflow, preferred size, and placement, or remove the
|
||||
item. To reorder it, use the **Up / Down** arrow buttons or drag its handle; dragging
|
||||
also lets you move it to another group, and dropping into an empty zone creates a
|
||||
group. Hidden controls remain in the editor with faded icons and labels. These
|
||||
changes use the existing save and Undo controls, and `ferese-settings --page bar`
|
||||
opens the page directly.
|
||||
|
||||
Use **Add group** in Start, Center, or End to create an empty group, then select
|
||||
its name to change placement, surface, spacing, and padding. Arrow buttons reorder
|
||||
groups within a zone; before removing a group, move or remove its controls.
|
||||
|
||||
The **Background** presets set the panel fill and default group surface together:
|
||||
Continuous uses `solid` for the panel and `none` for groups, while Islands uses
|
||||
`none` for the panel and `island` for groups. Applying either preset clears group
|
||||
surface overrides while keeping your arrangement intact.
|
||||
|
||||
Use **Default group surface** to choose what groups inherit, or select Default,
|
||||
None, Inset, or Island in an individual group's inspector. None adds no fill,
|
||||
Inset wraps the padded content in a rounded surface, and Island adds a full-height
|
||||
surface with island padding. Groups on a filled panel use a subtle local tint,
|
||||
allowing arrangements such as a continuous panel with one media island or
|
||||
navigation and status islands around an undecorated title. With mixed settings,
|
||||
neither preset button is selected.
|
||||
|
||||
**Group borders** controls the outlines of all groups and is off by default,
|
||||
while opacity and corner radii apply across the panel.
|
||||
|
||||
**Background opacity** overrides shell opacity for the panel background in either
|
||||
arrangement, without fading controls or changing popups. **Use shell opacity**
|
||||
restores inheritance.
|
||||
|
||||
Choose **Customize corners** to override the radius for the whole panel,
|
||||
including its groups. The four sliders control top left, top right, bottom right,
|
||||
and bottom left, saving each change when you release the slider.
|
||||
|
||||
In KDL, pixel values follow CSS shorthand: one value sets all corners; two set
|
||||
top-left/bottom-right and top-right/bottom-left; three set
|
||||
top-left, top-right/bottom-left, and bottom-right; four run clockwise from
|
||||
top-left. For example, `4px 8px 12px 16px` gives each corner a different radius.
|
||||
Values must be finite and nonnegative; percentages and elliptical `/` syntax are
|
||||
not supported. Radii are clamped to half the shorter surface dimension.
|
||||
|
||||
At zero edge margin, panel backgrounds reach the selected screen edge with square
|
||||
corners where they touch it, without changing the saved radii. Islands preserve
|
||||
the gaps between groups, while Continuous fills the whole panel.
|
||||
|
||||
**Side margins** moves the left and right ends inward together over a range of
|
||||
0–4096 px. The shell limits the requested inset for each output using measured
|
||||
content widths: controls may compact, but the inset stops before causing
|
||||
additional overflow. As content grows or the output gets smaller, the applied
|
||||
inset shrinks to make room. If the controls cannot fit even at zero margin, the
|
||||
panel uses its normal overflow behavior.
|
||||
|
||||
The panel follows the shell radius unless you set an override, which stays in
|
||||
place when the shell radius changes. **Use shell radius** clears that override
|
||||
without changing the arrangement; **Remove custom panel** restores both the
|
||||
default arrangement and its inherited radius.
|
||||
|
||||
Dragging changes the drop hint until release, then saves the complete move once.
|
||||
Escape, focus loss, and release outside a drop target cancel without saving.
|
||||
|
||||
The composition preview follows your draft and adapts to the Settings window's
|
||||
width using sample content with every service available. Select a preview control
|
||||
to edit that instance, or use the chevron to reveal overflow items. Browsing and
|
||||
selection do not save anything: the first edit saves the composition and the
|
||||
change together. The preview shares the shell's sizing resolver, while live
|
||||
service state and exact vertical styling can differ.
|
||||
Most panels default to 36 logical pixels high, Morph to 34, and detached styles
|
||||
use 8-pixel margins unless your configuration overrides them. The packaged
|
||||
configuration includes its own geometry overrides. For the complete options and
|
||||
examples, see the [panel configuration guide](panel-configuration.md).
|
||||
|
||||
```kdl
|
||||
panel "main" {
|
||||
surface "none"
|
||||
group-surface "island"
|
||||
geometry { height 30; edge-margin 6; side-margins 18; window-clearance 4; }
|
||||
border #false
|
||||
background-opacity 0.85
|
||||
edge "top"
|
||||
style "floating"
|
||||
geometry { height 36; edge-margin 8; window-clearance 4; }
|
||||
start {
|
||||
group "navigation" {
|
||||
item "overview" kind="overview" overflow="never"
|
||||
item "workspaces" kind="workspaces" overflow="never"
|
||||
item "workspaces" kind="workspaces" style="dots" overflow="never"
|
||||
}
|
||||
}
|
||||
center {
|
||||
group "title" {
|
||||
surface "none"
|
||||
item "title" kind="focused-window" overflow="never"
|
||||
}
|
||||
}
|
||||
end {
|
||||
group "status" {
|
||||
item "network" kind="network" overflow="always"
|
||||
item "audio" kind="audio"
|
||||
item "quick-settings" kind="quick-settings"
|
||||
item "battery" kind="battery" percentage=#true
|
||||
item "clock" kind="clock" representation="compact"
|
||||
}
|
||||
@@ -925,64 +858,11 @@ panel "main" {
|
||||
}
|
||||
```
|
||||
|
||||
Start, center, and end contain ordered groups of item instances. Their IDs must
|
||||
be unique within the panel, contain 1–128 ASCII letters/digits or `-_.:@`, and not
|
||||
start with `_`. Exactly one panel can be configured, without per-output overrides.
|
||||
|
||||
Built-in kinds are `overview`, `workspaces`, `focused-window`, `media`,
|
||||
`quick-settings`, `network`, `audio`, `recording`, `notifications`, `battery`,
|
||||
`clock`, and `display-mode`. Availability still follows the associated service
|
||||
or hardware. Duplicate kinds are allowed when their IDs differ; clock instances
|
||||
currently share the same clock format and timezone.
|
||||
|
||||
| Scope / key | Values / default | Meaning |
|
||||
| --- | --- | --- |
|
||||
| Panel `surface` | `solid` (default), `none` | Full panel fill or transparent space between decorated groups |
|
||||
| Panel `group-surface` | `none` (default), `inset`, `island` | Inherited group surface |
|
||||
| Group `surface` | omit to inherit, `none`, `inset`, `island` | Override surface independently of other groups |
|
||||
| Panel `geometry` | height 28, edge/side margins 0, window clearance 0, inner padding 12 | Dimensions independent of the theme |
|
||||
| Panel `border` | boolean; default `false` | Show group outlines |
|
||||
| Panel `corner-radius` | optional px string, e.g. `"4px 8px"` | Override shell radius for all panel surfaces |
|
||||
| Zone `spacing` | 0–64; default 8 | Gap between groups |
|
||||
| Panel `background-opacity` | optional 0–1; inherits shell opacity | Override panel background opacity in either arrangement |
|
||||
| Groups per panel | at most 31 | Reserves one of the 32 material regions for overflow |
|
||||
| Group `spacing` | 0–64; default 1 | Gap between items |
|
||||
| Group `padding` | two integers 0–32; default `2 3` | Vertical and horizontal inner padding |
|
||||
| Group `island-padding` | 0–32; default 4 | Additional horizontal padding for islands |
|
||||
| Item `visible` | boolean; default `true` | Allow the item when available |
|
||||
| Item `overflow` | `auto` (default), `never`, `always` | Move when needed, keep visible, or place in overflow |
|
||||
| Item `priority` | integer 0–100; default 50 | Lower priorities yield space first |
|
||||
| Item `representation` | omit, `wide`, `compact`, `icon` | Preferred supported form; smaller forms may be used |
|
||||
| Item `gap-before` | 0–64; unset | Override the preceding gap within a group |
|
||||
| Item `metadata` | optional section | Custom data preserved by the editor; no shell behavior |
|
||||
| Workspaces `style` | `numbers`, `dots` (default), `tabs`, `window-stacks`, `app-icons` | Workspace indicators; choose in the Workspaces item inspector |
|
||||
| Battery `percentage` | boolean; default `true` | Include percentage in its full form |
|
||||
| Focused window `visible` | boolean; default `true` | Include the title |
|
||||
|
||||
Media and clock support all three representations. Battery with a percentage
|
||||
supports `wide` and `icon`; other controls keep their existing form. Unsupported
|
||||
preferences use the kind's normal form. The title can shrink and ellipsize;
|
||||
workspace controls scroll within their allocation. The panel itself does not scroll.
|
||||
|
||||
Workspace indicators keep the same width as their state changes. Dots use a pill
|
||||
for the active workspace, a filled dot for an occupied workspace, and an outline
|
||||
for an empty one. Tabs show workspace names, window stacks show up to three
|
||||
window outlines, and app icons show up to two distinct running applications.
|
||||
Hover for the workspace name and window count. Active transitions follow the
|
||||
animation and reduced-motion settings. Explicitly set `style="numbers"`
|
||||
to retain numbered indicators.
|
||||
|
||||
Item-specific settings belong to their kind: Workspaces uses `style`, Battery
|
||||
uses `percentage`, and Focused window uses the shared `visible` flag. Unrecognized
|
||||
options, including misspellings, are rejected, so custom data belongs in an
|
||||
explicit `metadata` section such as
|
||||
`item "clock" kind="clock" { metadata { note "Desk clock"; }; }`.
|
||||
|
||||
The center stays screen-centered. When controls cannot fit, lower-priority items
|
||||
adapt first, with definition order breaking ties. The overflow chevron appears
|
||||
before the end controls and opens displaced items through their usual menus.
|
||||
`never` moves to overflow only when the mandatory controls cannot fit. A surface
|
||||
narrower than the chevron's padded minimum clips that control.
|
||||
If you omit the panel block, Ferese uses its default composition; if you write
|
||||
one, its groups and items define the contents, and empty zones stay empty. Only
|
||||
one panel block is accepted, and group and item IDs must be unique within it.
|
||||
Use `edge "bottom"` to move the same arrangement to the bottom, with popups
|
||||
opening toward the desktop and edge-relative corners mirroring vertically.
|
||||
|
||||
## Status controls
|
||||
|
||||
@@ -992,15 +872,16 @@ narrower than the chevron's padded minimum clips that control.
|
||||
| `low-battery-threshold` | integer 0–100 | `20` | Warning-color threshold |
|
||||
| `settings-command` | argument array | `["ferese-settings"]` | Settings launcher; `[]` hides the action |
|
||||
|
||||
Configure panel surfaces in **Panel & Shell** or in the `panel` block above.
|
||||
Transparent gaps pass clicks through. Group islands use panel opacity and corner
|
||||
radii; changing their surface leaves modal transparency and window clearance
|
||||
unchanged. Island padding belongs to each group and applies only to islands.
|
||||
Configure the panel in **Panel & Shell** or its KDL block, as described in the
|
||||
[panel guide](panel-configuration.md). The panel's appearance applies to every
|
||||
group, while popup and notification backgrounds follow the shared shell theme.
|
||||
Transparent gaps between islands pass clicks through to the windows beneath.
|
||||
|
||||
### Now Playing
|
||||
|
||||
The media control on the right shows artwork, the track title and a play/pause
|
||||
button. Click the artwork or title to open playback controls for MPRIS players.
|
||||
The Media item can show artwork, the track title and a play/pause button wherever
|
||||
you place it in the panel. Click the artwork or title to open playback controls
|
||||
for MPRIS players; Morph presents playback in its Music view.
|
||||
Scroll over the control to change the player's volume, or
|
||||
middle-click to raise its window when supported. The menu has previous/next
|
||||
buttons, a seek slider when supported, and a player chooser. It uses the same
|
||||
@@ -1140,7 +1021,8 @@ and blur masks. Small controls cap the radius to fit their size; circles and pil
|
||||
keep circular outlines. The measured profile has small tangent and curvature
|
||||
discontinuities at its internal segment joins. Window rounding remains under
|
||||
Settings → Windows. Shell rounding comes from `theme.geometry.shell-radius`,
|
||||
which defaults to 14 px, with an optional corner override for each panel.
|
||||
which defaults to 14 px. Panel corners follow their selected style and height,
|
||||
with optional overrides in the [panel configuration](panel-configuration.md#background-outline-and-corners).
|
||||
|
||||
## X11 support (xwayland-satellite)
|
||||
|
||||
|
||||
Reference in new issue
Block a user