detached 068ba85

docs(readme): introduce the library with a minimal counter

commit
068ba85462f9eef7712fe672e5d6d37af55390de
author
brice · · 2026-09-30 03:34 UTC
parent
d438c5c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +69 -28
M README.md +43 -28
@@ -1,49 +1,64 @@
11 # NeferGUI
22
3-Native immediate-mode GUI library for Go, built for Wayland with Vulkan rendering and CSS styling.
3+A native Go GUI library for Linux: Wayland windows, Vulkan rendering, and CSS styling. Build your view from the current model; controls return events during that call. No cgo required.
44
5-## Status
5+> [!WARNING]
6+> **Early development.** No release yet. Expect bugs and breaking changes. Platform accessibility is not connected.
67
7-NeferGUI is under active development and has no release yet.
8-
9-## Usage
8+## A small example
109
1110 ```go
12-type Model struct{ Name, Status string }
11+package main
1312
14-func view(f *nefergui.Frame, m *Model) {
15- root := f.Root(nefergui.Class("app"))
16- root.Input("Name", &m.Name, nefergui.Key("name"))
17- if root.Button("Greet", nefergui.Key("greet")).Activated() {
18- m.Status = "Hello " + m.Name
19- }
20- root.Text(m.Status)
21-}
13+import (
14+ "context"
15+ "fmt"
16+ "log"
17+
18+ "github.com/bnema/nefergui"
19+)
2220
2321 func main() {
24- var m Model
25- if err := nefergui.Run(context.Background(), &m, view, nefergui.Title("Hello"), nefergui.Size(640, 480), nefergui.Styles("app.css")); err != nil {
22+ count := 0
23+ view := func(f *nefergui.Frame, count *int) {
24+ root := f.Root().Column()
25+ root.Text("Hello, Wayland!")
26+ if root.Button("Count", nefergui.Key("count")).Activated() {
27+ *count++
28+ }
29+ root.Text(fmt.Sprintf("Clicked %d times", *count))
30+ }
31+ if err := nefergui.Run(context.Background(), &count, view,
32+ nefergui.Title("Hello"), nefergui.Size(320, 200)); err != nil {
2633 log.Fatal(err)
2734 }
2835 }
2936 ```
3037
31-Runtime requirements: a Wayland compositor with linux-dmabuf and linux-drm-syncobj, `libvulkan.so.1` and `libxkbcommon.so.0`. Builds with `CGO_ENABLED=0`. See [docs/runtime.md](docs/runtime.md) and `examples/demo`.
38+Default styles work without a stylesheet; `nefergui.Styles("app.css")` loads your own CSS.
3239
33-## Documentation
40+## Try it
3441
35-- [CSS properties and limitations](docs/css.md)
36-- [Layout](docs/layout.md) · [Controls](docs/controls.md) · [Runtime](docs/runtime.md)
37-- [Troubleshooting](docs/troubleshooting.md) · [Harness](docs/harness.md) · [Performance](docs/performance.md)
42+Requires Go 1.27, `libvulkan.so.1`, `libxkbcommon.so.0`, usable fonts, and a Wayland compositor supporting linux-dmabuf and linux-drm-syncobj. Fractional scaling also requires viewporter. No X11 or software-rendering fallback.
3843
39-## Design records
44+```sh
45+go get github.com/bnema/nefergui
46+```
47+
48+From a checkout, run the [demo](examples/demo):
49+
50+```sh
51+CGO_ENABLED=0 go run ./examples/demo
52+```
4053
41-- [0002 Wayland bindings and FD ownership](docs/adr/0002-wayland-bindings-and-fd-ownership.md)
42-- [0003 Vulkan presentation through DMA-BUF](docs/adr/0003-vulkan-dmabuf-presentation.md)
43-- [0004 Keyboard interpretation](docs/adr/0004-keyboard.md)
44-- [0005 Immediate-mode identity and events](docs/adr/0005-identity-and-events.md)
45-- [0006 CSS and text scope](docs/adr/0006-css-and-text-scope.md)
54+## Documentation
55+
56+- [Controls](docs/controls.md) and [layout](docs/layout.md)
57+- [CSS properties and limitations](docs/css.md)
58+- [Runtime requirements and behavior](docs/runtime.md) and [troubleshooting](docs/troubleshooting.md)
59+- [Visual test harness](docs/harness.md) and [performance](docs/performance.md)
60+- [Architecture decisions](docs/adr)
4661
4762 ## License
4863
49-NeferGUI is licensed under [GNU GPL v3](LICENSE). Third-party code and test fonts retain their licenses and attribution notices in their respective directories.
64+[GNU GPL v3](LICENSE). Third-party code and test fonts retain their own licenses and attribution.
@@ -1,49 +1,64 @@
1 # NeferGUI1 # NeferGUI
2 2
3-Native immediate-mode GUI library for Go, built for Wayland with Vulkan rendering and CSS styling.3+A native Go GUI library for Linux: Wayland windows, Vulkan rendering, and CSS styling. Build your view from the current model; controls return events during that call. No cgo required.
4 4
5-## Status5+> [!WARNING]
6+> **Early development.** No release yet. Expect bugs and breaking changes. Platform accessibility is not connected.
6 7
7-NeferGUI is under active development and has no release yet.8+## A small example
8-
9-## Usage
10 9
11 ```go10 ```go
12-type Model struct{ Name, Status string }11+package main
13 12
14-func view(f *nefergui.Frame, m *Model) {13+import (
15- root := f.Root(nefergui.Class("app"))14+ "context"
16- root.Input("Name", &m.Name, nefergui.Key("name"))15+ "fmt"
17- if root.Button("Greet", nefergui.Key("greet")).Activated() {16+ "log"
18- m.Status = "Hello " + m.Name17+
19- }18+ "github.com/bnema/nefergui"
20- root.Text(m.Status)19+)
21-}
22 20
23 func main() {21 func main() {
24- var m Model22+ count := 0
25- if err := nefergui.Run(context.Background(), &m, view, nefergui.Title("Hello"), nefergui.Size(640, 480), nefergui.Styles("app.css")); err != nil {23+ view := func(f *nefergui.Frame, count *int) {
24+ root := f.Root().Column()
25+ root.Text("Hello, Wayland!")
26+ if root.Button("Count", nefergui.Key("count")).Activated() {
27+ *count++
28+ }
29+ root.Text(fmt.Sprintf("Clicked %d times", *count))
30+ }
31+ if err := nefergui.Run(context.Background(), &count, view,
32+ nefergui.Title("Hello"), nefergui.Size(320, 200)); err != nil {
26 log.Fatal(err)33 log.Fatal(err)
27 }34 }
28 }35 }
29 ```36 ```
30 37
31-Runtime requirements: a Wayland compositor with linux-dmabuf and linux-drm-syncobj, `libvulkan.so.1` and `libxkbcommon.so.0`. Builds with `CGO_ENABLED=0`. See [docs/runtime.md](docs/runtime.md) and `examples/demo`.38+Default styles work without a stylesheet; `nefergui.Styles("app.css")` loads your own CSS.
32 39
33-## Documentation40+## Try it
34 41
35-- [CSS properties and limitations](docs/css.md)42+Requires Go 1.27, `libvulkan.so.1`, `libxkbcommon.so.0`, usable fonts, and a Wayland compositor supporting linux-dmabuf and linux-drm-syncobj. Fractional scaling also requires viewporter. No X11 or software-rendering fallback.
36-- [Layout](docs/layout.md) · [Controls](docs/controls.md) · [Runtime](docs/runtime.md)
37-- [Troubleshooting](docs/troubleshooting.md) · [Harness](docs/harness.md) · [Performance](docs/performance.md)
38 43
39-## Design records44+```sh
45+go get github.com/bnema/nefergui
46+```
47+
48+From a checkout, run the [demo](examples/demo):
49+
50+```sh
51+CGO_ENABLED=0 go run ./examples/demo
52+```
40 53
41-- [0002 Wayland bindings and FD ownership](docs/adr/0002-wayland-bindings-and-fd-ownership.md)54+## Documentation
42-- [0003 Vulkan presentation through DMA-BUF](docs/adr/0003-vulkan-dmabuf-presentation.md)55+
43-- [0004 Keyboard interpretation](docs/adr/0004-keyboard.md)56+- [Controls](docs/controls.md) and [layout](docs/layout.md)
44-- [0005 Immediate-mode identity and events](docs/adr/0005-identity-and-events.md)57+- [CSS properties and limitations](docs/css.md)
45-- [0006 CSS and text scope](docs/adr/0006-css-and-text-scope.md)58+- [Runtime requirements and behavior](docs/runtime.md) and [troubleshooting](docs/troubleshooting.md)
59+- [Visual test harness](docs/harness.md) and [performance](docs/performance.md)
60+- [Architecture decisions](docs/adr)
46 61
47 ## License62 ## License
48 63
49-NeferGUI is licensed under [GNU GPL v3](LICENSE). Third-party code and test fonts retain their licenses and attribution notices in their respective directories.64+[GNU GPL v3](LICENSE). Third-party code and test fonts retain their own licenses and attribution.
A readme_example_test.go +26 -0
@@ -0,0 +1,26 @@
1+package nefergui_test
2+
3+import (
4+ "context"
5+ "fmt"
6+ "log"
7+
8+ "github.com/bnema/nefergui"
9+)
10+
11+// Compile the README example without opening a window during tests.
12+func Example_counter() {
13+ count := 0
14+ view := func(f *nefergui.Frame, count *int) {
15+ root := f.Root().Column()
16+ root.Text("Hello, Wayland!")
17+ if root.Button("Count", nefergui.Key("count")).Activated() {
18+ *count++
19+ }
20+ root.Text(fmt.Sprintf("Clicked %d times", *count))
21+ }
22+ if err := nefergui.Run(context.Background(), &count, view,
23+ nefergui.Title("Hello"), nefergui.Size(320, 200)); err != nil {
24+ log.Fatal(err)
25+ }
26+}
@@ -0,0 +1,26 @@
1+package nefergui_test
2+
3+import (
4+ "context"
5+ "fmt"
6+ "log"
7+
8+ "github.com/bnema/nefergui"
9+)
10+
11+// Compile the README example without opening a window during tests.
12+func Example_counter() {
13+ count := 0
14+ view := func(f *nefergui.Frame, count *int) {
15+ root := f.Root().Column()
16+ root.Text("Hello, Wayland!")
17+ if root.Button("Count", nefergui.Key("count")).Activated() {
18+ *count++
19+ }
20+ root.Text(fmt.Sprintf("Clicked %d times", *count))
21+ }
22+ if err := nefergui.Run(context.Background(), &count, view,
23+ nefergui.Title("Hello"), nefergui.Size(320, 200)); err != nil {
24+ log.Fatal(err)
25+ }
26+}

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