robotgo/AGENTS.md
2026-04-17 14:21:33 -07:00

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 with xvfb-run — see .circleci/config.yml)
  • Single test: go test -v -run TestGetScreenSize .
  • Format: gofmt -w . (code uses tab indentation, standard gofmt style)
  • 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 (see CONTRIBUTING.md). Preserve it verbatim when editing; add a second header only if authorship changes.
  • Indentation: tabs (Go default). Run gofmt before committing.
  • Build tags: use both forms together — //go:build darwin plus legacy // +build darwin — matching existing files.
  • Cgo: import "C" immediately follows a /* ... */ comment block containing #cgo directives and #includes. Keep LDFLAGS per-OS (#cgo darwin LDFLAGS, #cgo linux LDFLAGS, #cgo windows LDFLAGS).
  • Naming: exported CamelCase; key constants prefixed Key (e.g. KeyA, KeyEnter); C-type aliases prefixed C (CBitmap, CHex). Mirror existing patterns.
  • Imports: stdlib first, blank line, then third-party (github.com/...). Internal subpackage imported as github.com/go-vgo/robotgo/clipboard (full module path, not relative).
  • Comments: godoc-style // FuncName does X on every exported symbol. Package doc lives in doc.go / top of robotgo.go.
  • Error handling: return error as last result; use errors.New / fmt.Errorf. Try(fn, handler) helper wraps panics via recover. Do not swallow errors.
  • Types: existing code uses interface{} (pre-generics) — match local style when editing that file, but prefer any in 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.go beside sources. Package declared as robotgo_test (external) for API-surface tests, or robotgo for 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.go and run only under CircleCI's xvfb-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:build tags and have implementations (even stub) for darwin, linux, windows — examine mouse/mouse_darwin.go, mouse_windows.go, mouse_x11.go as the template.
  • Free C-allocated bitmaps: every CaptureScreen, ToCBitmap, etc. must be paired with defer robotgo.FreeBitmap(bit) or robotgo.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.go contains deprecated v1 aliases — do not add new APIs there, but do not delete existing ones (backwards compatibility).
  • Version string lives in robotgo.go as const Version = "v1.00.0.1189, MT. Baker!". Bump it when releasing; TestGetVer asserts it matches GetVersion().
  • Windows pid vs hwnd: set robotgo.NotPid = true to 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 avoid go mod vendor (upstream note in README references golang/go#26366).
  • C artifacts (*.cgo1.go, *.cgo2.c, _cgo_*, *.o, *.a except whitelisted cdeps/... 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 by key/).
  • 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 by robotgo_ocr.go; needs libtesseract).
  • 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).