7.9 KiB
RobotGo
Go native cross-platform desktop automation: mouse, keyboard, screen, bitmap, process, window handle, clipboard, and global event listener. Supports macOS, Windows, Linux (X11); amd64 and arm64.
Module: github.com/go-vgo/robotgo — Go 1.24 (CI pins Go 1.25 / 1.26).
Build/Test/Lint Commands
Prerequisites: GCC must be installed. CGO_ENABLED=1 (default). On macOS, Xcode Command Line Tools + Accessibility/Screen Recording permissions. On Linux, X11 + XTest (libx11-dev xorg-dev libxtst-dev).
- Build:
go build -v . - Build all subpackages:
go build -v ./... - Fetch deps:
go get -v -t -d ./... - Test (CI minimal — no display required):
go test -v robot_info_test.go - Test (full):
go test -v ./...(Linux CI wraps withxvfb-run— see.circleci/config.yml) - Single test:
go test -v -run TestGetScreenSize . - Format:
gofmt -w .(code uses tab indentation, standardgofmtstyle) - Vet:
go vet ./... - Run an example:
cd examples/mouse && go run main.go
There is no Makefile / Taskfile / linter config. CI is .github/workflows/go.yml (macOS + Windows: go test -v robot_info_test.go only), .circleci/config.yml (Linux full tests under xvfb), appveyor.yml (Windows MinGW).
Architecture
Single Go package robotgo at repo root (flat layout) with platform-specific files and C-binding subpackages. Most features are Cgo wrappers over C headers vendored in subdirectories; build tags split platform implementations.
robotgo/
├── robotgo.go # main API + Cgo preamble (darwin/linux/windows LDFLAGS)
├── robotgo_mac.go # //go:build darwin
├── robotgo_mac_unix.go # //go:build darwin || linux
├── robotgo_mac_win.go # //go:build darwin || windows
├── robotgo_win.go # //go:build windows
├── robotgo_x11.go # //go:build linux (X11)
├── robotgo_android.go, robotgo_adb.go
├── wayland_n.go, windows_n.go
├── key.go, keycode.go, screen.go, img.go, ps.go
├── robotgo_fn_v1.go # deprecated v1 aliases (kept for compat)
├── robot_info_test.go # only portable test (used by CI)
├── robotgo_test.go # full interactive tests
├── base/ # C helpers (MMBitmap, rgb, microsleep, types, xdisplay)
├── mouse/ # Go pkg + C (mouse.h, mouse_c.h) with *_darwin.go/_windows.go/_x11.go
├── key/ # Go pkg + C (keycode.h, keypress_c.h)
├── screen/ # Go pkg + C (goScreen.h, screengrab_c.h)
├── window/ # Go pkg + C (goWindow.h, window.h, alert_c.h, win_sys.h, pub.h)
├── clipboard/ # Go pkg (darwin/unix/windows variants) + cmd/gocopy, cmd/gopaste
├── event/ # C headers for android / ios
├── cv/ # OpenCV helper (gocv.go)
├── examples/ # mouse, key, screen, window, scale — runnable main.go
├── docs/ # install.md, keys.md, CHANGELOG.md
└── .github/workflows/go.yml, .circleci/config.yml, appveyor.yml
Key subpackage relationships: the root robotgo package pulls C code from screen/goScreen.h, mouse/mouse_c.h, window/goWindow.h. The key/ and clipboard/ directories are importable Go packages; base/ is header-only C support.
Code Style
- Copyright header: every Go and C file starts with the 10-line
Copyright (c) 2016-2025 AtomAI...block (seeCONTRIBUTING.md). Preserve it verbatim when editing; add a second header only if authorship changes. - Indentation: tabs (Go default). Run
gofmtbefore committing. - Build tags: use both forms together —
//go:build darwinplus legacy// +build darwin— matching existing files. - Cgo:
import "C"immediately follows a/* ... */comment block containing#cgodirectives and#includes. Keep LDFLAGS per-OS (#cgo darwin LDFLAGS,#cgo linux LDFLAGS,#cgo windows LDFLAGS). - Naming: exported
CamelCase; key constants prefixedKey(e.g.KeyA,KeyEnter); C-type aliases prefixedC(CBitmap,CHex). Mirror existing patterns. - Imports: stdlib first, blank line, then third-party (
github.com/...). Internal subpackage imported asgithub.com/go-vgo/robotgo/clipboard(full module path, not relative). - Comments: godoc-style
// FuncName does Xon every exported symbol. Package doc lives indoc.go/ top ofrobotgo.go. - Error handling: return
erroras last result; useerrors.New/fmt.Errorf.Try(fn, handler)helper wraps panics viarecover. Do not swallow errors. - Types: existing code uses
interface{}(pre-generics) — match local style when editing that file, but preferanyin new code. Do not mass-rewrite; gopls emits hints, not errors.
Testing
- Framework: stdlib
testing+github.com/vcaesar/tt(tt.Expect(t, want, got)). - Test files:
*_test.gobeside sources. Package declared asrobotgo_test(external) for API-surface tests, orrobotgofor internal. - Portable tests live in
robot_info_test.go— the only file exercised by GitHub Actions. Keep new tests here if they must run headless on macOS/Windows CI. - Interactive / display-required tests go in
robotgo_test.goand run only under CircleCI'sxvfb-run go test -v ./.... - Run one test:
go test -v -run TestGetScreenSize . - No fixtures, snapshots, or golden files in use. Screenshots produced by examples are
.gitignored.
Key Patterns
- Cgo + platform split is mandatory. Any new OS-specific function must be gated by
//go:buildtags and have implementations (even stub) for darwin, linux, windows — examinemouse/mouse_darwin.go,mouse_windows.go,mouse_x11.goas the template. - Free C-allocated bitmaps: every
CaptureScreen,ToCBitmap, etc. must be paired withdefer robotgo.FreeBitmap(bit)orrobotgo.FreeBitmapArr(...). Leaking is a memory bug on all platforms. - Global tunables are package-level vars, not config structs:
MouseSleep,KeySleep,DisplayID,NotPid,Scale. Callers mutate them directly (see README examples). Do not hide them behind getters. robotgo_fn_v1.gocontains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).- Version string lives in
robotgo.goasconst Version = "v1.00.0.1189, MT. Baker!". Bump it when releasing;TestGetVerasserts it matchesGetVersion(). - Windows pid vs hwnd: set
robotgo.NotPid = trueto pass window handles instead of pids into the window/key APIs on Windows. - macOS permissions: most screen/input APIs silently fail without Accessibility + Screen Recording grants. When reproducing bugs on darwin, verify System Settings → Privacy & Security first.
- Do not vendor:
vendor/is in.gitignore; also avoidgo mod vendor(upstream note in README references golang/go#26366). - C artifacts (
*.cgo1.go,*.cgo2.c,_cgo_*,*.o,*.aexcept whitelistedcdeps/...libpng archives) are git-ignored — do not commit them. - Commit sign-off is expected (see
CONTRIBUTING.md); PRs require ≥2 maintainer review (LGTM).
Dependencies
github.com/jezek/xgb,github.com/jezek/xgbutil— X11 protocol on Linux.github.com/tailscale/win,github.com/dblohm7/wingoes,github.com/yusufpapurcu/wmi,github.com/go-ole/go-ole— Windows system APIs.github.com/vcaesar/keycode— cross-platform keycode mapping (used bykey/).github.com/vcaesar/imgo,golang.org/x/image— image encode/decode (PNG/JPEG save).github.com/vcaesar/screenshot— screenshot backend.github.com/vcaesar/gops,github.com/shirou/gopsutil/v4— process enumeration (FindIds,PidExists,Kill).github.com/vcaesar/tt— testing assertions.github.com/otiai10/gosseract/v2— OCR (used byrobotgo_ocr.go; needslibtesseract).github.com/godbus/dbus/v5— used on Linux for Wayland/desktop ops.- Companion repos (not in
go.mod, referenced in README/examples):github.com/vcaesar/bitmap,github.com/vcaesar/gcv(OpenCV),github.com/jezek/gohook(global event hook).