detached 5004296

README.md RawHistoryFolder

go-wayland-bindings

Go bindings for the Wayland protocols, generated from vendored upstream XML. One module is the single source of truth for both sides of the wire:

  • client/<pkg>: client bindings for the pure-Go wlturbo runtime.
  • server/<pkg>: server bindings for the libwayland-server runtime in purego-libwayland.

Everything builds with CGO_ENABLED=0.

Install

go get github.com/bnema/go-wayland-bindings@latest

Usage

Client (the runtime lives in github.com/bnema/wlturbo):

import (
	"github.com/bnema/wlturbo/wl"

	"github.com/bnema/go-wayland-bindings/client/wayland"
)

display, err := wl.Connect("")
// ...
compositor := wayland.NewCompositor(display.Context())
err = display.Registry().Bind(name, wayland.CompositorInterface, 1, compositor)

Server (the runtime lives in github.com/bnema/purego-libwayland/server):

import (
	"github.com/bnema/purego-libwayland/server"

	"github.com/bnema/go-wayland-bindings/server/wayland"
)

err := wayland.NewCompositorGlobal(display, 6, func(c server.Client, version, id uint32) {
	_, _ = wayland.NewCompositor(c, int32(version), id, myCompositorHandler{})
})

Packages

A package name derives from the XML file name: drop .xml, drop a trailing -unstable-vN, then a trailing -vN, then remove every -. So xdg-shell.xml is xdgshell, wlr-layer-shell-unstable-v1.xml is wlrlayershell, and wayland.xml is wayland. The package has the same name under client/ and server/. When several upstream versions of one protocol exist, the most stable and then highest version is used; there is one major version per protocol.

The full list, with upstream source, path, license and interfaces, is in spec/manifest.json.

Custom protocol XML

wlbgen generates bindings for a private protocol XML. Interfaces it references from the vendored protocols (such as wl_surface) are resolved automatically to the matching client/<pkg> or server/<pkg> package:

go run github.com/bnema/go-wayland-bindings/cmd/wlbgen \
    -side server -package mything -out mything_generated.go mything.xml

Use -side client for client bindings. -import iface=importpath overrides the package of one interface (repeatable); an interface that cannot be resolved is an error.

Development

Regenerate every binding from spec/manifest.json:

go generate ./...

Generated output is deterministic: a second run changes nothing. Hand-written files that live next to generated code (for example client/linuxdmabuf/table.go) are never touched.

Sync the vendored XML with upstream (needs network and git):

go run ./cmd/wlbsync            # update spec/xml and spec/manifest.json
go run ./cmd/wlbsync -check     # print changed=true|false, write nothing
go run ./cmd/wlbsync -notes notes.md

spec/manifest.json is written by wlbsync and is never edited by hand.

Releases

A scheduled workflow syncs upstream every day. When protocol XML changed it regenerates the bindings, runs the checks and publishes a new minor version v0.X.0 whose release notes list added and removed packages, interface version bumps and breaking changes. A moved upstream ref with identical XML publishes nothing, and neither does a failed run.

Tests

env CGO_ENABLED=0 go test ./...
go test -race ./...          # needs libwayland-server installed

The end-to-end tests in internal/e2e (and the race run) need libwayland-server.so.0, which the server runtime loads at run time. Without it those tests are skipped, with the reason shown by go test -v; any other server start failure still fails them.

Two environment variables enable tests that are skipped by default:

  • WLTURBO_HEADLESS: path to a headless compositor binary (NeferWL) for the end-to-end tests in client/.
  • WLTURBO_LIVE: set to 1 to run the tests that talk to the compositor of the current session.

Licenses

The code of this repository (generators, tooling, tests) is MIT licensed, copyright go-wayland-bindings contributors; see LICENSE.

The vendored XML and the bindings generated from it keep the license of the upstream protocol; each generated file carries the upstream copyright notice. Most protocols are MIT. The serverdecoration protocol (KDE server-decoration.xml) is LGPL-2.1-or-later; its text is in LICENSES/.

source
1# go-wayland-bindings
2
3Go bindings for the Wayland protocols, generated from vendored upstream XML.
4One module is the single source of truth for both sides of the wire:
5
6- `client/<pkg>`: client bindings for the pure-Go
7  [wlturbo](https://github.com/bnema/wlturbo) runtime.
8- `server/<pkg>`: server bindings for the libwayland-server runtime in
9  [purego-libwayland](https://github.com/bnema/purego-libwayland).
10
11Everything builds with `CGO_ENABLED=0`.
12
13## Install
14
15```sh
16go get github.com/bnema/go-wayland-bindings@latest
17```
18
19## Usage
20
21Client (the runtime lives in `github.com/bnema/wlturbo`):
22
23```go
24import (
25	"github.com/bnema/wlturbo/wl"
26
27	"github.com/bnema/go-wayland-bindings/client/wayland"
28)
29
30display, err := wl.Connect("")
31// ...
32compositor := wayland.NewCompositor(display.Context())
33err = display.Registry().Bind(name, wayland.CompositorInterface, 1, compositor)
34```
35
36Server (the runtime lives in `github.com/bnema/purego-libwayland/server`):
37
38```go
39import (
40	"github.com/bnema/purego-libwayland/server"
41
42	"github.com/bnema/go-wayland-bindings/server/wayland"
43)
44
45err := wayland.NewCompositorGlobal(display, 6, func(c server.Client, version, id uint32) {
46	_, _ = wayland.NewCompositor(c, int32(version), id, myCompositorHandler{})
47})
48```
49
50## Packages
51
52A package name derives from the XML file name: drop `.xml`, drop a trailing
53`-unstable-vN`, then a trailing `-vN`, then remove every `-`. So
54`xdg-shell.xml` is `xdgshell`, `wlr-layer-shell-unstable-v1.xml` is
55`wlrlayershell`, and `wayland.xml` is `wayland`. The package has the same name
56under `client/` and `server/`. When several upstream versions of one protocol
57exist, the most stable and then highest version is used; there is one major
58version per protocol.
59
60The full list, with upstream source, path, license and interfaces, is in
61[`spec/manifest.json`](spec/manifest.json).
62
63## Custom protocol XML
64
65`wlbgen` generates bindings for a private protocol XML. Interfaces it
66references from the vendored protocols (such as `wl_surface`) are resolved
67automatically to the matching `client/<pkg>` or `server/<pkg>` package:
68
69```sh
70go run github.com/bnema/go-wayland-bindings/cmd/wlbgen \
71    -side server -package mything -out mything_generated.go mything.xml
72```
73
74Use `-side client` for client bindings. `-import iface=importpath` overrides
75the package of one interface (repeatable); an interface that cannot be
76resolved is an error.
77
78## Development
79
80Regenerate every binding from `spec/manifest.json`:
81
82```sh
83go generate ./...
84```
85
86Generated output is deterministic: a second run changes nothing. Hand-written
87files that live next to generated code (for example
88`client/linuxdmabuf/table.go`) are never touched.
89
90Sync the vendored XML with upstream (needs network and `git`):
91
92```sh
93go run ./cmd/wlbsync            # update spec/xml and spec/manifest.json
94go run ./cmd/wlbsync -check     # print changed=true|false, write nothing
95go run ./cmd/wlbsync -notes notes.md
96```
97
98`spec/manifest.json` is written by `wlbsync` and is never edited by hand.
99
100## Releases
101
102A scheduled workflow syncs upstream every day. When protocol XML changed it
103regenerates the bindings, runs the checks and publishes a new minor version
104`v0.X.0` whose release notes list added and removed packages, interface
105version bumps and breaking changes. A moved upstream ref with identical XML
106publishes nothing, and neither does a failed run.
107
108## Tests
109
110```sh
111env CGO_ENABLED=0 go test ./...
112go test -race ./...          # needs libwayland-server installed
113```
114
115The end-to-end tests in `internal/e2e` (and the race run) need
116`libwayland-server.so.0`, which the server runtime loads at run time. Without
117it those tests are skipped, with the reason shown by `go test -v`; any other
118server start failure still fails them.
119
120Two environment variables enable tests that are skipped by default:
121
122- `WLTURBO_HEADLESS`: path to a headless compositor binary (NeferWL) for the
123  end-to-end tests in `client/`.
124- `WLTURBO_LIVE`: set to `1` to run the tests that talk to the compositor of
125  the current session.
126
127## Licenses
128
129The code of this repository (generators, tooling, tests) is MIT licensed,
130copyright go-wayland-bindings contributors; see [`LICENSE`](LICENSE).
131
132The vendored XML and the bindings generated from it keep the license of the
133upstream protocol; each generated file carries the upstream copyright notice.
134Most protocols are MIT. The `serverdecoration` protocol (KDE
135`server-decoration.xml`) is LGPL-2.1-or-later; its text is in
136[`LICENSES/`](LICENSES/LGPL-2.1-or-later.txt).

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 1

↑↓ moveenter openesc close