Documentation
¶
Overview ¶
Package neferclient is a Wayland client toolkit library for Go: connection, outputs, surface roles, seat and DMA-BUF presentation. It does not render and holds no application policy.
Index ¶
- Constants
- Variables
- type Anchor
- type Buffer
- type CapabilityError
- type Conn
- func (c *Conn) Bind[P wl.Proxy](iface string, version uint32, newProxy func(*wl.Context) P) (P, uint32, error)
- func (c *Conn) Close() error
- func (c *Conn) Context() *wl.Context
- func (c *Conn) Dispatch(h Handler) error
- func (c *Conn) Display() *wl.Display
- func (c *Conn) Lock() (*Lock, error)
- func (c *Conn) NewLayerSurface(cfg LayerConfig) (*Surface, error)
- func (c *Conn) NewToplevel(title string, w, h int32) (*Surface, error)
- func (c *Conn) Outputs() []Output
- func (c *Conn) Roundtrip() error
- func (c *Conn) Seat() *Seat
- func (c *Conn) UnwatchFD(fd int) error
- func (c *Conn) Wake() <-chan struct{}
- func (c *Conn) WatchFD(fd int, id uint64) error
- type CursorShape
- type Feedback
- type Format
- type Handler
- type KeyEvent
- type KeyboardMode
- type LayerConfig
- type LayerLevel
- type Lock
- type Modifiers
- type NopHandler
- func (NopHandler) Closed(SurfaceID)
- func (NopHandler) Configure(SurfaceID, int32, int32)
- func (NopHandler) Error(error)
- func (NopHandler) FDReady(uint64)
- func (NopHandler) FeedbackDone(SurfaceID)
- func (NopHandler) Frame(SurfaceID)
- func (NopHandler) Key(*KeyEvent)
- func (NopHandler) KeyboardFocus(SurfaceID, bool)
- func (NopHandler) LockFinished()
- func (NopHandler) Locked()
- func (NopHandler) OutputAdded(*Output)
- func (NopHandler) OutputRemoved(uint32)
- func (NopHandler) Pointer(*PointerEvent)
- func (NopHandler) Scale(SurfaceID, float64)
- func (NopHandler) SecretChanged(int)
- type Output
- type Plane
- type PointerEvent
- type PointerKind
- type Present
- type Rect
- type Seat
- type SecretBuffer
- type Surface
- func (s *Surface) Close() error
- func (s *Surface) DestroyBuffer(id uint64) error
- func (s *Surface) DestroyTimeline(id uint64) error
- func (s *Surface) Feedback() *Feedback
- func (s *Surface) ID() SurfaceID
- func (s *Surface) ImportBuffer(id uint64, b *Buffer) (err error)
- func (s *Surface) ImportTimeline(id uint64, fd int) error
- func (s *Surface) PhysicalSize() (int32, int32, error)
- func (s *Surface) Present(p *Present) error
- func (s *Surface) SetInputRegion(rects []Rect) error
- func (s *Surface) Size() (w, h int32, scale float64)
- type SurfaceID
Constants ¶
const ( AxisVertical = 0 AxisHorizontal = 1 )
Scroll axes of PointerEvent.Axis.
const DefaultLayerNamespace = "neferclient"
DefaultLayerNamespace is used when LayerConfig.Namespace is empty.
Variables ¶
var ( // ErrClosed is returned by calls on a closed Conn. ErrClosed = errors.New("neferclient: connection closed") // ErrGlobalNotFound is returned by [Conn.Bind] when the compositor does // not announce the interface. Test it with errors.Is. ErrGlobalNotFound = wlturbo.ErrGlobalNotFound )
Functions ¶
This section is empty.
Types ¶
type Buffer ¶
type Buffer struct {
Width, Height int32 // physical pixels
FourCC uint32
Modifier uint64
Planes [4]Plane
PlaneCount int
}
Buffer describes a DMA-BUF to import as a wl_buffer.
type CapabilityError ¶
CapabilityError reports a missing or too old required protocol global.
func (*CapabilityError) Error ¶
func (e *CapabilityError) Error() string
func (*CapabilityError) Unwrap ¶
func (e *CapabilityError) Unwrap() error
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn is one Wayland connection. Two goroutines run beside the owner: the reader, which only decodes wire events into a fixed queue, and an epoll waiter for Conn.WatchFD. Everything else — event handling, requests, Bind, Roundtrip, Outputs, Close — belongs to the owner goroutine, the one that calls Conn.Dispatch.
func Connect ¶
Connect dials the compositor and completes the registry setup: every wl_output announced at that point is bound and its first description is available from Conn.Outputs. display names the socket relative to $XDG_RUNTIME_DIR, or is an absolute path; "" uses $WAYLAND_DISPLAY, then "wayland-0". Cancelling ctx abandons setup; afterwards ctx is not used.
func (*Conn) Bind ¶
func (c *Conn) Bind[P wl.Proxy](iface string, version uint32, newProxy func(*wl.Context) P) (P, uint32, error)
Bind binds the global named iface at min(announced, version) and returns the proxy and the negotiated version. newProxy creates the proxy on the given context; register its event handlers inside newProxy: the reader is paused until Bind returns, but the bound object's first events can arrive right after, so a handler added later may miss them. A missing global yields an error matching ErrGlobalNotFound.
func (*Conn) Close ¶
Close closes the connection and stops both goroutines. It never requests an unlock or any other protocol shutdown; those are explicit calls. It is safe to call more than once.
func (*Conn) Dispatch ¶
Dispatch applies the events the reader queued and calls h for each one that matters to the application, on the calling goroutine. It handles at most one ring of events per call and signals Conn.Wake again if more are pending. A nil h discards the notifications but still applies the state changes. It returns the transport error once the queue is drained after the connection failed, and ErrClosed after Close.
func (*Conn) Display ¶
Display returns the underlying wlturbo display. Only the owner goroutine may call Dispatch or Roundtrip on it; use Conn.Dispatch and Conn.Roundtrip instead.
func (*Conn) Lock ¶
Lock requests a session lock. At most one lock is live per connection. The compositor answers through Handler.Locked or Handler.LockFinished.
func (*Conn) NewLayerSurface ¶
func (c *Conn) NewLayerSurface(cfg LayerConfig) (*Surface, error)
NewLayerSurface creates a wlr-layer-shell surface. It becomes presentable after the first Handler.Configure.
func (*Conn) NewToplevel ¶
NewToplevel creates an xdg-toplevel window with the given title and initial logical size. It becomes presentable after the first Handler.Configure.
func (*Conn) Outputs ¶
Outputs returns the outputs that finished their first description, ordered by Global. The slice is reused by the next call; owner goroutine only.
func (*Conn) Roundtrip ¶
Roundtrip sends wl_display.sync and dispatches until it returns. The reader is paused meanwhile; when Roundtrip returns, every event handled before the sync reply is queued for Conn.Dispatch (up to the ring capacity; the rest follows as the reader resumes).
func (*Conn) Seat ¶
Seat returns the connection's seat (nil after Close), binding wl_seat on first use. The seat is also bound when the first surface is created. Input starts flowing to the Handler once the compositor announces the capabilities.
func (*Conn) Wake ¶
func (c *Conn) Wake() <-chan struct{}
Wake returns a channel with capacity 1 that is signaled whenever events are queued: call Conn.Dispatch when it fires. A signal can be stale (the events were already drained), so Dispatch may find nothing to do.
type CursorShape ¶
type CursorShape uint32
CursorShape is a wp_cursor_shape_v1 shape. The values are the protocol's.
const ( CursorDefault CursorShape = iota + 1 CursorContextMenu CursorHelp CursorPointer CursorProgress CursorWait CursorCell CursorCrosshair CursorText CursorVerticalText CursorAlias CursorCopy CursorMove CursorNoDrop CursorNotAllowed CursorGrab CursorGrabbing CursorEResize CursorNResize CursorNEResize CursorNWResize CursorSResize CursorSEResize CursorSWResize CursorWResize CursorEWResize CursorNSResize CursorNESWResize CursorNWSEResize CursorColResize CursorRowResize CursorAllScroll CursorZoomIn CursorZoomOut CursorDndAsk // needs cursor-shape version 2 CursorAllResize // needs cursor-shape version 2 )
type Feedback ¶
type Feedback struct {
MainDevice uint64 // dev_t of the compositor's main device
Formats []Format // every tranche's formats, flattened in tranche order
}
Feedback is the latest complete linux-dmabuf feedback of a surface.
type Handler ¶
type Handler interface {
// OutputAdded reports an output that became complete after [Connect]
// returned: the compositor sent its first wl_output.done. Outputs that
// existed during Connect are not reported; read them with [Conn.Outputs].
// Later property changes are applied to [Conn.Outputs] silently. out is
// valid only during the call.
OutputAdded(out *Output)
// OutputRemoved reports that the wl_output global went away. The output is
// already gone from [Conn.Outputs].
OutputRemoved(global uint32)
// FDReady reports that a descriptor registered with [Conn.WatchFD] is
// readable. The watch is re-armed when the call returns. It can be
// spurious: drain the descriptor without blocking.
FDReady(id uint64)
// Error reports a non-fatal failure while handling an event, for example
// a wl_output that could not be bound. Fatal transport errors are returned
// by Dispatch instead.
Error(err error)
// Configure reports the logical size of a surface after the compositor's
// configure was acknowledged (the library acks internally). The first
// call makes the surface presentable. For layer surfaces an axis the
// compositor leaves unchanged keeps its previous size.
Configure(id SurfaceID, width, height int32)
// Scale reports a changed preferred scale: fractional (n/120) when the
// compositor supports wp_fractional_scale, else the integer buffer scale.
// Re-read [Surface.PhysicalSize] and render again.
Scale(id SurfaceID, scale float64)
// Frame reports that the frame callback requested by the last
// [Surface.Present] fired; the next Present is allowed.
Frame(id SurfaceID)
// Closed reports that the compositor closed the surface (toplevel close,
// layer surface closed). Call [Surface.Close]; nothing else happens
// automatically.
Closed(id SurfaceID)
// FeedbackDone reports that a complete linux-dmabuf feedback round was
// applied; [Surface.Feedback] holds the new main device and formats. It
// is sent again whenever the compositor changes its preference.
FeedbackDone(id SurfaceID)
// Locked reports ext_session_lock_v1.locked for the live [Lock]: every
// output is protected. Only now may [Lock.Unlock] be called.
Locked()
// LockFinished reports ext_session_lock_v1.finished: the compositor
// refused or ended the lock. Destroy it with [Lock.Close].
LockFinished()
// Pointer reports pointer input over one of the connection's surfaces:
// enter, leave, motion, buttons and scrolling. ev is valid only during the
// call.
Pointer(ev *PointerEvent)
// Key reports a key press, repeat or release for the surface that has
// keyboard focus. Text is the text the key produced (nil for releases and
// keys without text) and is valid only during the call. While a
// [SecretBuffer] is installed with [Seat.SetSecret], Text is always nil
// and the text goes into the buffer; see [Handler.SecretChanged]. For
// those keys (press, repeat and release) ev.Secret is set and Keycode and
// Keysym are 0, so the event does not reveal the typed character; Enter,
// Escape, BackSpace and Control combinations keep their keysym. ev is
// valid only during the call.
Key(ev *KeyEvent)
// KeyboardFocus reports that a surface gained or lost keyboard focus.
KeyboardFocus(id SurfaceID, focused bool)
// SecretChanged reports that a key press, repeat or backspace changed the
// installed [SecretBuffer]; count is its length in code points. It is
// called after the [Handler.Key] call of that key.
SecretChanged(count int)
}
Handler receives the events Conn.Dispatch drains. Every method is called on the goroutine that called Dispatch, never on the reader goroutine, so an implementation may send requests and call Conn.Bind, Conn.Roundtrip, Conn.WatchFD and Conn.UnwatchFD from inside any method. It must not call Dispatch.
type KeyEvent ¶
type KeyEvent struct {
Surface SurfaceID
Keycode uint32 // evdev key code; 0 when Secret is set
Keysym uint32 // xkb keysym in the current layout and modifier state; 0 when Secret is set
Modifiers Modifiers
Group uint32 // effective layout index
Pressed bool
Repeat bool
// Secret is set while a [SecretBuffer] is installed, for the press,
// repeats and release of a key that produced text (or is a dead or compose
// key): the text went into the buffer, and Keycode and Keysym are 0 so the
// event does not reveal which character was typed. Other keys (Enter,
// Escape, BackSpace, modifiers, Control combinations) keep their keysym.
Secret bool
// Text is the UTF-8 text of the key, nil for releases and keys without
// text. It aliases library storage that is wiped when Handler.Key
// returns. It is always nil while a [SecretBuffer] is installed.
Text []byte
}
KeyEvent is one key press, repeat or release.
type KeyboardMode ¶
type KeyboardMode uint8
KeyboardMode is the layer surface keyboard interactivity. The zero value is KeyboardNone. KeyboardOnDemand needs zwlr_layer_shell_v1 version 4.
const ( KeyboardNone KeyboardMode = iota KeyboardExclusive KeyboardOnDemand )
type LayerConfig ¶
type LayerConfig struct {
Output string // wl_output name; empty lets the compositor choose
Namespace string // defaults to [DefaultLayerNamespace]
Level LayerLevel
Anchors Anchor
Keyboard KeyboardMode
ExclusiveZone int32 // >0 reserves, 0 neutral, -1 ignores other zones
Margin [4]int32 // top, right, bottom, left
// InputRects, when non-nil, restricts pointer input to these rectangles
// (logical pixels). An empty non-nil slice makes the surface click-through.
InputRects []Rect
// Width and Height are the requested logical size. They are required on
// every axis that is not anchored to both opposite edges.
Width, Height int32
}
LayerConfig requests a wlr-layer-shell surface. Width and Height give the initial logical size; an axis anchored to both opposite edges is sized by the compositor and reported through Handler.Configure.
type LayerLevel ¶
type LayerLevel uint8
LayerLevel is the wlr-layer-shell stacking layer. The zero value is invalid.
const ( LayerBackground LayerLevel = iota + 1 LayerBottom LayerTop LayerOverlay )
type Lock ¶
type Lock struct {
// contains filtered or unexported fields
}
Lock is an ext-session-lock-v1 session lock. It reports Handler.Locked once every output is protected and Handler.LockFinished if the compositor refuses or ends it. Closing the connection or destroying surfaces never unlocks; only Lock.Unlock after Locked does. Owner goroutine only.
func (*Lock) Close ¶
Close destroys a lock that never reached Locked (refused or abandoned). A locked session is only ended by Unlock, so Close fails once Locked was applied. Because the compositor may have sent locked before it processes the destroy request (which would then be a protocol error), Close first roundtrips and looks through the queued events: if a locked event for this lock is already queued it is treated as applied (Handler.Locked is still delivered by the next Dispatch) and Close fails with the same error.
func (*Lock) Locked ¶
Locked reports whether the compositor confirmed the lock (applied by Dispatch) and it has not finished.
func (*Lock) NewSurface ¶
NewSurface creates the lock surface covering the output with the given registry name (see Output.Global). It becomes presentable after the first Handler.Configure; a lock surface is always opaque and takes all input.
type NopHandler ¶
type NopHandler struct{}
NopHandler implements every Handler method as a no-op. Embed it in a handler and override only the methods you need; methods added to Handler in later versions get their no-op here, so embedding keeps the type compiling.
func (NopHandler) Closed ¶
func (NopHandler) Closed(SurfaceID)
func (NopHandler) Error ¶
func (NopHandler) Error(error)
func (NopHandler) FDReady ¶
func (NopHandler) FDReady(uint64)
func (NopHandler) FeedbackDone ¶
func (NopHandler) FeedbackDone(SurfaceID)
func (NopHandler) Frame ¶
func (NopHandler) Frame(SurfaceID)
func (NopHandler) Key ¶
func (NopHandler) Key(*KeyEvent)
func (NopHandler) KeyboardFocus ¶
func (NopHandler) KeyboardFocus(SurfaceID, bool)
func (NopHandler) LockFinished ¶
func (NopHandler) LockFinished()
func (NopHandler) Locked ¶
func (NopHandler) Locked()
func (NopHandler) OutputAdded ¶
func (NopHandler) OutputAdded(*Output)
func (NopHandler) OutputRemoved ¶
func (NopHandler) OutputRemoved(uint32)
func (NopHandler) Pointer ¶
func (NopHandler) Pointer(*PointerEvent)
func (NopHandler) Scale ¶
func (NopHandler) Scale(SurfaceID, float64)
func (NopHandler) SecretChanged ¶
func (NopHandler) SecretChanged(int)
type Output ¶
type Output struct {
Global uint32 // registry name; identifies the output for its lifetime
Name string // wl_output.name, empty before version 4
Scale int32 // integer scale, 1 until announced
Width, Height int32 // current mode in physical pixels
}
Output describes one wl_output after its latest wl_output.done. Only wl_output globals of version 2 or later are bound (version 1 has no done event, so its description is never known to be complete); older ones are ignored.
type PointerEvent ¶
type PointerEvent struct {
Surface SurfaceID
Kind PointerKind
X, Y float64
DX, DY float64 // PointerAxis: continuous scroll value
Button uint32 // PointerButton: evdev button code
Pressed bool // PointerButton
Axis uint32 // PointerAxis, PointerAxisStop: AxisVertical or AxisHorizontal
Value120 int32 // PointerAxis: wheel value in 1/120 notches
}
PointerEvent is one pointer event over a surface of the connection. X and Y are surface-local logical pixels (already logical: never divide by scale) and hold the latest position for every kind.
type PointerKind ¶
type PointerKind uint8
PointerKind tells which pointer event a PointerEvent is.
const ( PointerEnter PointerKind = iota + 1 PointerLeave PointerMotion PointerButton // PointerAxis is a scroll step on Axis. DX or DY carry the continuous // value in logical pixels; Value120 carries the wheel value in 1/120 of a // notch. A compositor can send both for one physical step: use one. PointerAxis // PointerAxisStop ends a scroll sequence on Axis. PointerAxisStop )
type Present ¶
type Present struct {
Buffer uint64
AcquireTimeline uint64
ReleaseTimeline uint64
AcquirePoint uint64
ReleasePoint uint64
Damage []Rect // nil or empty damages the whole buffer
Opaque bool // the whole surface is opaque
}
Present describes one commit: which imported buffer, the explicit-sync timelines and points, and the damage in buffer pixels.
type Rect ¶
type Rect struct{ X, Y, Width, Height int32 }
Rect is an integer rectangle: surface-local logical pixels for input regions, buffer pixels for damage.
type Seat ¶
type Seat struct {
// contains filtered or unexported fields
}
Seat is the connection's first wl_seat: pointer, keyboard and cursor. It belongs to the owner goroutine. Without a seat global every method is a no-op. The seat is bound once, at first use: a seat announced later is not picked up, and a removed one is not replaced (no seat hotplug).
func (*Seat) SetCursor ¶
func (s *Seat) SetCursor(shape CursorShape) error
SetCursor asks the compositor to show shape for the pointer. It is a no-op when the compositor has no cursor-shape support, the pointer is outside the connection's surfaces, or shape is unchanged since the last enter.
func (*Seat) SetSecret ¶
func (s *Seat) SetSecret(b *SecretBuffer)
SetSecret installs b to receive typed text, or removes it with nil. While installed, printable text goes only into b and never into KeyEvent.Text; BackSpace removes one code point; every other key is still delivered as a KeyEvent without text. Keys that produced text are delivered with KeyEvent.Secret set and Keycode and Keysym 0, for the press, repeats and release; Enter, Escape, BackSpace and Control combinations keep their keysym. Installing or removing cancels held keys and repeat. The previous buffer is not wiped: that is the caller's call.
Limits: runtime/secret (GOEXPERIMENT=runtimesecret) erases Go registers, stack and heap temporaries, but not the native memory of libxkbcommon, which processes the key text.
type SecretBuffer ¶
type SecretBuffer struct {
// contains filtered or unexported fields
}
SecretBuffer collects text typed while it is installed with Seat.SetSecret, for example a password. Its storage is allocated once at full size, so it never reallocates and leaves no stale copies behind; the text is never turned into a string by the library.
Only the owner goroutine (the one calling Conn.Dispatch) may use it.
func NewSecretBuffer ¶
func NewSecretBuffer(capacity int) *SecretBuffer
NewSecretBuffer returns a buffer holding up to capacity code points. capacity is clamped to 1..4096.
func (*SecretBuffer) Bytes ¶
func (b *SecretBuffer) Bytes() []byte
Bytes returns the UTF-8 text held. The slice aliases the buffer: do not retain it, convert it to a string or log it; it changes on the next edit.
func (*SecretBuffer) Len ¶
func (b *SecretBuffer) Len() int
Len returns the number of code points held.
func (*SecretBuffer) Wipe ¶
func (b *SecretBuffer) Wipe()
Wipe zeroes the whole storage and empties the buffer.
type Surface ¶
type Surface struct {
// contains filtered or unexported fields
}
Surface is one wl_surface with its role and the DMA-BUF presentation objects. Every method belongs to the owner goroutine.
func (*Surface) Close ¶
Close destroys the surface, its buffers, timelines and role objects, children before parents. It is safe to call more than once. The caller must stop using buffers it imported first (the compositor keeps them until it processes the destruction).
func (*Surface) DestroyBuffer ¶
DestroyBuffer destroys an imported wl_buffer. The compositor may still read it until its release point signals; see the explicit-sync rules.
func (*Surface) DestroyTimeline ¶
DestroyTimeline destroys an imported timeline object. The id is the one given to Surface.ImportTimeline; it may be imported again afterwards. Do not destroy a timeline that a pending commit still references. Surface.Close destroys every remaining timeline.
func (*Surface) Feedback ¶
Feedback returns the latest complete dmabuf feedback, or nil before the first Handler.FeedbackDone. The value and its slice stay valid until the next FeedbackDone.
func (*Surface) ImportBuffer ¶
ImportBuffer creates a wl_buffer from b under the caller's id. The plane descriptors are duplicated internally; the caller keeps ownership of its own.
func (*Surface) ImportTimeline ¶
ImportTimeline imports a DRM syncobj timeline. fd is duplicated internally.
func (*Surface) PhysicalSize ¶
PhysicalSize returns the buffer size in pixels for the current logical size and scale.
func (*Surface) Present ¶
Present commits an imported buffer. It refuses before the first configure, before the first complete dmabuf feedback and while the previous frame callback is pending.
func (*Surface) SetInputRegion ¶
SetInputRegion sets the input region (logical pixels). nil restores the whole surface; a non-nil empty slice passes all input through. The region is double-buffered state: it is committed immediately only once the surface presented a buffer; before that the next Present applies it (committing earlier would map a surface without a buffer, which lock surfaces forbid and layer surfaces answer with an error). Lock surfaces always take all input and refuse it.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
secret
Package secret runs key translation that touches secret text under runtime/secret when the toolchain provides it (GOEXPERIMENT=runtimesecret), and plainly otherwise.
|
Package secret runs key translation that touches secret text under runtime/secret when the toolchain provides it (GOEXPERIMENT=runtimesecret), and plainly otherwise. |