v0.2.1 c0399be

README.md RawHistoryFolder

Puregotk

NOTE: This library is currently expiremental and needs thorough testing. Some APIs might be incorrectly exposed

Autogenerated GTK4+Adwaita bindings for Go leveraging purego

Motivation

I created this library because I found that alternative libraries using Cgo had much too slow compilation speed. For my laptop around 15 minutes to build a simple example (without build cache) for gotk3 and also gotk4. Whilst this is maybe not a big problem for development, I found it annoying for CI and package building where you would not want to rely on a cache. Additionally, having Cgo involved means harder cross compilation.

This is not a fault for these libraries as CGo compilation is just inherently slow in Go. In this project I want to test a new approach by levering purego which allows you to load libraries using dlopen without needing cgo.

Compilation speed currently is around 40 seconds for me on basic examples.

Advantages

No Cgo needed, thus:

  • Easy cross compilation
  • No C toolchain needed
  • Much faster compile times than alternatives like gotk3 & gotk4

Disadvantages

Limitations of this library as compared to the alternatives using cgo:

  • Some APIs are not possible due to purego not currently supporting struct arguments (that are not pointers)

Planned features

In order of priority:

  • General code cleanup
  • Support for OS other than Linux (I only test on Linux currently)
  • GTK 3 support
  • Architectures other than AMD64/ARM64

Basic example

package main

import (
	"os"

	"github.com/jwijenbergh/puregotk/v4/gio"
	"github.com/jwijenbergh/puregotk/v4/gtk"
)

func main() {
	app := gtk.NewApplication("com.github.jwijenbergh.puregotk.gtk4.hello", gio.GApplicationFlagsNoneValue)
	// cleanup, no finalizers are used in this library
	defer app.Unref()
	// functions with callback arguments take function pointers
	// this is for internal re-use of callbacks
	actcb := func(_ gio.Application) {
		activate(app)
	}
	app.ConnectActivate(&actcb)

	if code := app.Run(len(os.Args), os.Args); code > 0 {
		os.Exit(code)
	}
}

func activate(app *gtk.Application) {
	window := gtk.NewApplicationWindow(app)
	window.SetTitle("purego")
	label := gtk.NewLabel("Hello, World!")
	window.SetChild(&label.Widget)
	// cleanup, no finalizers are used in this library
	label.Unref()
	window.SetDefaultSize(500, 500)
	window.Present()
}

Save this to a main.go and then build & run with

go run main.go

NOTE: You can also use CGO_ENABLED=0 to build without cgo!

Library loading

Because the GTK libs are loading at runtime (in init), we have to know where your libs are located. The default configuration is a "just works" configuration, we hardcode some paths that are common.

However, for systems such as NixOS or distros that use other paths the following environment variables might help:

  • PUREGOTK_LIB_FOLDER, set this to the root folder where all libs are stored e.g. /some/path/
  • PUREGOTK_LIBNAME_PATH where LIBNAME is the name of the library, e.g. PUREGOTK_GTK_PATH for the file path to GTK e.g. /some/path/libgtk-4.so. You have to do this for all deps, e.g. cairo, pango, etc

See https://github.com/jwijenbergh/puregotk/blob/main/internal/core/core.go for exact implementation details.

Additionally we also have a fallback to pkg-config, but I would say only rely on this as a last effort due to the increased startup time. When packaging code, always make sure that correct paths are used by e.g. using the aforementioned environment variables.

Generating the library

This library is automatically generated by reading GIR files.

To generate the library, run:

./gen.sh

In the root of the project. This needs:

License

MIT

Acknowledgements

  • Purego and the ebitengine team for their great work
  • gotk4 for some GIR type definitions
  • gtk of course
source
1# Puregotk
2
3> **_NOTE:_**  This library is currently expiremental and needs thorough testing. Some APIs might be incorrectly exposed
4
5Autogenerated GTK4+Adwaita bindings for Go leveraging [purego](https://github.com/ebitengine/purego)
6
7# Motivation
8I created this library because I found that alternative libraries using Cgo had much too slow compilation speed. For my laptop around 15 minutes to build a simple example (*without build cache*) for [gotk3](https://github.com/gotk3/gotk3) and also [gotk4](https://github.com/diamondburned/gotk4). Whilst this is maybe not a big problem for development, I found it annoying for CI and package building where you would not want to rely on a cache. Additionally, having [Cgo](https://pkg.go.dev/cmd/cgo) involved means harder cross compilation.
9
10This is not a fault for these libraries as CGo compilation is just inherently slow in Go. In this project I want to test a new approach by levering purego which allows you to load libraries using dlopen without needing cgo.
11
12Compilation speed currently is around 40 seconds for me on basic examples.
13
14## Advantages
15
16No Cgo needed, thus:
17* Easy cross compilation
18* No C toolchain needed
19* Much faster compile times than alternatives like [gotk3](https://github.com/gotk3/gotk3) & [gotk4](https://github.com/diamondburned/gotk4)
20  
21## Disadvantages
22
23Limitations of this library as compared to the alternatives using cgo:
24* Some APIs are not possible due to purego not currently supporting struct arguments (that are not pointers)
25
26# Planned features
27In order of priority:
28* General code cleanup
29* Support for OS other than Linux (I only test on Linux currently)
30* GTK 3 support
31* Architectures other than AMD64/ARM64
32
33# Basic example
34
35```go
36package main
37
38import (
39	"os"
40
41	"github.com/jwijenbergh/puregotk/v4/gio"
42	"github.com/jwijenbergh/puregotk/v4/gtk"
43)
44
45func main() {
46	app := gtk.NewApplication("com.github.jwijenbergh.puregotk.gtk4.hello", gio.GApplicationFlagsNoneValue)
47	// cleanup, no finalizers are used in this library
48	defer app.Unref()
49	// functions with callback arguments take function pointers
50	// this is for internal re-use of callbacks
51	actcb := func(_ gio.Application) {
52		activate(app)
53	}
54	app.ConnectActivate(&actcb)
55
56	if code := app.Run(len(os.Args), os.Args); code > 0 {
57		os.Exit(code)
58	}
59}
60
61func activate(app *gtk.Application) {
62	window := gtk.NewApplicationWindow(app)
63	window.SetTitle("purego")
64	label := gtk.NewLabel("Hello, World!")
65	window.SetChild(&label.Widget)
66	// cleanup, no finalizers are used in this library
67	label.Unref()
68	window.SetDefaultSize(500, 500)
69	window.Present()
70}
71```
72
73Save this to a main.go and then build & run with
74
75```bash
76go run main.go
77```
78
79> **_NOTE:_**  You can also use `CGO_ENABLED=0` to build without cgo!
80
81# Library loading
82Because the GTK libs are loading at runtime (in `init`), we have to know where your libs are located.
83The default configuration is a "just works" configuration, we hardcode some paths that are common. 
84
85However, for systems such as NixOS or distros that use other paths the following environment variables might help:
86
87- `PUREGOTK_LIB_FOLDER`, set this to the root folder where all libs are stored e.g. `/some/path/`
88- `PUREGOTK_LIBNAME_PATH` where `LIBNAME` is the name of the library, e.g. `PUREGOTK_GTK_PATH` for the file path to GTK e.g. `/some/path/libgtk-4.so`. You have to do this for all deps, e.g. cairo, pango, etc
89
90See https://github.com/jwijenbergh/puregotk/blob/main/internal/core/core.go for exact implementation details.
91
92Additionally we also have a fallback to `pkg-config`, but I would say only rely on this as a last effort due to the increased startup time.
93When packaging code, always make sure that correct paths are used by e.g. using the aforementioned environment variables.
94
95# Generating the library
96This library is automatically generated by reading GIR files.
97
98To generate the library, run:
99
100```bash
101./gen.sh
102```
103
104In the root of the project. This needs:
105
106- Go >= 1.20
107- [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports)
108
109# License
110
111[MIT](./LICENSE)
112
113# Acknowledgements
114* [Purego](https://github.com/ebitengine/purego) and the ebitengine team for their great work
115* [gotk4](https://github.com/diamondburned/gotk4) for some GIR type definitions
116* [gtk](https://gitlab.gnome.org/gnome/gtk) of course

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 102

↑↓ moveenter openesc close