v0.5.0 5fd5066

README.md RawHistoryFolder

NeferGUI

A pure-Go GUI renderer for Linux: build your view from the current model, style it with CSS, and draw it with Vulkan into DMA-BUF buffers. Controls return events during the view call. No cgo required.

NeferGUI imports no Wayland library. Your application owns the Wayland client (connection, surface, linux-dmabuf feedback, buffer import, seat events) and drives a Renderer; github.com/bnema/neferclient is a client toolkit built for this. The two do not import each other: the application copies plain fields between them.

[!WARNING] Early development. No release yet. Expect bugs and breaking changes. Platform accessibility is not connected.

A small example

The view is plain Go. The model type is yours.

type Model struct{ Count int }

view := func(f *nefergui.Frame, m *Model) {
	root := f.Root().Column()
	root.Text("Hello, Wayland!")
	if root.Button("Count", nefergui.Key("count")).Activated() {
		m.Count++
	}
	root.Text(fmt.Sprintf("Clicked %d times", m.Count))
}

The client loop, on one owner goroutine:

r, err := nefergui.NewRenderer(nefergui.RendererConfig{MainDevice: dev, Formats: formats})
r.Resize(320, 200, 1)          // on configure and scale changes
r.Input(&nefergui.Input{...})  // for each pointer, key and focus event

var out nefergui.Output
if ok, err := r.Render(&out, &model, view); ok && err == nil {
	// import out.Planes as a wl_buffer when out.NewBuffer, attach with the
	// acquire/release points, commit
}
r.Released(buffer) // when out.ReleaseFD becomes readable

RendererConfig.Styles loads your own CSS; default styles work without it. See ExampleRenderer and runtime for the full contract.

Requirements

Go 1.27, libvulkan.so.1 and usable fonts. The GPU must export DMA-BUF and support DRM syncobj timelines (kernel 6.6 or later for eventfd waits). The compositor, reached through your Wayland client, must offer linux-dmabuf and linux-drm-syncobj; fractional scaling also needs viewporter. No X11 or software-rendering fallback.

go get github.com/bnema/nefergui

Documentation

License

GNU GPL v3. Third-party code and test fonts retain their own licenses and attribution.

source
1# NeferGUI
2
3A pure-Go GUI renderer for Linux: build your view from the current model, style it with CSS, and draw it with Vulkan into DMA-BUF buffers. Controls return events during the view call. No cgo required.
4
5NeferGUI imports no Wayland library. Your application owns the Wayland client (connection, surface, linux-dmabuf feedback, buffer import, seat events) and drives a `Renderer`; [github.com/bnema/neferclient](https://github.com/bnema/neferclient) is a client toolkit built for this. The two do not import each other: the application copies plain fields between them.
6
7> [!WARNING]
8> **Early development.** No release yet. Expect bugs and breaking changes. Platform accessibility is not connected.
9
10## A small example
11
12The view is plain Go. The model type is yours.
13
14```go
15type Model struct{ Count int }
16
17view := func(f *nefergui.Frame, m *Model) {
18	root := f.Root().Column()
19	root.Text("Hello, Wayland!")
20	if root.Button("Count", nefergui.Key("count")).Activated() {
21		m.Count++
22	}
23	root.Text(fmt.Sprintf("Clicked %d times", m.Count))
24}
25```
26
27The client loop, on one owner goroutine:
28
29```go
30r, err := nefergui.NewRenderer(nefergui.RendererConfig{MainDevice: dev, Formats: formats})
31r.Resize(320, 200, 1)          // on configure and scale changes
32r.Input(&nefergui.Input{...})  // for each pointer, key and focus event
33
34var out nefergui.Output
35if ok, err := r.Render(&out, &model, view); ok && err == nil {
36	// import out.Planes as a wl_buffer when out.NewBuffer, attach with the
37	// acquire/release points, commit
38}
39r.Released(buffer) // when out.ReleaseFD becomes readable
40```
41
42`RendererConfig.Styles` loads your own CSS; default styles work without it. See `ExampleRenderer` and [runtime](docs/runtime.md) for the full contract.
43
44## Requirements
45
46Go 1.27, `libvulkan.so.1` and usable fonts. The GPU must export DMA-BUF and support DRM syncobj timelines (kernel 6.6 or later for eventfd waits). The compositor, reached through your Wayland client, must offer linux-dmabuf and linux-drm-syncobj; fractional scaling also needs viewporter. No X11 or software-rendering fallback.
47
48```sh
49go get github.com/bnema/nefergui
50```
51
52## Documentation
53
54- [Controls](docs/controls.md) and [layout](docs/layout.md)
55- [CSS properties and limitations](docs/css.md)
56- [Runtime requirements and behavior](docs/runtime.md) and [troubleshooting](docs/troubleshooting.md)
57- [Performance](docs/performance.md)
58- [Architecture decisions](docs/adr)
59
60## License
61
62[GNU GPL v3](LICENSE). Third-party code and test fonts retain their own licenses and attribution.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 12

↑↓ moveenter openesc close