Note that this project is largely unmaintained as I don't have the time to do or support more development. Please consider using this fork instead: https://github.com/jezek/xgb XGB is the X Go Binding, which is a low-level API to communicate with the core X protocol and many of the X extensions. It is closely modeled after XCB and xpyb. It is thread safe and gets immediate improvement from parallelism when GOMAXPROCS > 1. (See the benchmarks in xproto/xproto_test.go for evidence.) Please see doc.go for more info. Note that unless you know you need XGB, you can probably make your life easier by using a slightly higher level library: xgbutil. Quick Usage =========== go get github.com/BurntSushi/xgb go run go/path/src/github.com/BurntSushi/xgb/examples/create-window/main.go BurntSushi's Fork ================= I've forked the XGB repository from Google Code due to inactivty upstream. Godoc documentation can be found here: https://godoc.org/github.com/BurntSushi/xgb Much of the code has been rewritten in an effort to support thread safety and multiple extensions. Namely, go_client.py has been thrown away in favor of an xgbgen package. The biggest parts that *haven't* been rewritten by me are the connection and authentication handshakes. They're inherently messy, and there's really no reason to re-work them. The rest of XGB has been completely rewritten. I like to release my code under the WTFPL, but since I'm starting with someone else's work, I'm leaving the original license/contributor/author information in tact. I suppose I can legitimately release xgbgen under the WTFPL. To be fair, it is at least as complex as XGB itself. *sigh* What follows is the original README: XGB README ========== XGB is the X protocol Go language Binding. It is the Go equivalent of XCB, the X protocol C-language Binding (http://xcb.freedesktop.org/). Unless otherwise noted, the XGB source files are distributed under the BSD-style license found in the LICENSE file. Contributions should follow the same procedure as for the Go project: http://golang.org/doc/contribute.html
The X Go Binding is a low-level API to communicate with the X server. It is modeled on XCB and supports many X extensions.
Owner
Andrew Gallant
Comments
-
xgb produces non-recoverable panic when X server is closed
When an X server closes, normally or otherwise, xgb panics within a goroutine it has itself created, making the panic non-recoverable. As per Go convention, panics should really only be exposed/visible to the calling program if the programmer has made a mistake. In this case, the panic is preventing me from cleaning up a unix domain socket (by design, the kernel doesn't/won't ever do that for us), and in my case, I do need to do useful work after the X server is gone.
Stack trace follows:
XGB: xgb.go:371: A read error is unrecoverable. panic: EOF
goroutine 9 [running]: runtime.panic(0x58e2a0, 0xc208028060) /home/kevin/go/src/pkg/runtime/panic.c:278 +0xf8 github.com/BurntSushi/xgb.(*Conn).readResponses(0xc208078000) /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:372 +0x366 created by github.com/BurntSushi/xgb.NewConnDisplay /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:113 +0x20b
goroutine 1 [select]: main.Server(0xc20800a080, 0x11) /home/kevin/src/github.com/extemporalgenome/xrs/main.go:142 +0xb55 main.main() /home/kevin/src/github.com/extemporalgenome/xrs/main.go:85 +0x57b
goroutine 4 [finalizer wait]: runtime.park(0x421620, 0x6d6f10, 0x6d53da) /home/kevin/go/src/pkg/runtime/proc.c:1406 +0x9d runtime.parkunlock(0x6d6f10, 0x6d53da) /home/kevin/go/src/pkg/runtime/proc.c:1422 +0x3e runfinq() /home/kevin/go/src/pkg/runtime/mgc0.c:1659 +0xd8 runtime.goexit() /home/kevin/go/src/pkg/runtime/proc.c:1475
goroutine 5 [syscall]: os/signal.loop() /home/kevin/go/src/pkg/os/signal/signal_unix.go:21 +0x1e created by os/signal.init·1 /home/kevin/go/src/pkg/os/signal/signal_unix.go:27 +0x32
goroutine 17 [syscall, locked to thread]: runtime.goexit() /home/kevin/go/src/pkg/runtime/proc.c:1475
goroutine 6 [chan send]: github.com/BurntSushi/xgb.(*Conn).generateXIds(0xc208078000) /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:236 +0x1b5 created by github.com/BurntSushi/xgb.NewConnDisplay /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:110 +0x1c3
goroutine 7 [chan send]: github.com/BurntSushi/xgb.(*Conn).generateSeqIds(0xc208078000) /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:258 +0x71 created by github.com/BurntSushi/xgb.NewConnDisplay /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:111 +0x1db
goroutine 8 [chan receive]: github.com/BurntSushi/xgb.(*Conn).sendRequests(0xc208078000) /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:303 +0x7a created by github.com/BurntSushi/xgb.NewConnDisplay /home/kevin/src/github.com/BurntSushi/xgb/xgb.go:112 +0x1f3
goroutine 10 [IO wait]: net.runtime_pollWait(0x7f941c410b38, 0x72, 0x0) /home/kevin/go/src/pkg/runtime/netpoll.goc:146 +0x66 net.(_pollDesc).Wait(0xc20807a1b0, 0x72, 0x0, 0x0) /home/kevin/go/src/pkg/net/fd_poll_runtime.go:84 +0x46 net.(_pollDesc).WaitRead(0xc20807a1b0, 0x0, 0x0) /home/kevin/go/src/pkg/net/fd_poll_runtime.go:89 +0x42 net.(_netFD).accept(0xc20807a150, 0x0, 0x7f941c40f940, 0xb) /home/kevin/go/src/pkg/net/fd_unix.go:419 +0x344 net.(_UnixListener).AcceptUnix(0xc20800a380, 0xc208097f60, 0x0, 0x0) /home/kevin/go/src/pkg/net/unixsock_posix.go:282 +0x51 net.(*UnixListener).Accept(0xc20800a380, 0x0, 0x0, 0x0, 0x0) /home/kevin/go/src/pkg/net/unixsock_posix.go:293 +0x4b main.func·005() /home/kevin/src/github.com/extemporalgenome/xrs/main.go:116 +0x4d created by main.Server /home/kevin/src/github.com/extemporalgenome/xrs/main.go:131 +0x609
-
Don't use logger.Fatal
imho there is absolutely no excuse to use logger.Fatal in a library. logger.Fatal should only be used for debug-purposes (like an assert or something) or in an application where all behaviour is well-known. logger.Fatal calls os.Exit which in turn prevents other cleanup-operations (like removing files or similar). Therefore every well-written software should always return from main. Also, not every application that uses X should be considered „unrecoverable“ if the X-connection dies. (Consider a C-library that calls _exit(2) - not even exit(3) - which would almost certainly have undesirable side-effects).
The easiest „correct“ way to handle this would probably be to panic in the deeper nested calls and recover in the user-facing API-calls and gracefully returning an appropriate error.
-
Constructors for xproto.ClientMessageDataUnion always expects 20 bytes
I didn't look at the code of the other "constructors", but xproto.ClientMessageDataUnionData32New()` always expects a slice with 5 elements. It's very annoying if you have to pass additional arguments and it shouldn't be too hard to implement this or at least mention it in the documentation.
-
Not reciving DestroyNotifyEvents despite using EventMaskSubstructureNotify
In a similar fashion to #47 I am trying to receive
DestroyNotifyEvents
. I have registered the root window withEventMaskSubstructureNotify
yet don't receive any. My code to get the root window looks like thisfunc takeOwnership() error { return xproto.ChangeWindowAttributesChecked( xc, xroot.Root, xproto.CwEventMask, []uint32{ xproto.EventMaskButtonPress | xproto.EventMaskButtonRelease | xproto.EventMaskKeyPress | xproto.EventMaskKeyRelease | xproto.EventMaskStructureNotify | xproto.EventMaskSubstructureRedirect, }).Check() }
And my event loop case concerning
DestroyNotifyEvents
looks like this:case xproto.DestroyNotifyEvent: log.Println("destroy event registered") for _, w := range workspaces { go func(w *workspace) { if err := w.removeWindow(e.Window); err == nil { if err := w.TileWindows(); err != nil { log.Fatal(err) } } }(w) }
I am unsure of what I'm doing wrong or if this is an error with with package (which I do doubt) The whole source can be viewed here Many thanks in advance
-
Trying to get notified when a window gets closed
I'm trying to receive DestroyNotify events, to detect when a specific window has been closed. If I understand the Xlib docs correctly, I need to change the window attributes and add xproto.EventMaskStructureNotify to receive those notifications.
However I just can't seem to work it out. Could you provide an example for that scenario?
-
Server side connection close panic fix
Rewrite spawning of go routines upon new connection, so we can signal them and wait for them on connection close.
This fixes e.g. a panic in window example after window close:
$ go run examples/create-window/main.go Map window 71303169 successful! Checked Error for mapping window 0x1: BadWindow {NiceName: Window, Sequence: 5, BadValue: 0, MinorOpcode: 0, MajorOpcode: 8} Event: ReparentNotify {Sequence: 4, Event: 71303169, Window: 71303169, Parent: 11719003, X: 0, Y: 0, OverrideRedirect: false} Event: ConfigureNotify {Sequence: 4, Event: 71303169, Window: 71303169, AboveSibling: 0, X: 1, Y: 28, Width: 500, Height: 500, BorderWidth: 0, OverrideRedirect: false} Event: MapNotify {Sequence: 6, Event: 71303169, Window: 71303169, OverrideRedirect: false} XGB: xgb.go:403: A read error is unrecoverable: EOF XGB: xgb.go:403: A read error is unrecoverable: EOF panic: close of closed channel goroutine 23 [running]: github.com/BurntSushi/xgb.(*Conn).Close(...) /home/jezek/.go/src/github.com/BurntSushi/xgb/xgb.go:140 github.com/BurntSushi/xgb.(*Conn).readResponses(0xc4200c8000) /home/jezek/.go/src/github.com/BurntSushi/xgb/xgb.go:405 +0x25e created by github.com/BurntSushi/xgb.postNewConn /home/jezek/.go/src/github.com/BurntSushi/xgb/xgb.go:133 +0x232 exit status 2
to
$ go run examples/create-window/main.go Map window 71303169 successful! Checked Error for mapping window 0x1: BadWindow {NiceName: Window, Sequence: 5, BadValue: 0, MinorOpcode: 0, MajorOpcode: 8} Event: ReparentNotify {Sequence: 4, Event: 71303169, Window: 71303169, Parent: 11721679, X: 0, Y: 0, OverrideRedirect: false} Event: ConfigureNotify {Sequence: 4, Event: 71303169, Window: 71303169, AboveSibling: 0, X: 1, Y: 28, Width: 500, Height: 500, BorderWidth: 0, OverrideRedirect: false} Event: MapNotify {Sequence: 6, Event: 71303169, Window: 71303169, OverrideRedirect: false} XGB: xgb.go:433: A read error is unrecoverable: EOF XGB: xgb.go:597: Invalid event/error type: *errors.errorString Both event and error are nil. Exiting...
-
fix race condition in xgb.go
The xgb package has a data race exercised by the xproto tests and several example programs. The cookie sequence id is set concurrently with it being checked in an xproto Check call.
To resolve the race I've made the Conn.NewRequest method block until the request has been assigned a sequence id. I did that by adding a channel to the struct that is closed after a sequence id is assigned. It's a little bit of a hack but it seemed like the cleanest thing to do, due to the type being unexpected.
What do you think @BurntSushi?
-
xgb/record 's range size error
https://github.com/BurntSushi/xgb/blob/master/record/record.go#L312 the size of "range" is 24,
xgb.Pad will alignment 4 bytes.
This (https://github.com/BurntSushi/xgb/blob/master/record/record.go#L318) will cause "b" exceed 24 , so panic.
-
Xft support
Hi ! I need to draw some text on my windows using xgb. Drawing with X core fonts is working perfectly however as it has been deprecated for xft I was wondering how could I use it with xgb.
I didn't find any bindings for xft in go. Any ideas ?
Regards
-
Create-window example not working
When executing go run examples/create-window/main.go I get this errors:
Checked Error for mapping window 31457281: BadWindow {NiceName: Window, Sequence: 3, BadValue: 31457281, MinorOpcode: 0, MajorOpcode: 8} Checked Error for mapping window 0x1: BadWindow {NiceName: Window, Sequence: 5, BadValue: 0, MinorOpcode: 0, MajorOpcode: 8} Error: BadWindow {NiceName: Window, Sequence: 1, BadValue: 8781824, MinorOpcode: 0, MajorOpcode: 1} Error: BadWindow {NiceName: Window, Sequence: 2, BadValue: 31457281, MinorOpcode: 0, MajorOpcode: 2}
No windows appear and the program waits until I sigterm it. I ran a git-bisect on this and the problem appears revision c3541209a0fb8271645c882f7e4a4d7254823992 (the one about the Str type padding).I'm running Fedora 19, go version 1.2.
-
how do i use the record extension
Originally posted by @snyh in #14:
I'm curious about how use record extension.
I have modified record.go so that it didn't panic.
By run some code like below can cause xserver send a "RECOD-CONTEXTENABLE" when a key pressed or released(I use wireshark watched this), But the xgb will be blocked and print an warning(xgb.go:493).
record.Init(c) record.QueryVersion(c, 1, 13).Reply() rc, err := record.NewContextId(c) if err != nil { panic(err) } ranges := []record.Range{record.Range{}} ranges[0].DeviceEvents.First = xproto.KeyPress ranges[0].DeviceEvents.Last = xproto.ButtonRelease fmt.Println(ranges[0].Bytes()) clientspec := []record.ClientSpec{record.ClientSpec(record.CsAllClients)} record.CreateContextChecked(c, rc, record.ElementHeader(1), 1, 1, clientspec, ranges).Reply() record.RegisterClients(c, rc, record.ElementHeader(1), uint32(len(clientspec)), uint32(len(ranges)), clientspec, ranges).Reply() rr, err := record.EnableContext(c, rc).Reply()
-
Create go.mod
Without a
go.mod
, the build fails with error:go: go.mod file not found in current directory or any parent directory; see 'go help modules' go: go.mod file not found in current directory or any parent directory; see 'go help modules'
Note that since go 1.16, the
go
command will build packages in module-aware mode by default, see: https://go.dev/blog/go116-module-changes#modules-on-by-default -
Mz fixes
I prepared some small changes which prevent some edge cases of XGB usage.
I can reproduce the panic errors on Xvfb connections when Xvfb is killed externally. These changes will keep Go app alive just with a closed X server connection. There are still some questions on running go routines in BG (see new TODO comments).
I'm free to discuss changes and update PR.
-
xgc/res protocol / data size mismatch
Hi,
Calling
res.QueryClientIds(conn, 1, specs).Reply()
will crash due to an old bug inxcb/proto/src/res.xml
. The problem is located here: https://github.com/BurntSushi/xgb/blob/27f122750802c950b2c869a5b63dafcf590ced95/res/res.go#L170The
ClientIdValue.Length
we get from the server indicates the length in bytes, but the loop reads CARD32s.The bug has been fixed in the protocol description (see https://cgit.freedesktop.org/xcb/proto/commit/?id=f7948e355d85624c577d0fa63977b3bed4d6024f), but the X-Resource bindings will have to be re-generated from the updated
res.xml
(or edited manually) to fix this. -
Prevent panicking from goroutine if a read error is encountered.
Currently on MacOS, closing a window causes a panic inside a goroutine, which can't be recovered from. This is due to c.Close() being called more than once in the readResponses() method that encounters the error.
This change tries to propagate that error and breaks out of the for loop instead.
-
Determine if X recognized new monitors
Hi,
I got an issue:
I got a udev rule which launches a go routine when a monitor was connected/disconnected. That routine is using xgb. I configure the monitors depening on how they are (dis)connected. The udev rule works reliable in determining changes on the monitor setup. The problem is, that X or xgb needs some time to realize the change. Means: when my go routine is launched and checks for connected monitors it usually delivers the pre-plug/unplug state. I tried to wait for it with xgb.Sync but it didn't help. I tried to wait for events with xgb.Conn.WaitForEvent or xgb.Conn.PollForEvent but those never got me any events. Any recommendation how to solve that?
Related tags
A utility library to make use of the X Go Binding easier. (Implements EWMH and ICCCM specs, key binding support, etc.)
xgbutil is a utility library designed to work with the X Go Binding. This project's main goal is to make various X related tasks easier. For example,
Go binding for GTK
go-gtk WHATS Go bindings for GTK SCREENSHOT INSTALL You can experiment with go-gtk by running the various example programs: git clone https://github.c
Qt binding for Go (Golang) with support for Windows / macOS / Linux / FreeBSD / Android / iOS / Sailfish OS / Raspberry Pi / AsteroidOS / Ubuntu Touch / JavaScript / WebAssembly
Introduction Qt is a free and open-source widget toolkit for creating graphical user interfaces as well as cross-platform applications that run on var
Simple QML binding for Go
Qamel Qamel is a simple QML binding for Go, heavily inspired by therecipe/qt. This package only binds Qt's classes that used for creating a simple QML
SDL2 binding for Go
SDL2 binding for Go go-sdl2 is SDL2 wrapped for Go users. It enables interoperability between Go and the SDL2 library which is written in C. That mean
Qt binding for Go (Golang) aims get Go's compile speed again.
qt.go Qt5 binding for Go (Golang) without CGO that aims to achieve Go's native compile speeds. Instead of using common bindings and heavy C++ wrapper
Windows API and GUI in idiomatic Go.
Windigo Win32 API and GUI in idiomatic Go. Overview The UI library is divided in the following packages: Package Description ui High-level UI wrappers
Flutter on Windows, MacOS and Linux - based on Flutter Embedding, Go and GLFW.
go-flutter - A package that brings Flutter to the desktop Purpose Flutter allows you to build beautiful native apps on iOS and Android from a single c
Slice and dice your TMUX windows and panes
Chaakoo is a wrapper over TMUX that can create sessions, windows and panes from a grid based layout. The idea here is inspired by the CSS grid template areas.
Built Virtual Operating System and integrated application like calculator, gallery app , weather app, and text editor.
Virtual Operating System Built Virtual Operating System and integrated application like calculator, gallery app , weather app, and text editor. Langua
Native Go (golang) Graphical Interface system (2D and 3D), built on GoKi tree framework
GoGi is part of the GoKi Go language (golang) full strength tree structure system (ki = 木 = tree in Japanese) package gi is a scenegraph-based 2D and
Tiny cross-platform webview library for C/C++/Golang. Uses WebKit (Gtk/Cocoa) and Edge (Windows)
webview A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs. Also, there are Rust bindings, Python bindings, Ni
A package to build progressive web apps with Go programming language and WebAssembly.
go-app is a package to build progressive web apps (PWA) with Go programming language and WebAssembly. It uses a declarative syntax that allows creatin
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by Electron)
Thanks to go-astilectron build cross platform GUI apps with GO and HTML/JS/CSS. It is the official GO bindings of astilectron and is powered by Electr
Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs)
gowd Build cross platform GUI apps with GO and HTML/JS/CSS (powered by nwjs) How to use this library: Download and install nwjs Install this library g
a cross platfrom Go library to place an icon and menu in the notification area
systray is a cross-platform Go library to place an icon and menu in the notification area. Features Supported on Windows, macOS, and Linux Menu items
Cross-platform GUI for go is never this easy and clean.
gimu Strongly suggest NOT to use this project anymore, the auto-generated cgo wrapper of Nuklear has a random crash issue which is hard to fix (becaus
Go cross-platform library for displaying dialogs and input boxes
dlgs dlgs is a cross-platform library for displaying dialogs and input boxes. Installation go get -u github.com/gen2brain/dlgs Documentation Document
Go Web UI Toolkit - Public Releases and Development
Welcome! Gowut (Go Web UI Toolkit) is a full-featured, easy to use, platform independent Web UI Toolkit written in pure Go, no platform dependent nati