Help us shape the future of Go! Take the 2026 Go Developer Survey

shell

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: BSD-3-Clause Imports: 81 Imported by: 0

Documentation

Overview

Package shell holds the bar model: its retained tree, its widgets, and the projection from service and Niri state into that tree.

Index

Constants

View Source
const (
	// MaxRuns caps the styled spans one body produces.
	MaxRuns = 256
	// MaxMarkupDepth caps nesting. Past it the body is treated as plain text.
	MaxMarkupDepth = 16
	// MaxLinkBytes caps one link target.
	MaxLinkBytes = 2 << 10
)

Notification bodies carry the freedesktop markup subset: <b>, <i>, <u>, <a href>, <img> and line breaks. The body is another process's text, so the parser is bounded everywhere it could grow and never renders a tag it does not know.

View Source
const BarGap = 4

BarGap is the outer gap between the screen edge and the painted body.

View Source
const BarHeight = 48

BarHeight is the nominal bar height token. It is not a Wayland dimension: the painted body is BarHeight-2*BarGap and the surface is BarGap + body, so the exclusive zone is 44 for the default 48/4 pair.

Variables

This section is empty.

Functions

func ActiveGroupCard

func ActiveGroupCard(g activeGroup, now time.Time, expanded bool, raster *ui.Image, allowLinks bool, tr translateFunc) *ui.Node

ActiveGroupCard is one Current-tab group. Actions come from the newest member. Expand lists up to 10 members.

func ExpandedNotificationCard

func ExpandedNotificationCard(n protocol.Notification, raster *ui.Image, allowLinks bool, measure ui.MeasureText, wrap func(string) []string) *ui.Node

ExpandedNotificationCard is a toast whose body is wrapped over several lines after a vertical drag.

func HistoryCard

func HistoryCard(e protocol.HistoryEntry, now time.Time, raster *ui.Image, allowLinks bool, tr translateFunc) *ui.Node

HistoryCard builds one closed history row. A right-pinned remove control is present when the pinned service accepts history.remove.

func NotificationCard

func NotificationCard(n protocol.Notification, raster *ui.Image, allowLinks bool, measure ui.MeasureText) *ui.Node

NotificationCard builds one active toast. raster is the already decoded icon, or nil for the glyph tile. measure packs action pills into rows; nil stacks them one per row.

Types

type Badge

type Badge struct {
	Label string
	Tone  BadgeTone
}

type BadgeTone

type BadgeTone string
const (
	BadgeOfficial  BadgeTone = "official"
	BadgeCommunity BadgeTone = "community"
	BadgeSource    BadgeTone = "source"
	BadgeWarning   BadgeTone = "warning"
	BadgeLocal     BadgeTone = "local"
)

type Bar

type Bar struct {
	// contains filtered or unexported fields
}

Bar owns the model, the retained tree, the text renderer and style, and one buffered invalidation channel, for exactly one output.

UpdateNiri, Handle, and rendering arrive from different goroutines. The mutex is held only while copying or changing state; shaping and painting happen after the state has been copied out.

func New

func New(connector string) (*Bar, error)

New builds a bar from the built-in defaults for one connector.

func NewWithTheme

func NewWithTheme(theme Theme, policy config.Bar, connector string) (*Bar, error)

NewWithTheme builds a bar from resolved theme tokens, a bar policy, and the connector whose Niri state it reads.

func (*Bar) Configure

func (b *Bar) Configure(logicalWidth, logicalHeight, scale120 int) error

Configure records a new logical size and scale from the Wayland owner.

func (*Bar) Handle

func (b *Bar) Handle(event wayland.Event) bool

Handle applies a pointer event and reports whether the model changed. A click counts only when the press and the release land on the same node, so the press target is recorded and compared on release.

func (*Bar) Invalidations

func (b *Bar) Invalidations() <-chan struct{}

Invalidations is the stand-alone seam for a bar no registry has adopted; proofs and tests own it and never close it. An adopted bar routes its invalidations through the registry instead (see onPublish).

func (*Bar) Layout

func (b *Bar) Layout(width, height int) error

Layout arranges the three sections at the logical configure size.

func (*Bar) Overflow

func (b *Bar) Overflow() ui.BarOverflow

Overflow reports what the last layout could not place, per section.

func (*Bar) Render

func (b *Bar) Render(pixels []byte, width, height, stride int) error

Render paints the arranged tree into the physical buffer.

type BrowseQuery

type BrowseQuery struct {
	Text, Source, Category string
	HideInstalled          bool
	Sort                   SortKey
	Desc                   bool
}

type Calendar

type Calendar struct {
	Weeks [][]calCell
}

type Card

type Card struct {
	Title          string
	Byline         string
	Description    string
	Badges         []Badge
	Screenshot     store.MediaKey
	ScreenshotPath string
	Glyph          string
	Action         StoreAction
	Reason         string
}

type Color

type Color = render.Color

Color is the painter's colour type, re-exported so components name one type.

type Detail

type Detail struct {
	ID               string
	Title            string
	Author           string
	Category         string
	Glyph            string
	Version          string
	ReleaseRef       store.ReleaseRef
	License          string
	Source           string
	SourceBadge      string
	CatalogCommit    string
	SHA256Prefix     string
	Description      string
	Readme           string
	Homepage         string
	ReleaseNotes     string
	Capabilities     []string
	RequiredCommands []string
	Screenshot       store.MediaKey
	ScreenshotPath   string
	Badges           []Badge
	Action           StoreAction
	Reason           string
	NeedsConsent     bool
	StartImmediately bool
	InstalledVersion string
	ConsentLines     []string
}

type Joints

type Joints struct {
	Left, Right           int
	FlushLeft, FlushRight bool
}

Joints is how an attached panel meets the bar: the concave wedge beside each side of its attached edge, and whether a side sits flush on the screen edge instead, curving into it past its far corner.

func (Joints) Flush

func (j Joints) Flush() bool

Flush reports whether either side sits on the screen edge.

type LockState

type LockState struct {
	Running       bool
	Acquired      bool
	RespawnedUsed bool
	ExitCode      int
}

type Margins

type Margins struct{ Top, Bottom, Left, Right int }
type Menu struct {
	// contains filtered or unexported fields
}

Menu is an in-panel dropdown. It is not a Wayland surface: the open list is a child region of the already-mapped panel.

A picker is the same control over a list too long to read whole: it draws a filter well above its options and narrows them as they are typed. index and cursor stay addresses in the full option list however narrow the drawn list becomes, so a selection made through a filter commits the option the user pointed at rather than the row it happened to occupy.

func NewMenu

func NewMenu(options []string, index int) *Menu

func NewPicker

func NewPicker(options, values []string, index int) *Menu

NewPicker builds a menu that filters. values may be nil, in which case each option writes itself.

func (m *Menu) Cancel()
func (m *Menu) Edit(fn func(*ui.Field)) bool

Edit applies one edit to the filter well and re-narrows the list. The menu owns the field so the drawn rows can never disagree with the text above them.

func (m *Menu) Filtering() bool

Filtering reports whether this menu is a picker. The panel asks before routing text at it, and before treating space as the accept key.

func (m *Menu) Handle(key uint32) bool

Handle routes keys while the menu is open. Escape cancels without changing the committed value. Returns false when the menu is closed so the panel can take Escape, and false for the keys a picker's well should take as text rather than as commands.

func (m *Menu) Index() int
func (m *Menu) Next()
func (m *Menu) Node() *ui.Node
func (m *Menu) Open()
func (m *Menu) Opened() bool
func (m *Menu) PickAt(n *ui.Node, x, y int) bool

PickAt moves the cursor to the option under the point and reports whether it found one. A picker's first child is its filter well, and a press there is not a choice.

func (m *Menu) Prev()
func (m *Menu) RowAt(n *ui.Node, x, y int) int

RowAt returns the option row under a point, or -1. A picker's filter field is the first child and is not an option.

func (m *Menu) Select() int
func (m *Menu) Value() string

type OSDManager

type OSDManager struct {
	// contains filtered or unexported fields
}

func (*OSDManager) Show

func (m *OSDManager) Show(v OSDView)

func (*OSDManager) Visible

func (m *OSDManager) Visible() bool

type OSDView

type OSDView struct {
	Kind  string
	Level int
	Muted bool
	Text  string
	On    bool
}

OSDView is one OSD payload. Level is 0..100 for metered kinds; Muted is audio mute or a stopped player; Text is a media title or a layout name; On is a toggle's state or a playing player.

type Palette

type Palette struct {
	Surface                 Color
	SurfaceDim              Color
	SurfaceBright           Color
	SurfaceContainerLowest  Color
	SurfaceContainerLow     Color
	SurfaceContainer        Color
	SurfaceContainerHigh    Color
	SurfaceContainerHighest Color
	SurfaceVariant          Color
	OnSurface               Color
	OnSurfaceVariant        Color

	Primary              Color
	OnPrimary            Color
	PrimaryContainer     Color
	OnPrimaryContainer   Color
	Secondary            Color
	OnSecondary          Color
	SecondaryContainer   Color
	OnSecondaryContainer Color
	Tertiary             Color
	OnTertiary           Color
	TertiaryContainer    Color
	OnTertiaryContainer  Color

	Error            Color
	OnError          Color
	ErrorContainer   Color
	OnErrorContainer Color

	Outline          Color
	OutlineVariant   Color
	InverseSurface   Color
	InverseOnSurface Color
	InversePrimary   Color
	Shadow           Color
	Scrim            Color
	SurfaceTint      Color
}

Palette is the parsed Material role set for one resolved theme. It carries the roles the shell paints with; the fixed accents stay in theme.Tokens, where the application template catalogue reads them, because no surface has a use for a role that holds one tone across light and dark.

type PaletteSummary

type PaletteSummary struct {
	Slug   string
	Name   string
	Err    string // why the file is unusable; empty when it loads
	Active bool
}

PaletteSummary is one saved palette as the list and the IPC verbs show it.

type PanelHost

type PanelHost struct {
	// contains filtered or unexported fields
}

PanelHost is one open panel: two surfaces' callbacks, content tree, focus, leases, and reveal state.

type PanelID

type PanelID uint8

PanelID identifies one process-wide auxiliary panel instance.

const (
	PanelClock PanelID = iota
	PanelMonitor
	PanelSession
	PanelSettings
	PanelLauncher
	PanelPlugin
	PanelNotifications
	PanelWallpaper
	PanelAudio
	PanelControlCenter
	PanelNetwork
	PanelBluetooth
	PanelWeather
	PanelClipboard
	PanelPluginStore
	PanelFiles
	PanelTerminalArt
	PanelOnboarding
)

func (PanelID) String

func (p PanelID) String() string

type PanelSet

type PanelSet struct {
	// contains filtered or unexported fields
}

PanelSet tracks one open output per panel ID. Registry owns synchronization.

func (*PanelSet) Close

func (ps *PanelSet) Close(p PanelID)

func (*PanelSet) Output

func (ps *PanelSet) Output(p PanelID) (uint32, bool)

func (*PanelSet) Toggle

func (ps *PanelSet) Toggle(p PanelID, output uint32) ToggleResult

type Placement

type Placement struct {
	BarEdge      string
	Output       ui.Rect
	BarZone      int
	Gap, Padding int
	Panel        ui.Rect
	Align        string
	// AnchorX and AnchorY are the logical centre of the triggering widget.
	// Zero means unset; Align then centres along the bar's main axis.
	AnchorX, AnchorY int
	// CenterY centres the panel on the cross axis inside the remaining work
	// area: Settings, the launcher and the clipboard float.
	CenterY bool
	// Detached keeps a panel off the bar, Gap away from it with no joints:
	// islands paint no ground to join, and an output without a bar has none.
	Detached bool
	// BarShape, BarGap and BarRadius describe the bar an attached panel joins,
	// and Fillet is the joint radius. Together they say where the bar's
	// straight edge ends on each side, which bounds each joint.
	BarShape          string
	BarGap, BarRadius int
	Fillet            int
	// Overlap is how far an attached panel tucks under the bar's edge, so
	// no seam of wallpaper opens between them at a fractional scale.
	Overlap int
}

Placement computes the logical margins for a panel anchored to a bar edge.

func (Placement) Attached

func (p Placement) Attached() bool

Attached reports whether the panel joins the bar along its edge.

func (Placement) FittedSize

func (p Placement) FittedSize() (w, h int)

FittedSize returns the panel size after reserving the bar edge and output padding.

func (Placement) Joints

func (p Placement) Joints() Joints

Joints is the panel's joints at its placed position.

func (Placement) Margins

func (p Placement) Margins() Margins

func (Placement) Rect

func (p Placement) Rect() ui.Rect

Rect is the panel's body on its output, in logical pixels.

type PluginHostOptions

type PluginHostOptions struct {
	Roots    []plugin.Root
	StateDir string
	Notify   func(context.Context, v1.NotifyParams) (v1.NotifyResult, error)
}

PluginHostOptions is how the process attaches discovery, state, and notify.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry owns every bar, the services they consume, and the state they read.

Bars are keyed by wl_registry global name. A connector is an attribute: two globals may briefly share one during a reconnect, and they must stay distinct instances with distinct service leases.

Niri state is keyed by connector and held whether or not a host exists, because a Niri event may name an output whose wl_output has not been announced yet or has already been removed. A host is never created or destroyed from a Niri event.

func NewRegistry

func NewRegistry(cfg config.Config) *Registry

func (*Registry) ApplyClipboard

func (r *Registry) ApplyClipboard(update clipboardUpdate) []uint32

ApplyClipboard applies one client update and invalidates only bars whose metadata projection changed.

func (*Registry) ApplyGammaEvent added in v0.2.0

func (r *Registry) ApplyGammaEvent(ev wayland.GammaEvent)

ApplyGammaEvent applies one immutable output status to the policy service.

func (*Registry) ApplyNotify

func (r *Registry) ApplyNotify(m notifyclient.Message)

ApplyNotify applies one client message. main's pump calls it; the exported form keeps applyNotify reachable for the wiring layer only.

func (*Registry) ApplyTray

func (r *Registry) ApplyTray(m trayclient.Message)

ApplyTray applies one client message: the projection first, then every surface that shows it. Each kind states which correlations it breaks.

func (*Registry) AudioAvailable

func (r *Registry) AudioAvailable() bool

func (*Registry) AuxRequests

func (r *Registry) AuxRequests() <-chan wayland.AuxRequest

func (*Registry) BindClipboard

func (r *Registry) BindClipboard(sender clipboardCommandSender)

func (*Registry) BindNotifications

func (r *Registry) BindNotifications(sender notifyCommandSender)

BindNotifications wires the toast host and the command sender. main calls it once before running the client; tests that drive applyNotify directly leave it nil.

func (*Registry) BindPersist

func (r *Registry) BindPersist(path string, reloads chan<- struct{})

BindPersist sets the file and reload signal used when settings write a candidate. Empty path skips the write (tests). The channel is the same one SIGHUP uses.

func (*Registry) BindPluginStore

func (r *Registry) BindPluginStore(s *store.Store)

BindPluginStore attaches the plugin store. The store runs its own goroutine; the registry answers what it asks (enabled sources, local copies) and lends it the plugin host to swap directories under.

func (*Registry) BindPlugins

func (r *Registry) BindPlugins(opts PluginHostOptions) error

BindPlugins discovers enabled plugins and starts one runtime for each. Tests call it; production calls it once after NewRegistry.

func (*Registry) BindTray

func (r *Registry) BindTray(sender trayCommandSender)

BindTray installs the presentation hosts, the command sender, and the one bounded icon worker. The wiring layer calls it; tests that drive applyTray directly do not, so nothing starts a goroutine they did not ask for.

func (*Registry) BrightnessAvailable

func (r *Registry) BrightnessAvailable() bool

func (*Registry) Clock

func (r *Registry) Clock() *services.Clock

Clock is the shared clock service. The process pumps its updates into UpdateClock.

func (*Registry) Close

func (r *Registry) Close()

func (*Registry) ClosePanel

func (r *Registry) ClosePanel(id PanelID)

func (*Registry) ClosePanelByName

func (r *Registry) ClosePanelByName(name string) error

func (*Registry) DropAux

func (r *Registry) DropAux(output uint32, surfaceID string)

func (*Registry) DropHost

func (r *Registry) DropHost(global uint32)

DropHost releases a bar and its service leases after its surface is destroyed. Only the named global is affected, so a stale global sharing a connector with a reconnected one cannot remove it.

func (*Registry) DropTrayAux

func (r *Registry) DropTrayAux(output uint32, surfaceID string) bool

DropTrayAux handles a compositor-side close of a tray surface: the compositor destroyed it, so the shell releases its root without asking the compositor to close it again.

func (*Registry) GammaEventSink added in v0.2.0

func (r *Registry) GammaEventSink() chan<- wayland.GammaEvent

GammaEventSink gives the Wayland owner the send side of the status channel.

func (*Registry) GammaEvents added in v0.2.0

func (r *Registry) GammaEvents() <-chan wayland.GammaEvent

GammaEvents receives per-output gamma state from the Wayland owner.

func (*Registry) GammaRequests added in v0.2.0

func (r *Registry) GammaRequests() <-chan wayland.GammaRequest

GammaRequests carries colour-temperature changes to the Wayland owner.

func (*Registry) HandlePanelByName

func (r *Registry) HandlePanelByName(action, name, section string) error

HandlePanelByName validates a requested section before it changes the root.

func (*Registry) Invalidations

func (r *Registry) Invalidations() <-chan wayland.Invalidation

Invalidations is the channel the Wayland owner receives from. The registry owns it and never closes it.

func (*Registry) LocalPluginDirs

func (r *Registry) LocalPluginDirs() map[string]string

LocalPluginDirs maps plugin id to directory for every usable user-root copy.

func (*Registry) LockState

func (r *Registry) LockState() (LockState, bool)

LockState reports the tracked locker's status (T17/CC status label).

func (*Registry) LockStateMap

func (r *Registry) LockStateMap() map[string]any

LockStateMap answers session.lock-state for the IPC server.

func (*Registry) LockTracked

func (r *Registry) LockTracked() error

LockTracked spawns the configured locker through the tracked manager.

func (*Registry) Metrics

func (r *Registry) Metrics() *services.Metrics

Metrics is the shared sampling service. The process pumps its updates into UpdateMetrics.

func (*Registry) NewHost

func (r *Registry) NewHost(global uint32, connector string) (wayland.HostCallbacks, error)

NewHost builds the hooks for one output's bar and acquires its services.

func (*Registry) NightLight added in v0.2.0

func (r *Registry) NightLight() *services.NightLightService

NightLight is the schedule service shared with the control centre and IPC.

func (*Registry) NightLightCall added in v0.2.0

func (r *Registry) NightLightCall(method string, params json.RawMessage) (map[string]any, error)

NightLightCall answers nightlight.* IPC methods. Persistent temperature changes go through the same Settings entry and config reload as the pane.

func (*Registry) NotifyMessages

func (r *Registry) NotifyMessages() chan notifyclient.Message

NotifyMessages returns the channel the notifyclient publishes to and main drains onto applyNotify.

func (*Registry) OSD

func (r *Registry) OSD() *OSDManager

func (*Registry) OSDStep

func (r *Registry) OSDStep(kind, action string) error

func (*Registry) OpenPanel

func (r *Registry) OpenPanel(id PanelID, output uint32, trig Trigger) error

func (*Registry) OpenPanelByName

func (r *Registry) OpenPanelByName(name string) error

func (*Registry) PaletteCopyJSON

func (r *Registry) PaletteCopyJSON(slug string) error

PaletteCopyJSON puts the exported JSON on the clipboard.

func (*Registry) PaletteDelete

func (r *Registry) PaletteDelete(slug string) error

PaletteDelete removes a palette. If it was in use the shell keeps painting its last complete palette and records why it is not the requested one.

func (*Registry) PaletteExport

func (r *Registry) PaletteExport(slug string) (string, error)

PaletteExport writes <slug>.sysc-palette.json to the Downloads directory and returns the path. The directory is created if it does not exist.

func (*Registry) PaletteImport

func (r *Registry) PaletteImport(data []byte, fallbackName string) (string, int, error)

PaletteImport stores a palette parsed from bytes and reports how many roles were adjusted to meet the contrast floor.

func (*Registry) PaletteImportFile

func (r *Registry) PaletteImportFile(path string) (string, int, error)

PaletteImportFile imports from a path; only a regular file under 64 KiB.

func (*Registry) PaletteRename

func (r *Registry) PaletteRename(slug, name string) error

PaletteRename changes the display name; the slug and the config are untouched.

func (*Registry) PaletteSaveCurrent

func (r *Registry) PaletteSaveCurrent(cfg config.Config, name string) (string, error)

PaletteSaveCurrent stores the palette cfg resolves to, both modes, under name. It generates in an isolated cache (matugen can take seconds), so it must run off the owner and never under Registry.mu.

func (*Registry) PaletteUpdate

func (r *Registry) PaletteUpdate(slug string, f theme.PaletteFile) error

PaletteUpdate replaces a saved palette's colours. If it is the one in use the theme is regenerated.

func (*Registry) PalettesList

func (r *Registry) PalettesList() ([]PaletteSummary, error)

PalettesList is the saved palettes with the in-use one marked, per the persisted configuration (the file the IPC and settings writers share). It re-reads the directory first, so a hand edit is reported.

func (*Registry) PluginBarViews

func (r *Registry) PluginBarViews(output string) int

func (*Registry) PluginNotify

func (r *Registry) PluginNotify(ctx context.Context, p v1.NotifyParams) (v1.NotifyResult, error)

PluginNotify is the plugin host's notify seam: it republishes each plugin toast as a producer command with a unique key, because the service replaces live notifications that share one key. The reply ID is the client request ID; plugins treat it as opaque.

ponytail: v1 Actions are dropped — the producer protocol has no actions.

func (*Registry) PluginPID

func (r *Registry) PluginPID(id string) int

func (*Registry) PluginSources

func (r *Registry) PluginSources() []store.Source

PluginSources returns the enabled sources from configuration.

func (*Registry) PluginStoreCall

func (r *Registry) PluginStoreCall(method string, params json.RawMessage) (map[string]any, error)

PluginStoreCall answers the plugins.* IPC methods. Operations are queued and return at once; callers read plugins.store for the outcome, because an install outlives the IPC client's two-second deadline. An IPC install is the user's own command at their own socket, so it is its own consent, as a hand-edited configuration is.

func (*Registry) PrepareConfig

func (r *Registry) PrepareConfig(cfg config.Config, identities []wayland.HostIdentity) (wayland.PreparedConfig, error)

PrepareConfig builds every enabled host's replacement bar and acquires its services before the caller changes live host policy.

Acquiring here, and releasing the outgoing leases only in Commit, is what keeps a service in continuous use from stopping: its consumer count never reaches zero, so it is never restarted. A failure at any point releases exactly what this call acquired.

func (*Registry) ReducedMotion

func (r *Registry) ReducedMotion() bool

ReducedMotion reports the accessibility preference from the live config.

func (*Registry) RepaintAll

func (r *Registry) RepaintAll()

RepaintAll invalidates every live output's surfaces once. Resume uses it: after a sleep cycle shell pixels, cursor planes and damage state are stale, and one forced frame per output is cheaper than reasoning about which surfaces survived. While the Wayland owner is suspended its bridge queues the invalidations, so this call never blocks on the socket's silence.

func (*Registry) ReplacePlugin

func (r *Registry) ReplacePlugin(id string, swap func() error) error

ReplacePlugin is the store's Installer.Replace. It runs on the store worker, never under Registry.mu.

func (*Registry) Screenshot

func (r *Registry) Screenshot(mode string) error

Screenshot starts a capture: "screen" and "window" through niri, "region" through the shell's own selector. It returns once the capture has started; the result is a toast.

func (*Registry) Selections

func (r *Registry) Selections() <-chan wayland.SelectionRequest

Selections is the shell's system-clipboard request stream. The platform owner drains it; a full buffer drops the request rather than block the registry lock.

func (*Registry) SetCapabilities

func (r *Registry) SetCapabilities(c wayland.Capabilities)

SetCapabilities records the compositor's optional effects. The platform calls it on the Wayland goroutine before the first bar is built, and again when the answer changes.

func (*Registry) SetExternalInhibitors

func (r *Registry) SetExternalInhibitors(list []services.ScreenSaverInhibitor)

SetExternalInhibitors is the screensaver service's change callback. It runs on that service's D-Bus signal pump goroutine.

func (*Registry) SetIdleService

func (r *Registry) SetIdleService(s *services.IdleService)

setMedia installs the media service and relays its cached snapshots into the retained bar and control-centre trees. The widget and page acquire leases for the service's bus watch; the relay itself never keeps the service alive. SetIdleService installs the idle policy service. Its channels go into wayland.Callbacks by the caller; main wires both before Run.

func (*Registry) SetLockActive added in v0.2.0

func (r *Registry) SetLockActive(active bool)

SetLockActive records whether the session lock is up. The locker reports through here instead of enqueueing wallpaper commands itself so the kiosk switch and the remaining reasons are judged in one place.

func (*Registry) SetPluginEnabled

func (r *Registry) SetPluginEnabled(id string, on bool) error

func (*Registry) SetScreenSaver

func (r *Registry) SetScreenSaver(ss *services.ScreenSaverService)

SetScreenSaver installs the bus-name owner and takes its first inhibitor snapshot.

func (*Registry) SetScreensOff added in v0.2.0

func (r *Registry) SetScreensOff(off bool)

SetScreensOff records whether idle blanking has turned the displays off. Only idle blanking counts: a locked session and the Session menu keep the screens on, so they are not the screens-off reason.

func (*Registry) SetWallsService

func (r *Registry) SetWallsService(svc *walls.Service)

SetWallsService attaches the one service that owns sysc-walls discovery and commands. The service already queues its initial refresh when constructed.

func (*Registry) ShowWindowSwitcher

func (r *Registry) ShowWindowSwitcher() error

ShowWindowSwitcher opens the per-output switcher only when no other modal root owns keyboard focus. Caller is the same-user IPC handler.

func (*Registry) Status

func (r *Registry) Status() map[string]any

func (*Registry) SuspendTracked

func (r *Registry) SuspendTracked() error

SuspendTracked waits for the managed protocol event before calling logind. Without a managed locker, or with one whose owner is not on the bus, there is no seal to wait for, so plain suspend runs: sleep protection is a preference, but refusing to suspend is not an option (GH #116).

func (*Registry) SyncToastOutputs

func (r *Registry) SyncToastOutputs(globals map[string]uint32)

SyncToastOutputs opens or closes toast surfaces as outputs come and go. The registry calls it from its output bookkeeping, with no lock held: the toast host's own state is under Registry.mu, because the compositor drives its configure, paint, and pointer callbacks on another goroutine.

func (*Registry) ThemeCall

func (r *Registry) ThemeCall(method string, params json.RawMessage) (map[string]any, error)

ThemeCall answers the theme.* IPC methods (sysc-715). Writes go through the same settings entries the pane uses, so the entry's own Setter is the only validation, and persist through writeConfig: the file write plus a reload poke is the sanctioned way to change the theme from outside the owner goroutine, the same way the settings pane commits a draft.

func (*Registry) TogglePanel

func (r *Registry) TogglePanel(id PanelID, output uint32, trig Trigger) error

func (*Registry) TogglePanelByName

func (r *Registry) TogglePanelByName(name string) error

func (*Registry) Tokens

func (r *Registry) Tokens() theme.Tokens

Tokens is the palette the registry generated at construction or last reload.

func (*Registry) TrayMessages

func (r *Registry) TrayMessages() chan trayclient.Message

TrayMessages is the channel the trayclient publishes to and main drains onto ApplyTray.

func (*Registry) UpdateClock

func (r *Registry) UpdateClock(now time.Time) []uint32

UpdateClock applies a shared time snapshot to every bar and reports the globals whose text actually changed.

One tick reaches every bar from one snapshot; a bar whose rendered text is unchanged is not reported, so no frame is submitted for it.

func (*Registry) UpdateMetrics

func (r *Registry) UpdateMetrics(snap services.Snapshot) []uint32

UpdateMetrics applies a sampling pass to every bar and reports the globals whose rendering actually changed.

func (*Registry) UpdateNightLight added in v0.2.0

func (r *Registry) UpdateNightLight()

UpdateNightLight rebuilds the open views from the latest service snapshot. The caller does not pass the snapshot so a queued stale update cannot overwrite a newer timer or gamma event.

func (*Registry) UpdateNiri

func (r *Registry) UpdateNiri(s niri.Snapshot) []uint32

UpdateNiri projects a snapshot into per-connector text and reports the globals whose text actually changed.

func (*Registry) UpdateWeather

func (r *Registry) UpdateWeather(reading services.Reading) []uint32

UpdateWeather applies a reading to every bar and reports the globals whose text actually changed.

func (*Registry) Weather

func (r *Registry) Weather() *services.Weather

Weather is the shared weather service. The process pumps its updates into UpdateWeather.

type Run

type Run struct {
	Text      string
	Bold      bool
	Italic    bool
	Underline bool
	// Link is the href of the enclosing anchor, empty when there is none or
	// when link support is off.
	Link  bool
	Href  string
	Break bool
}

Run is one styled span of body text. A run never spans a line break: the card builder turns each break into a new line of nodes.

func ParseBody

func ParseBody(body string, allowLinks bool) []Run

ParseBody turns a notification body into bounded styled runs.

Markup the spec does not define, or markup that does not close, makes the whole body plain text rather than a guess: a half-applied style is a worse lie than no style. Links become runs only when the shell is allowed to open them; otherwise the anchor text survives unstyled.

type SortKey

type SortKey uint8
const (
	SortName SortKey = iota
	SortUpdated
	SortAdded
	SortCategory
	SortInstalledFirst
)

func (SortKey) Next

func (key SortKey) Next() SortKey

type StoreAction

type StoreAction string
const (
	ActionInstall   StoreAction = "install"
	ActionInstalled StoreAction = "installed"
	ActionUpdate    StoreAction = "update"
	ActionDisabled  StoreAction = "disabled"
	ActionRemove    StoreAction = "remove"
)

type Surfaces

type Surfaces struct {
	Bar     uint8
	Panel   uint8
	Overlay uint8
}

Surfaces carries the alpha each root surface paints at. Nested fills composite over their painted parent rather than inheriting these, which is what keeps a card distinct on a translucent panel.

type Theme

type Theme struct {
	// Palette is the accessible, validated role set.
	Palette Palette
	// Metrics is the density row in force, with any bar override applied.
	Metrics theme.Metrics
	// Shapes are the resolved corner radii.
	Shapes render.Shapes
	// Type resolves a semantic text role to a family, size, and weight.
	Type render.TypeSet
	// Surfaces is the per-surface root opacity.
	Surfaces Surfaces
	// Elevation selects how much of the shadow renderer a floating surface
	// uses.
	Elevation theme.Elevation
	// Motion is the duration table and curve in force.
	Motion render.MotionSet
	// Outlined forces the structural boundary on. High contrast sets it, and
	// so does a palette whose surface levels cannot separate on their own.
	Outlined bool

	// BarGap is the outer gap between the screen edge and the painted body.
	// It lives inside the surface, so the screen edge stays clickable, and it
	// is a docking choice rather than a density row.
	BarGap int
	// Fillet is the radius of the concave wedges joining a panel to the bar.
	// It lives beside BarGap because it is the same kind of decision: how the
	// shell's surfaces meet, not a density row.
	Fillet int

	// BarStyle is the effective bar style. High contrast forces solid, and a
	// bar that names no style paints solid, as every bar did before styles.
	BarStyle string
	// BarEdge and BarShape are the bar policy's edge and the shape it lays out
	// in (layoutShape), which decide where its surface meets the screen.
	BarEdge, BarShape string
	// Blur reports that the compositor blurs behind this bar: its style is
	// translucent and the compositor offers ext-background-effect.
	Blur bool
	// PillAlpha is the alpha of the bar's capsules. Surfaces.Bar is the
	// ground's.
	PillAlpha uint8

	// The fields below are the flat names the existing surfaces still read.
	// They are derived from the groups above, and they go away as each tree
	// moves onto roles.
	BarHeight  int
	BarPadding int
	Spacing    int
	Radius     int
	TextSize   int

	IconSize   int
	CardRadius int

	Surface                 Color
	SurfaceContainer        Color
	SurfaceContainerHigh    Color
	SurfaceContainerHighest Color
	OnSurface               Color
	OnSurfaceVariant        Color
	Primary                 Color
	OnPrimary               Color
	PrimaryContainer        Color
	OnPrimaryContainer      Color
	Outline                 Color
	OutlineVariant          Color
	Error                   Color
	OnError                 Color

	Background Color
	Foreground Color
	Accent     Color
	Muted      Color
	// Capsule fills the pill around a bar widget. Container fills a workspace
	// pill that is not focused, and is a distinct container colour rather than
	// the capsule surface. OnAccent and OnContainer keep a pill's numeral
	// legible on its own fill.
	Capsule     Color
	Container   Color
	OnAccent    Color
	OnContainer Color
	// contains filtered or unexported fields
}

Theme is the one resolved contract every surface paints from. Components request semantic roles; no component carries an independent pixel constant or an RGB value.

func DefaultTheme

func DefaultTheme() Theme

DefaultTheme is the resolved theme for the default configuration and the compiled fallback palette. It is what a surface looks like before any palette has been generated.

func ResolveTheme

func ResolveTheme(cfg config.Config, bar config.Bar, tok theme.Tokens) (Theme, error)

ResolveTheme is the only path from configuration and a palette to a painted surface.

It parses the palette, applies the composition, lets the resolved bar policy override the geometry it owns, enforces accessibility last, and validates the result before returning it. A caller that gets an error keeps whatever theme it already had: a surface painted half in one theme is worse than one painted entirely in the previous.

func ThemeFrom

func ThemeFrom(cfg config.Config, bar config.Bar) Theme

ThemeFrom resolves a validated configuration against the compiled fallback palette. It is what a bare Bar in a test paints with; every surface the shell actually paints resolves through the registry, which a test in this package enforces.

func ThemeFromTokens

func ThemeFromTokens(tok theme.Tokens, radius int) Theme

ThemeFromTokens maps generated Material 3 tokens onto the default composition at one radius.

func (Theme) AttachedPanelStyle

func (t Theme) AttachedPanelStyle() render.Style

AttachedPanelStyle keeps the semantic panel roles but resolves its root at the bar opacity. Without a captured backdrop the two surfaces are one joined ground; using the detached panel alpha would composite a different colour.

func (Theme) BackgroundOpaque

func (t Theme) BackgroundOpaque() bool

BackgroundOpaque reports whether the surface token is fully opaque.

func (Theme) Geometry

func (t Theme) Geometry() (surface, body, gap int)

Geometry derives the Wayland dimensions from the tokens. The gap lives inside the surface, so the surface carries one gap and not two. surface is the bar's extent, where panels meet it; an attached bar's overhang lies past it and does not count.

The derivation itself is config.Bar's, which is what keeps this from drifting away from the extent the platform sizes the surface to. The exclusive zone is no longer part of it: a bar may reserve less than it occupies, or nothing at all.

func (Theme) LerpColors

func (t Theme) LerpColors(to Theme, progress float64) Theme

LerpColors blends this theme's colours toward another. Geometry is not interpolated: heights, padding, and radii come from the incoming theme at once, because a control that changes size mid-fade would relayout every frame. Only the palette travels.

func (Theme) OverlayStyle

func (t Theme) OverlayStyle() render.Style

func (Theme) PanelStyle

func (t Theme) PanelStyle() render.Style

PanelStyle and OverlayStyle name the two non-bar roots so a host does not have to remember which alpha it owns.

func (Theme) Style

func (t Theme) Style() render.Style

Style projects the resolved theme onto the painter's view. Every surface builds its style here so a control cannot inherit a different palette from the pill beside it; callers supply only geometry that varies per surface -- scale, body, and attach edge.

func (Theme) StyleFor

func (t Theme) StyleFor(a uint8) render.Style

StyleFor is the resolved style for one root surface. Style() is the bar's, which is why the plain form keeps the bar alpha; a panel, a toast, a tray surface and the OSD float over the wallpaper and take their own.

Only the root fill changes. Every nested fill composites over the painted root, so a card inside a 90 percent panel is still an opaque card.

func (Theme) Valid

func (t Theme) Valid() error

Valid reports whether the tokens produce a usable bar.

func (Theme) WithCompositor

func (t Theme) WithCompositor(blur bool) Theme

WithCompositor resolves the bar's ground and pill alpha against whether the compositor can blur behind the bar (design D1-D3). Without blur, frosted paints as solid and islands keeps its unpainted ground with pills on the solid floor. It re-derives from the configured values, so it can be applied again whenever the capability changes.

func (Theme) WithEffectBehind added in v0.2.0

func (t Theme) WithEffectBehind(on, blur bool) Theme

WithEffectBehind records whether a terminal effect plays behind the bar and re-derives its ground and pills, as WithCompositor does for blur.

type ToggleResult

type ToggleResult uint8
const (
	Opened ToggleResult = iota
	Closed
	Moved
)

type Trigger

type Trigger struct {
	BarEdge    string
	BarZone    int
	Align      string
	OutW, OutH int
	AnchorX    int
	AnchorY    int
}

Trigger is the placement hint for opening a panel on one output.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL