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, binding keys, using the EWMH or ICCCM specs with the window manager, moving/resizing windows, assigning function callbacks to particular events, drawing images to a window, etc. xgbutil attempts to be thread safe, but it has not been completely tested in this regard. In general, the X event loop implemented in the xevent package is sequential. The idea is to be sequential by default, and let the user spawn concurrent code at their discretion. (i.e., the complexity of making the main event loop generally concurrent is vast.) You may sleep safely at night by assuming that XGB is thread safe, though. To start using xgbutil, you should have at least a passing familiarity with X. Your first stop should be the examples directory. Installation ============ go get github.com/BurntSushi/xgbutil Dependencies ============ XGB is the main dependency. Use of the xgraphics packages requires graphics-go and freetype-go. XGB project URL: https://github.com/BurntSushi/xgb Quick Example ============= go get github.com/BurntSushi/xgbutil/_examples/window-name-sizes "$GOPATH"/bin/window-name-sizes The output will be a list of names of all top-level windows and their geometry including window manager decorations. (Assuming your window manager supports some basic EWMH properties.) Documentation ============= https://godoc.org/github.com/BurntSushi/xgbutil Examples ======== There are several examples in the examples directory covering common use cases. They are heavily documented and should run out of the box. Python ====== An older project of mine, xpybutil, served as inspiration for xgbutil. If you want to use Python, xpybutil should help quite a bit. Please note though, that at this point, xgbutil provides a lot more functionality and is much better documented. xpybutil project URL: https://github.com/BurntSushi/xpybutil
A utility library to make use of the X Go Binding easier. (Implements EWMH and ICCCM specs, key binding support, etc.)
Overview
Comments
-
Resize issues and Geometry values
Hi !
I am trying to resize and move window using xgbutil and facing some issues about it. I am running i3wm and use pkg.go.dev/go.i3wm.org/i3/ to obtain the focused window ID. Then I resize the window using one of the several methods provided by xgbutil.
My issue is : I have a window of random size, I want to move it and set it to a specific size, let's say 640x360. When I run one time my program, the window is moved in the correct place however the size is not correct. Geometry functions report a bogus size. If I run a second time the program immediately after, I can see the window changing a liittle bit its size again to finally get the correct size. Geometry functions returns the same value as before but this time it is correct. Subsquent run does not change the size anymore.
I have printed the geometry of the window before and after the call to the resize function and can see the second time that the size was incorrect (geometry reports the incorrect size). I don't understand why the geometry after the call in the first run is incorrect though.
Let's wrap-up: I create two sets of objects to be sure I am not reusing bufferized values. My code is
xgbUtil, _ := xgbutil.NewConn() xWin := xwindow.New(xgbUtil, windID) geom, _ := xWin.Geometry() fmt.Println("Before ", uint(geom.Width())) ewmh.MoveresizeWindow(xgbUtil, windID, 0, 0, 640,360) xgbUtil2, _ := xgbutil.NewConn() xWin2 := xwindow.New(xgbUtil2, windID) geom2, _ := xWin2.Geometry() fmt.Println("After ", uint(geom2.Width()))
First run I got:
Before 789 <= Random initial width of the window After 640 <= This is incorrect, the window is smaller
I do not touch anything and a rerun the program, I got:
Before 637 <= This shall have been in the "After" value on the first run After 640 <= Now this is correct !
I am a little bit confused in front of the multiple function to resize a window. I found: ewmh.MoveresizeWindow ewmh.MoveresizeWindowExtra ewmh.WmMoveresizeWindow ewmh.WmMoveresizeWindowExtra ewmh.ResizeWindow xwindow.Resize xwindow.MoveResize xwindow.WMResize xwindow.WMMoveResize
I understand some of the differences (such as between Move and MoveResize) but I do not understand the difference between Resize and WMResize for example.
-
Transparent Child Window
How do I create a transparent child window ?
This is how I create a child window under a root window
win, err := xwindow.Generate(xu) win.Create(parent, X,Y, Width,Height, xproto.CwBackPixel, 0xfffff)
Is it something to do with the valuemasks
xproto.CwBackPixel
?Any pointer will be very helpful. Thanks.
-
example window-gradient fails
example window-gradient fails
The example window-graient fails with a large number of xgraphics issues.
Errors
../../xgraphics/image.go:32: imported and not used: "code.google.com/p/graphics-go/graphics" ../../xgraphics/text.go:10: emptyarchive redeclared as imported package name previous declaration at ../../xgraphics/text.go:9 ../../xgraphics/text.go:10: imported and not used: "code.google.com/p/freetype-go/freetype/truetype" ../../xgraphics/text.go:24: undefined: truetype ../../xgraphics/text.go:54: undefined: truetype ../../xgraphics/text.go:63: undefined: freetype ../../xgraphics/text.go:63: undefined: truetype ../../xgraphics/text.go:73: undefined: truetype ../../xgraphics/text.go:88: undefined: truetype ../../xgraphics/util.go:10: imported and not used: "code.google.com/p/graphics-go/graphics" ../../xgraphics/text.go:88: too many errors
These same errors appear any time you attempt to load xgraphics.
-
[Question] Support for simulating keypresses?
Hello! Thanks for this library and for taking the time to write out the examples as they have been very helpful. Currently I'm trying to make a bare bones a simple text expander. The first part was easy to do modifying the example the
keypress-english
examples so I could listen for the text. I didn't any examples for simulating a keypress and was wondering if this library supports that and if not where to start looking for something like that? I have some very simple working C code:#include <stdio.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/extensions/XTest.h> #include <unistd.h> #define XK_c 0x0063 #define XK_d 0x0064 #define XK_h 0x0068 #define XK_o 0x006f #define XK_y 0x0079 #define XK_at 0x0040 #define XK_Shift_L 0xffe1 int main() { Display *dpy; dpy = XOpenDisplay(NULL); sleep(2); KeyCode code = XKeysymToKeycode(dpy, XK_c); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); code = XKeysymToKeycode(dpy, XK_o); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); code = XKeysymToKeycode(dpy, XK_d); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); code = XKeysymToKeycode(dpy, XK_y); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); // Make sure to send shift code = XKeysymToKeycode(dpy, XK_Shift_L); XTestFakeKeyEvent(dpy, code, True, CurrentTime); code = XKeysymToKeycode(dpy, XK_at); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); code = XKeysymToKeycode(dpy, XK_Shift_L); XTestFakeKeyEvent(dpy, code, False, CurrentTime); // No more shift // code = XKeysymToKeycode(dpy, XK_h); XTestFakeKeyEvent(dpy, code, True, CurrentTime); XTestFakeKeyEvent(dpy, code, False, CurrentTime); XFlush( dpy ); XCloseDisplay( dpy ); return 0; }
After that I updated this code to use something a bit more robust so I could call the C code from go with the following:
#include <stdio.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/extensions/XTest.h> int x11_key(char *zh){ Display *dpy; dpy = XOpenDisplay(NULL); KeySym sym = XStringToKeysym(zh); int min, max, numcodes; XDisplayKeycodes(dpy,&min,&max); KeySym *keysym; keysym = XGetKeyboardMapping(dpy,min,max-min+1,&numcodes); keysym[(max-min-1)*numcodes]=sym; XChangeKeyboardMapping(dpy,min,numcodes,keysym,(max-min)); XFree(keysym); XFlush( dpy ); KeyCode code = XKeysymToKeycode(dpy,sym); XTestFakeKeyEvent(dpy, code, True, 1); XTestFakeKeyEvent(dpy, code, False, 1); XFlush( dpy ); XCloseDisplay( dpy ); return 0; }
Which worked pretty well but when I would send a string like
[email protected]
the@
symbol would get messed up in programs other that the terminal I was running the code in. I searched around and saw the comment posted on https://stackoverflow.com/questions/26446184/control-the-mouse-and-keyboard-golang that saidFor X11 at least, there's no reason to use a C library. XGB is a native implementation of the X client protocol.
which lead me here but I couldn't find and examples that simulated keypresses. -
[Patch] Add a simple hook system to allow interception of events.
This is a simple patch that adds hooks to the xevent main loop, allowing handling of messages that don't conform to the package's routing mechanics
Hooks return true to allow the message to be processed as normal, false to abort processing of the event, presumably to implement it all in the hook's callback.
http://amanda.darkdna.net/p/1acba
-
png files (gopher subpackage) double-gzip'd
The png format already uses zlib internally for compression -- compressing it again is very unlikely to provide additional compression, and requires additional processing (once for your decompression, another time for the image library to decompress the png's pixels).
Large byte slices may also cause pathological behavior in the gc compiler (memory use ballooning). https://github.com/jteeuwen/go-bindata specializes in making sure the given binary file is compiled into a readonly memory segment without the major adverse effects -- though again, gzipping png files is best avoided.
-
WTFPL not supported by go.dev / no LICENSE file
Go.dev will not show documentation for this library because there is no LICENSE file and the WTFPL is not in their supported list.
Perhaps you wish to use the Unlicense?
You can find more information on this issue here.
-
xgraphics: package depends on code.google.com/p/jamslam-freetype-go/freetype
The package "code.google.com/p/jamslam-freetype-go/freetype" is going to disappear in January (last I heard). At that point the xgraphics package will not build.
It seems that the package requires the Context.MeasureString method which iirc was not available in "code.google.com/p/freetype-go/freetype".Context. I assume this was the original reason the "jamslam-" variant was used.
I have had similar requirements in the past. And I have used "jamslam" to meet them. Most recently when dealing with and trying to avoid code.google.com I found that I could achieve the MeasureString functionality by combining "github.com/golang/freetype" and "golang.org/x/image/font". You can look at my code. There is some weird rendering stuff going on in that program. But if you just trace back the types from the call site it should be fairly straightforward.
I think what it would boil down to in xgraphics/text.go would be something like the following (with some additional logic to create a font.Drawer):
w := f.MeasureString(text) h := int(c.PointToFixed(fontSize) >> 6)
The height calculation is basically the same thing that "jamslam" is doing.
-
Improved performance of XPaintRects
xgraphics.Image.xdraw
(called byXPaintRects
) has rather poor performance when called on a subimage.Without any change I can get it to push ~37'000'000 pixel/second. Just swapping the x and y indexes on the loop that copies to the
data
buffer I can get to ~60'000'000 pixel/second. With the change in this commit, that callscopy
on whole rowsxdraw
will push ~197'000'000 pixel/second, a 5x improvement on the original. -
add new api: NewConnXgb. We can use the specific xgb.Conn to init a xgbutil.XUtil
Add a new api:
NewConnXgb
. We can use a specific/customxgb.Conn
to initialize axgbutil.Xutil
.example:
xgbConn, _ := xgb.NewConnDisplay(":1") X, _ := xgbutil.NewConnXgb(xgbConn)
Meanwhile, the
NewConn
andNewConnDisplay
calls theNewConnXgb
. -
Image.Text and non-English chars.
The Text helper function seems to be rendering foreign chars incorrectly. For example (should be
śledź
):It's using a slightly modified
_examples/draw-text
code (changed the text to be rendered, of course). Tried with different fonts, all the same.By the looking of this, I think it might be calculating the extents wrong. Which will make it a freetype-go bug, I guess. In such case, feel free to close this one.
-
More functions for working with modifiers
Currently, if you don't want to do any masking yourself, there's only one function that you can use (that I know of), and that's
keybind.ModifierString
. This functions does several things you might not want:- It returns the modifiers connected with
-
- It returns the modifiers as strings, which isn't very efficient
Now, this isn't to say it's a bad function, but rather that it isn't sufficient as the only function.
- It returns the modifiers connected with
-
LookupString segfault on linux
output:
panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5911be] goroutine 19 [running]: testing.tRunner.func1.1(0x5b4dc0, 0x733ee0) /usr/lib/go-1.15/src/testing/testing.go:1057 +0x30d testing.tRunner.func1(0xc000082900) /usr/lib/go-1.15/src/testing/testing.go:1060 +0x41a panic(0x5b4dc0, 0x733ee0) /usr/lib/go-1.15/src/runtime/panic.go:969 +0x175 github.com/BurntSushi/xgbutil/keybind.KeysymGetWithMap(...) /home/binarycat/go/src/github.com/BurntSushi/xgbutil/keybind/keybind.go:260 github.com/BurntSushi/xgbutil/keybind.KeysymGet(...) /home/binarycat/go/src/github.com/BurntSushi/xgbutil/keybind/keybind.go:251 github.com/BurntSushi/xgbutil/keybind.interpretSymList(0xc0000fa140, 0x5ab836, 0x620101, 0xc000129e98, 0x59200d, 0x9, 0xc000129e80, 0x7208c0, 0x5ebcfd, 0x4) /home/binarycat/go/src/github.com/BurntSushi/xgbutil/keybind/encoding.go:87 +0x3e github.com/BurntSushi/xgbutil/keybind.LookupString(0xc0000fa140, 0x360010, 0x4, 0x6c68b0) /home/binarycat/go/src/github.com/BurntSushi/xgbutil/keybind/encoding.go:34 +0x3e github.com/lolbinarycat/dprefix.GetString(0x5f525ef0, 0xc000030770) /home/binarycat/go/src/github.com/lolbinarycat/dprefix/main.go:30 +0x8c github.com/lolbinarycat/dprefix.TestGetString(0xc000082900) /home/binarycat/go/src/github.com/lolbinarycat/dprefix/main_test.go:27 +0x26 testing.tRunner(0xc000082900, 0x5fd808) /usr/lib/go-1.15/src/testing/testing.go:1108 +0xef created by testing.(*T).Run /usr/lib/go-1.15/src/testing/testing.go:1159 +0x386
uname -a
:Linux binarycat 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 GNU/Linux
go env
:GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/binarycat/.cache/go-build" GOENV="/home/binarycat/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/binarycat/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/binarycat/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go-1.15" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go-1.15/pkg/tool/linux_amd64" GCCGO="/usr/bin/gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build338105219=/tmp/go-build -gno-record-gcc-switches"
-
[question] mousebind -- button chords
Thank you for this library, it's real nice, made things so much easier
Mousebind docs say mouse buttons can be modifiers, so mouse chords should work.
But running this code:
package main import ( "log" "github.com/BurntSushi/xgbutil" "github.com/BurntSushi/xgbutil/mousebind" "github.com/BurntSushi/xgbutil/xevent" ) func main() { X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } mousebind.Initialize(X) cb1 := mousebind.ButtonPressFun( func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) { log.Println("Button press!") }) err = cb1.Connect(X, X.RootWin(), "button3-1", false, true) if err != nil { log.Println(err) } xevent.Main(X) }
Produces this error:
Could not bind 'button3-1' because: BadValue {NiceName: Value, Sequence: 5, BadValue: 1024, MinorOpcode: 0, MajorOpcode: 28}
Any kind of help for solving this would be much appreciated. Thank you again for all your great work
-
[question] Fall back fonts.
How would I go about loading fallback fonts, for example I'm using a ttf font that doesn't have Japanese characters, so I want a different to be used whenever there is a Japanese character.
-
[feature request] Add support for pcf fonts.
See title, support for pcf fonts would be very nice, expecially since many terminal like applications make use of them and because it doesn't seem to be possible to draw bitmap fonts using freetype-go.
I've looked around and this seems to be the only pcf library for go: https://github.com/nareix/pcf
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
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.
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: ht
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
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
Odile is a simple GUI for the croc utility by Schollz.
Odile Odile is a simple GUI for the croc utility by Schollz. This program uses Fyne, a UI toolkit written in Go, as the graphical interface. Effort wa
QML support for the Go language
QML support for the Go language Documentation The introductory documentation as well as the detailed API documentation is available at gopkg.in/qml.v1
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 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
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
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
An experimental Go cross platform UI library.
GXUI - A Go cross platform UI library. Notice: Unfortunately due to a shortage of hours in a day, GXUI is no longer maintained. If you're looking for
Platform-native GUI library for Go.
ui: platform-native GUI library for Go This is a library that aims to provide simple GUI software development in Go. It is based on my libui, a simple
:traffic_light: Go bindings for libappindicator3 C library
go-appindicator Go bindings for libappindicator3 C library. Libappindicator is a library to allow applications to export a menu into the Unity Menu ba
Cross-platform Go library to place an icon in the host operating system's taskbar.
trayhost Package trayhost is a cross-platform Go library to place an icon in the host operating system's taskbar. Platform Support macOS - Fully imple
Common library for Go GUI apps on Windows
winc Common library for Go GUI apps on Windows. It is for Windows OS only. This makes library smaller than some other UI libraries for Go.
Windows GUI library for Go (Golang). Comes with a graphical UI designer.
Version 2 Please go to Version 2 of this library for the latest version. Windows GUI Library This is a pure Go library to create native Windows GUIs.
Go wrapper library for "Dear ImGui" (https://github.com/ocornut/imgui)
Dear ImGui for Go This library is a Go wrapper for Dear ImGui. This wrapper started as a special-purpose wrapper for use within InkyBlackness. However