Documentation
¶
Overview ¶
Package ui owns the immediate-mode frame tree, controls, editors, input routing and the Wayland run loop behind the public nefergui facade.
Index ¶
- Variables
- func Run[T any](ctx context.Context, model *T, view func(*Frame, *T), options ...WindowOption) error
- func RunFrames[T any](ctx context.Context, frames int, model *T, view func(*Frame, *T), ...) error
- func RunLock(ctx context.Context, cfg LockConfig) (err error)
- type Anchor
- type ButtonEvent
- type ButtonOption
- type ChangeEvent
- type CommonOption
- type ContainerOption
- type DisabledOption
- type EditEvent
- type EditOption
- type Frame
- type HeadingOption
- type InputEvent
- type InputKind
- type KeyboardMode
- type LayerConfig
- type LayerLevel
- type LockConfig
- type LockState
- type LockStatus
- type Modifiers
- type Node
- func (n Node) Aside(options ...ContainerOption) Node
- func (n Node) Box(options ...ContainerOption) Node
- func (n Node) Button(label string, options ...ButtonOption) ButtonEvent
- func (n Node) Checkbox(label string, value *bool, options ...ButtonOption) ChangeEvent
- func (n Node) Column(options ...ContainerOption) Node
- func (n Node) Element(typ string, options ...ContainerOption) Node
- func (n Node) Footer(options ...ContainerOption) Node
- func (n Node) Header(options ...ContainerOption) Node
- func (n Node) Heading(text string, options ...HeadingOption)
- func (n Node) Icon(name string, options ...ContainerOption)
- func (n Node) Image(img image.Image, options ...ContainerOption)
- func (n Node) Input(label string, value *string, options ...EditOption) EditEvent
- func (n Node) Main(options ...ContainerOption) Node
- func (n Node) Nav(options ...ContainerOption) Node
- func (n Node) Radio(label, option string, selected *string, options ...ButtonOption) ChangeEvent
- func (n Node) Rect(x, y, w, h float64) Node
- func (n Node) Row(options ...ContainerOption) Node
- func (n Node) Scroll(options ...ContainerOption) Node
- func (n Node) Section(options ...ContainerOption) Node
- func (n Node) Separator(options ...ContainerOption)
- func (n Node) Slider(label string, value *float64, min, max, step float64, options ...ValueOption) ChangeEvent
- func (n Node) Spacer(options ...ContainerOption)
- func (n Node) Stack(options ...ContainerOption) Node
- func (n Node) Text(text string, options ...ContainerOption)
- func (n Node) Textarea(label string, value *string, options ...EditOption) EditEvent
- type Rect
- type SecretBuffer
- type ValueOption
- type WaylandSurface
- type WindowOption
- func Layer(c LayerConfig) WindowOption
- func OnInput(fn func(InputEvent) bool) WindowOption
- func OnResize(fn func(width, height int, scale float64)) WindowOption
- func OnSurface(fn func(context.Context, WaylandSurface) error) WindowOption
- func Size(w, h int) WindowOption
- func Styles(s string) WindowOption
- func Title(s string) WindowOption
- func Transparent() WindowOption
- func Wake(ch <-chan struct{}) WindowOption
Constants ¶
This section is empty.
Variables ¶
var ErrLockFinished = errors.New("nefergui: session lock finished by the compositor")
ErrLockFinished reports that the compositor refused the session lock or ended it (ext_session_lock_v1.finished). NeferGUI never unlocks in response.
Functions ¶
func Run ¶
func Run[T any](ctx context.Context, model *T, view func(*Frame, *T), options ...WindowOption) error
Run builds and presents an immediate view on the Wayland session owner loop.
func RunFrames ¶
func RunFrames[T any](ctx context.Context, frames int, model *T, view func(*Frame, *T), committed func(uint64) error, options ...WindowOption) error
RunFrames is a deterministic harness entry: each commit requests a redraw.
func RunLock ¶ added in v0.3.0
func RunLock(ctx context.Context, cfg LockConfig) (err error)
RunLock acquires ext-session-lock on one connection and shows opaque black on every output through the regular Vulkan/DMA-BUF/explicit-sync path. Outputs added or removed later gain or lose a lock surface. Keyboard input feeds cfg.Secret only through the secret keyboard path. RunLock returns nil after an unlock requested through cfg.Unlock, ErrLockFinished (wrapped) when the compositor ends or refuses the lock, or the first failure; it never unlocks on failure or cancellation (closing the connection keeps the session locked).
Types ¶
type Anchor ¶ added in v0.2.0
type Anchor uint8
Anchor is a bit set of output edges a layer surface attaches to.
type ButtonEvent ¶
type ButtonEvent struct {
// contains filtered or unexported fields
}
Control event values are immutable snapshots; querying them never consumes events.
func (ButtonEvent) Activated ¶
func (e ButtonEvent) Activated() bool
type ButtonOption ¶
type ButtonOption interface {
// contains filtered or unexported methods
}
type ChangeEvent ¶
type ChangeEvent struct {
// contains filtered or unexported fields
}
func (ChangeEvent) Changed ¶
func (e ChangeEvent) Changed() bool
type CommonOption ¶
type CommonOption struct {
// contains filtered or unexported fields
}
CommonOption is the concrete type of Key, ID, Class and Inline; it belongs to every option family. It is exported only so the root facade can return it.
func Class ¶
func Class(class string) CommonOption
func ID ¶
func ID(id string) CommonOption
func Inline ¶
func Inline(src string) CommonOption
func Key ¶
func Key(key string) CommonOption
type ContainerOption ¶
type ContainerOption interface {
// contains filtered or unexported methods
}
ContainerOption, ButtonOption and EditOption are separate option families.
type DisabledOption ¶
type DisabledOption struct {
// contains filtered or unexported fields
}
DisabledOption is the concrete type of Disabled. It applies to every interactive control (buttons, value controls and editors) but not to containers or headings. Exported only so the root facade can return it.
func Disabled ¶
func Disabled(v bool) DisabledOption
Disabled blocks focus and interaction on an interactive control.
type EditOption ¶
type EditOption interface {
// contains filtered or unexported methods
}
func Password ¶
func Password(v bool) EditOption
func Placeholder ¶
func Placeholder(v string) EditOption
type Frame ¶
type Frame struct {
// contains filtered or unexported fields
}
Frame is valid only during one call to the view function.
func (*Frame) Diagnostics ¶
Diagnostics returns a copy of frame diagnostics (populated with -tags nefergui_debug).
func (*Frame) Root ¶
func (f *Frame) Root(options ...ContainerOption) Node
func (*Frame) SetInputRects ¶ added in v0.2.0
SetInputRects stages the input region for the surface: pointer input outside the rectangles passes through. It is applied after the view returns and and committed together with the frame's buffer, with no extra commit. nil restores the whole surface, and a non-nil empty slice makes the surface click-through. Rects need positive size. The slice is copied, so callers may reuse it; an unchanged region costs nothing. If the view never calls it, the Layer config's InputRects stay in effect.
type HeadingOption ¶
type HeadingOption interface {
// contains filtered or unexported methods
}
HeadingOption accepts common CSS options and Level, but not control options.
func Level ¶
func Level(level int) HeadingOption
Level sets the accessibility heading level (1 through 6).
type InputEvent ¶ added in v0.2.0
type InputEvent struct {
Kind InputKind
X, Y float64
DX, DY float64
Button uint32
Pressed bool
Repeat bool
KeyName string
Text string
Modifiers Modifiers
}
InputEvent is a raw platform event, delivered on the owner loop before the normal control routing. Coordinates are logical, surface-local pixels. Size changes are not input; use OnResize and Frame.Size. Which fields are set depends on Kind:
pointer motion/press/release/axis: X, Y; press/release: Button (evdev code) and Pressed; axis: DX, DY key: KeyName, Text, Modifiers, Pressed, Repeat
type KeyboardMode ¶ added in v0.2.0
type KeyboardMode uint8
KeyboardMode is the layer surface keyboard interactivity. The zero value is KeyboardNone: the surface never takes keyboard focus. KeyboardOnDemand needs layer-shell version 4.
const ( KeyboardNone KeyboardMode = iota KeyboardExclusive KeyboardOnDemand )
type LayerConfig ¶ added in v0.2.0
type LayerConfig struct {
Output string // output name; empty lets the compositor choose
// AllOutputs puts one surface on every output, including outputs added
// while Run is running; removed outputs lose theirs. Every surface shows
// the same view and model, laid out at its own size and scale. Run then
// returns only on cancellation or failure. It excludes Output, keyboard
// interactivity, OnSurface, OnResize and RunFrames.
AllOutputs bool
Namespace string // defaults to "nefergui"
Level LayerLevel
Anchors Anchor
Keyboard KeyboardMode
ExclusiveZone int32
Margin [4]int32 // top, right, bottom, left
// InputRects, when non-nil, restricts pointer input to these rectangles.
// An empty non-nil slice makes the surface fully click-through. Rects need
// positive width and height.
InputRects []Rect
}
LayerConfig requests a wlr-layer-shell surface instead of an xdg toplevel. Size still gives the initial logical size; an axis anchored to both opposite edges is sized by the compositor and reported through OnResize and Frame.Size. ExclusiveZone > 0 asks the compositor to reserve that many logical pixels from an anchored edge (only for one edge, or one edge plus both perpendicular edges); 0 reserves nothing and asks to avoid other surfaces' positive zones; -1 ignores other exclusive zones and extends to the anchored output edges.
type LayerLevel ¶ added in v0.2.0
type LayerLevel uint8
LayerLevel is the wlr-layer-shell stacking layer. The zero value is invalid, so a surface never silently lands below every window.
const ( LayerBackground LayerLevel = iota + 1 LayerBottom LayerTop LayerOverlay )
type LockConfig ¶ added in v0.3.0
type LockConfig struct {
// Display is the Wayland socket name; empty uses the environment.
Display string
// Styles is an optional author stylesheet path, as for the Styles option.
Styles string
// Secret receives typed input. Required.
Secret *SecretBuffer
// View builds the content of the one output that hosts it (the output whose
// surface has keyboard focus, initially the first). Required. Other outputs
// show plain opaque black.
View func(*Frame, LockState)
// OnLocked runs once on the owner loop when the compositor sends locked.
OnLocked func()
// OnSubmit runs on the owner loop when Enter is pressed after locked. It
// must not block: verification is asynchronous. secret aliases Secret's
// memory and is valid only during the call; it is wiped right after it
// returns, so the callee copies or consumes it before returning.
OnSubmit func(secret []byte)
// Unlock, when it receives a value, asks RunLock to send
// unlock_and_destroy, roundtrip and return nil. This is the only unlock
// path: it is the caller's explicit request after its own verification. A
// request received before the locked event is held until locked; closing
// the channel is not a request. A nil channel never unlocks.
Unlock <-chan struct{}
// Status delivers the state shown as LockState.Status; each received value
// schedules a redraw. Optional.
Status <-chan LockStatus
// Wake requests a redraw for each received value.
Wake <-chan struct{}
// OnOutputError reports an output added after acquisition that could not
// get a lock surface; the compositor keeps it black. Optional, owner loop.
OnOutputError func(output string, err error)
}
LockConfig configures RunLock.
type LockState ¶ added in v0.3.0
type LockState struct {
Mask int // typed code points, for a mask of that many bullets
Locked bool // the compositor confirmed the lock (locked event)
Status LockStatus // latest value received on LockConfig.Status
Width, Height int // logical size of the surface hosting the view
}
LockState is what the lock view may know: never the secret itself.
type LockStatus ¶ added in v0.3.0
type LockStatus uint8
LockStatus is an opaque caller-driven state shown by the view, for example while an authentication attempt runs. NeferGUI attaches no meaning to it.
const ( LockIdle LockStatus = iota // ready for input LockBusy // an attempt is being verified LockFailed // the last attempt was rejected )
type Modifiers ¶ added in v0.2.0
type Modifiers uint8
Modifiers is a bit set of keyboard modifiers held during a key event.
type Node ¶
type Node struct {
// contains filtered or unexported fields
}
Node is an ephemeral handle into the current frame. Do not retain it between frames.
func (Node) Aside ¶
func (n Node) Aside(options ...ContainerOption) Node
func (Node) Box ¶
func (n Node) Box(options ...ContainerOption) Node
func (Node) Button ¶
func (n Node) Button(label string, options ...ButtonOption) ButtonEvent
func (Node) Checkbox ¶
func (n Node) Checkbox(label string, value *bool, options ...ButtonOption) ChangeEvent
func (Node) Column ¶
func (n Node) Column(options ...ContainerOption) Node
func (Node) Footer ¶
func (n Node) Footer(options ...ContainerOption) Node
func (Node) Header ¶
func (n Node) Header(options ...ContainerOption) Node
func (Node) Heading ¶
func (n Node) Heading(text string, options ...HeadingOption)
func (Node) Icon ¶
func (n Node) Icon(name string, options ...ContainerOption)
func (Node) Image ¶
func (n Node) Image(img image.Image, options ...ContainerOption)
Image borrows a decoded Go image. Treat its pixels as immutable while passed to Image; pass a new image value to change pixels. Renderer cache identity requires a comparable image.Image value (for example, *image.RGBA).
func (Node) Input ¶
func (n Node) Input(label string, value *string, options ...EditOption) EditEvent
func (Node) Main ¶
func (n Node) Main(options ...ContainerOption) Node
func (Node) Nav ¶
func (n Node) Nav(options ...ContainerOption) Node
func (Node) Radio ¶
func (n Node) Radio(label, option string, selected *string, options ...ButtonOption) ChangeEvent
func (Node) Rect ¶ added in v0.2.0
Rect positions the node at x, y with size w, h in logical pixels, relative to the content box of its Stack parent, without CSS parsing or per-frame strings or style copies. The geometry is border-box and overrides authored width, height and margin. Rect is valid only on a direct child of Stack; elsewhere it is ignored, keeping normal flex and block layout, and debug builds (-tags nefergui_debug) report it through Frame.Diagnostics.
func (Node) Row ¶
func (n Node) Row(options ...ContainerOption) Node
func (Node) Scroll ¶
func (n Node) Scroll(options ...ContainerOption) Node
func (Node) Section ¶
func (n Node) Section(options ...ContainerOption) Node
func (Node) Separator ¶
func (n Node) Separator(options ...ContainerOption)
func (Node) Slider ¶
func (n Node) Slider(label string, value *float64, min, max, step float64, options ...ValueOption) ChangeEvent
func (Node) Spacer ¶
func (n Node) Spacer(options ...ContainerOption)
func (Node) Stack ¶
func (n Node) Stack(options ...ContainerOption) Node
func (Node) Text ¶
func (n Node) Text(text string, options ...ContainerOption)
type Rect ¶ added in v0.2.0
type Rect struct{ X, Y, Width, Height int32 }
Rect is an integer logical-pixel rectangle in surface coordinates.
type SecretBuffer ¶ added in v0.3.0
type SecretBuffer struct {
// contains filtered or unexported fields
}
SecretBuffer is a caller-owned fixed-capacity byte buffer for typed secret input. Typed bytes never become a Go string and are never stored in the model, tree or render text; the view only sees Len. Bytes beyond the capacity are dropped. It is used from the lock owner loop only.
func NewSecretBuffer ¶ added in v0.3.0
func NewSecretBuffer(capacity int) *SecretBuffer
NewSecretBuffer allocates a buffer holding at most capacity bytes (1..4096).
func (*SecretBuffer) Bytes ¶ added in v0.3.0
func (b *SecretBuffer) Bytes() []byte
Bytes returns the typed bytes. The slice aliases the buffer: do not retain it past the next edit or Wipe, and never convert it to a string.
func (*SecretBuffer) Len ¶ added in v0.3.0
func (b *SecretBuffer) Len() int
Len is the number of typed code points (the mask count).
func (*SecretBuffer) Wipe ¶ added in v0.3.0
func (b *SecretBuffer) Wipe()
Wipe zeroes the buffer. The caller may call it at any time on the owner loop.
type ValueOption ¶
type ValueOption interface {
// contains filtered or unexported methods
}
ValueOption accepts CSS options and Disabled for pointer-backed controls.
type WaylandSurface ¶ added in v0.2.0
WaylandSurface exposes the window's Wayland connection and wl_surface so an integrator can register extra protocol objects on the same client, such as clipboard or surface-marking extensions. It is the escape hatch to the underlying wlturbo objects; it does not add any protocol itself.
The values are owned by NeferGUI and valid until Run returns. Do not close the Display, destroy the Surface or attach buffers. Events for objects the callback creates are dispatched on the owner goroutine while requests such as roundtrips run before the event reader starts, and on NeferGUI's reader goroutine afterwards, so handlers must synchronize any state they share.
type WindowOption ¶
type WindowOption interface {
// contains filtered or unexported methods
}
func Layer ¶ added in v0.2.0
func Layer(c LayerConfig) WindowOption
Layer selects a wlr-layer-shell surface for the window.
func OnInput ¶ added in v0.2.0
func OnInput(fn func(InputEvent) bool) WindowOption
OnInput delivers every raw input event to fn on the session owner loop, before the event reaches NeferGUI controls; controls still receive it. fn may mutate the model the view reads. It returns true when it changed state the view shows, which schedules a redraw; a false return costs no frame, so pointer motion does not force a build. A nil fn is ignored. fn must not block.
func OnResize ¶ added in v0.2.0
func OnResize(fn func(width, height int, scale float64)) WindowOption
OnResize reports the logical size and scale once at start and again only when one of them changes; a change always schedules a redraw. It runs on the owner loop before the frame is built. A nil fn is ignored.
func OnSurface ¶ added in v0.2.0
func OnSurface(fn func(context.Context, WaylandSurface) error) WindowOption
OnSurface calls fn once on the owner goroutine, after the surface has its role (xdg toplevel or layer surface) and its first configure, and before the first buffer is attached, so the window is not yet visible. ctx is the Run context: if it is cancelled while fn runs, NeferGUI closes the display so blocking protocol calls fail, and Run returns ctx.Err() (joined with any other error fn returned). A non-nil error aborts Run and closes the session. A nil fn is ignored.
func Size ¶
func Size(w, h int) WindowOption
func Styles ¶
func Styles(s string) WindowOption
func Title ¶
func Title(s string) WindowOption
func Transparent ¶
func Transparent() WindowOption
Transparent requests an alpha-capable Wayland surface (opaque by default).
func Wake ¶ added in v0.2.0
func Wake(ch <-chan struct{}) WindowOption
Wake requests a redraw whenever a value arrives on ch, so a view can react to state changed by other goroutines. The caller synchronizes such state; the view still runs only on the owner loop. Closing ch stops forwarding. A nil ch is ignored.