Compare commits

...

74 Commits

Author SHA1 Message Date
Evans
a8c387a070
Merge pull request #725 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Update: use hid event in macos
2025-05-17 13:04:47 -07:00
vcaesar
3eef3b5879 Add: add CGEventSourceRef source
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2025-05-17 13:01:03 -07:00
vcaesar
b731094f61 Update: update if defined 2025-05-17 12:54:35 -07:00
vcaesar
8d4679db07 Merge remote-tracking branch 'origin/master' into bitmap-pr 2025-05-17 12:42:12 -07:00
vcaesar
02c668a946 Update: add CFRelease source 2025-05-17 12:37:38 -07:00
vcaesar
5c2864485d Update: use hid event in macos 2025-05-17 12:33:16 -07:00
Evans
f101b10497
Merge pull request #724 from go-vgo/bitmap-pr
Fixed: fixed default key toggle delay
2025-05-17 12:03:01 -07:00
vcaesar
73c07dc991 Fixed: fixed default key toggle delay 2025-05-17 12:01:12 -07:00
Evans
fc47bc8216
Merge pull request #723 from go-vgo/bitmap-pr
Update: update go mod and CI
2025-05-17 11:56:33 -07:00
vcaesar
912ddcbfe4 Update: update go mod and CI 2025-05-17 11:53:45 -07:00
Evans
57b5e5bca2
Merge pull request #720 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Update: update import
2025-04-19 12:56:42 -07:00
vcaesar
8031f7f526 Update: update import
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2025-04-19 12:54:47 -07:00
Evans
36bc85ad19
Merge pull request #719 from go-vgo/bitmap-pr
Some checks are pending
Go / test (macOS-latest) (push) Waiting to run
Go / test (windows-latest) (push) Waiting to run
Fix: fixed mac os version min required #698
2025-04-19 10:06:37 -07:00
vcaesar
5fc2bd4c73 Fix: fixed mac os version min required #698
Some checks are pending
Go / test (macOS-latest) (push) Waiting to run
Go / test (windows-latest) (push) Waiting to run
2025-04-19 10:05:01 -07:00
Evans
47abfac5ee
Merge pull request #716 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Fixed: fixed windows Scale #713 and Update readme.md
2025-04-11 14:37:12 -07:00
vcaesar
df0731c4df Fixed: fixed windows Scale #713 and Update readme.md
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2025-04-11 14:34:15 -07:00
Evans
03432155c1
Merge pull request #711 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Refactor: simplify mouse movement implementation for Windows
2025-03-08 15:03:56 -08:00
vcaesar
6a1f060a8c Refactor: simplify mouse movement implementation for Windows, use setCursorPos instead of mouse_event
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2025-03-08 15:02:39 -08:00
Evans
e924f25fe1
Merge pull request #708 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Update: updated go mod
2025-02-17 15:56:32 -08:00
vcaesar
d300eedf54 Update: updated go mod
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2025-02-17 15:54:57 -08:00
Evans
c07f3f0171
Merge pull request #701 from ronaldpetty/patch-1
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Update README.md
2024-12-10 11:32:09 -08:00
Ronald Petty
0b18fa5058
Update README.md
Added missing import
2024-12-09 19:51:43 -08:00
Evans
471f7ba05f
Merge pull request #695 from go-vgo/bitmap-pr
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
Update: update go mod
2024-10-07 14:17:46 -07:00
vcaesar
a84a195c4c Update: update go mod
Some checks failed
Go / test (macOS-latest) (push) Has been cancelled
Go / test (windows-latest) (push) Has been cancelled
2024-10-07 14:15:17 -07:00
Evans
c8df366f89
Merge pull request #694 from go-vgo/bitmap-pr
Update: update readme.md
2024-10-07 14:10:09 -07:00
vcaesar
70f811ce53 Update: update readme.md 2024-10-07 14:09:01 -07:00
Evans
ecc260ea31
Merge pull request #693 from go-vgo/bitmap-pr
Update: update screen capture code and examples
2024-10-07 14:00:37 -07:00
vcaesar
78d01703b8 Update: update examples and test code, README.md 2024-10-07 13:56:46 -07:00
vcaesar
47cde13dab Update: update screen capture code and examples 2024-10-07 13:45:03 -07:00
aohanhongzhi
8db59aac2d
capture error (#663)
* capture error

* aohanhongzhi

* Update go.mod

---------

Co-authored-by: Evans <vzvway@gmail.com>
2024-10-07 13:29:39 -07:00
Evans
217d6cf1f1
Merge pull request #692 from go-vgo/bitmap-pr
Some checks are pending
Go / test (macOS-latest) (push) Waiting to run
Go / test (windows-latest) (push) Waiting to run
Fixed: default use high capture resolution in macos15
2024-10-06 18:12:41 -07:00
vcaesar
75fd24ea0a Fixed: Fixed x11 build
Some checks are pending
Go / test (macOS-latest) (push) Waiting to run
Go / test (windows-latest) (push) Waiting to run
2024-10-06 18:11:23 -07:00
vcaesar
bed6776ca2 Fixed: default use high capture resolution in macos15 2024-10-06 18:04:17 -07:00
Evans
1923d7bb48
Merge pull request #691 from go-vgo/bitmap-pr
Update: move scale to screen and rename pub mdata
2024-10-06 17:54:40 -07:00
vcaesar
ead43d062e Fixed: fix x11 build 2024-10-06 17:51:51 -07:00
vcaesar
3258566802 Update: move scale to screen and rename pub mdata 2024-10-06 17:40:34 -07:00
Evans
0de26ecee4
Merge pull request #685 from go-vgo/bitmap-pr
Add: export Handle data and add more window handle function #683
2024-09-17 13:39:26 -07:00
vcaesar
c48e3d072c Update: Fixed godoc 2024-09-17 13:38:38 -07:00
vcaesar
b1ad7db6be Add: export Handle data and add more window handle function #683 2024-09-17 13:32:46 -07:00
Evans
0110b85d40
Merge pull request #684 from go-vgo/bitmap-pr
Add: export xClose main display function
2024-09-17 13:14:54 -07:00
vcaesar
3e5b10f720 Add: export XClose main display function 2024-09-17 13:11:02 -07:00
vcaesar
cb51e2aa10 Update: cleary some code style 2024-09-17 12:59:15 -07:00
Evans
85f2702683
Merge pull request #682 from go-vgo/bitmap-pr
Update: update screengrab to fixed macos 15
2024-09-15 12:25:18 -07:00
vcaesar
5b9871b063 Merge remote-tracking branch 'origin/master' into bitmap-pr 2024-09-05 13:26:02 -07:00
vcaesar
b201ab9f80 Update: update screengrad with fixed macos 15 2024-09-05 13:23:14 -07:00
Evans
d3e364fa26
Merge pull request #681 from go-vgo/bitmap-pr
Update: update go mod
2024-09-05 13:11:35 -07:00
vcaesar
1f437d12e4 Update: update go mod 2024-09-05 13:09:51 -07:00
Evans
c5110d0ac8
Merge pull request #675 from go-vgo/bitmap-pr
Update: update CI to newest
2024-08-16 11:36:44 -07:00
vcaesar
f98b4c52bd Update: update CI to newest 2024-08-16 11:35:18 -07:00
Evans
f1db2ede4a
Merge pull request #671 from go-vgo/bitmap-pr
Update: add svae capture and update go mod
2024-08-05 13:13:39 -07:00
vcaesar
d90493e63e Update: add svae capture and update go mod 2024-08-05 13:11:56 -07:00
Evans
63eb594ea5
Merge pull request #661 from go-vgo/bitmap-pr
Update: update go mod to newest
2024-06-12 13:06:53 -07:00
vcaesar
8a990ac042 Update: update go mod to newest 2024-06-12 13:02:30 -07:00
Evans
bf1758b424
Merge pull request #660 from go-vgo/bitmap-pr
Update: update CI and dockerfile
2024-06-05 12:40:24 -07:00
vcaesar
9424b71a73 Update: update CI and dockerfile 2024-06-05 12:38:39 -07:00
Evans
6c137427db
Merge pull request #649 from nzlov/patch-1
fix: DragSmooth Repeat Call MoveScale
2024-04-15 10:14:33 -07:00
Evans
ffbf4f875b
Merge pull request #651 from rustfix/master
chore: fix function names in comment
2024-04-15 10:11:35 -07:00
rustfix
05c54c6f25 chore: fix function names in comment
Signed-off-by: rustfix <771054535@qq.com>
2024-04-15 11:37:14 +08:00
nzlov
3171c5bdff
fix: DragSmooth Repeat Call MoveScale
`DragSmooth` calls `MoveScale` followed by `MoveSmooth`, and `MoveSmooth` calls `MoveScale` within `MoveSmooth`, resulting in duplicate calls to `MoveScale`.
2024-04-07 14:08:26 +08:00
Evans
b718cf4a8c
Merge pull request #643 from go-vgo/bitmap-pr
Update: bump CI to newest
2024-02-23 08:52:47 -08:00
vcaesar
bfc28d12fa Merge remote-tracking branch 'origin/master' into bitmap-pr 2024-02-23 08:49:07 -08:00
vcaesar
e9421b58b6 Update: bump CI to newest 2024-02-23 08:47:11 -08:00
Evans
4d780b9908
Merge pull request #630 from go-vgo/bitmap-pr
Add: add next Linux and Windows files
2023-12-20 09:55:27 -08:00
vcaesar
39818d41fa Add: add next Linux and Windows files 2023-12-20 09:52:51 -08:00
Evans
eacf74f488
Merge pull request #629 from sleep2144985/patch-1
fix: x11 capslock reference the wrong constant
2023-12-20 09:21:17 -08:00
sleep2144985
61b77ce3e1
fix: x11 capslock reference the wrong constant 2023-12-20 17:35:11 +08:00
Evans
01e4fffcb8
Merge pull request #623 from go-vgo/bitmap-pr
Update: update readme.md
2023-11-13 10:27:41 -08:00
vcaesar
e2f5f54804 Update: update readme.md 2023-11-13 10:22:10 -08:00
Evans
f22f063926
Merge pull request #622 from go-vgo/bitmap-pr
Update: update readme.md
2023-11-13 09:25:31 -08:00
vcaesar
722feb7ba3 Update: update readme.md 2023-11-13 09:23:29 -08:00
Evans
dbf0d84f12
Merge pull request #617 from go-vgo/bitmap-pr
Update: gofmt the code
2023-10-30 08:26:49 -07:00
vcaesar
b8a6b1778e Update: gofmt the code 2023-10-30 08:24:33 -07:00
Evans
a780825c09
Merge pull request #612 from yms2772/master
Fix: panic occurs when current window is minimized on macOS
2023-09-15 07:21:43 -07:00
Mokky
de675b4dd2
Update window.h
Fix: error when current window is minimized
2023-09-07 20:53:58 +09:00
28 changed files with 425 additions and 306 deletions

View File

@ -5,7 +5,7 @@ jobs:
docker:
# using custom image, see .circleci/images/primary/Dockerfile
# - image: govgo/robotgoci:1.10.3
- image: golang:1.21.0
- image: golang:1.23.0
working_directory: /gopath/src/github.com/go-vgo/robotgo
steps:
- checkout

View File

@ -1,5 +1,5 @@
# FROM golang:1.10.1
FROM golang:1.20.3-stretch AS build
FROM golang:1.24.2-stretch AS build
# FROM govgo/go:1.11.1
RUN apt update && apt install -y --no-install-recommends \

View File

@ -10,10 +10,10 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Set up Go 1.21.0
- name: Set up Go 1.24.0
uses: actions/setup-go@v1
with:
go-version: 1.21.0
go-version: 1.24.0
id: go
- name: Check out code into the Go module directory

View File

@ -10,7 +10,7 @@
[![Build Status](https://travis-ci.org/go-vgo/robotgo.svg)](https://travis-ci.org/go-vgo/robotgo)
![Appveyor](https://ci.appveyor.com/api/projects/status/github/go-vgo/robotgo?branch=master&svg=true)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-vgo/robotgo)](https://goreportcard.com/report/github.com/go-vgo/robotgo)
[![GoDoc](https://godoc.org/github.com/go-vgo/robotgo?status.svg)](https://godoc.org/github.com/go-vgo/robotgo)
[![GoDoc](https://pkg.go.dev/badge/github.com/go-vgo/robotgo?status.svg)](https://pkg.go.dev/github.com/go-vgo/robotgo?tab=doc)
[![GitHub release](https://img.shields.io/github/release/go-vgo/robotgo.svg)](https://github.com/go-vgo/robotgo/releases/latest)
[![Join the chat at https://gitter.im/go-vgo/robotgo](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-vgo/robotgo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@ -61,21 +61,31 @@ GCC
```
#### For MacOS:
```
brew install go
```
Xcode Command Line Tools (And Privacy setting: [#277](https://github.com/go-vgo/robotgo/issues/277) )
Xcode Command Line Tools (And Privacy setting: [#277](https://github.com/go-vgo/robotgo/issues/277))
```
xcode-select --install
```
#### For Windows:
```
winget install Golang.go
```
[MinGW-w64](https://sourceforge.net/projects/mingw-w64/files) (Use recommended)
```
winget install MartinStorsjo.LLVM-MinGW.UCRT
```
Or [MinGW-w64](https://sourceforge.net/projects/mingw-w64/files) (Use recommended) or others Mingw [llvm-mingw](https://github.com/mstorsjo/llvm-mingw);
Download the Mingw, then set system environment variables `C:\mingw64\bin` to the Path.
[Set environment variables to run GCC from command line](https://www.youtube.com/results?search_query=Set+environment+variables+to+run+GCC+from+command+line).
`Or the other GCC (But you should compile the "libpng" with yourself when use the bitmap.)`
`Or the other GCC` (But you should compile the "libpng" with yourself when use the [bitmap](https://github.com/vcaesar/bitmap).)
#### For everything else:
@ -87,15 +97,18 @@ X11 with the XTest extension (the Xtst library)
"Clipboard": xsel xclip
"Bitmap": libpng (Just used by the bitmap.)
"Bitmap": libpng (Just used by the "bitmap".)
"Event": xcb, xkb, libxkbcommon (Just used by the hook.)
"Event-Gohook": xcb, xkb, libxkbcommon (Just used by the "hook".)
```
##### Ubuntu:
```yml
# sudo apt install golang
sudo snap install go --classic
# gcc
sudo apt install gcc libc6-dev
@ -109,7 +122,7 @@ sudo apt install xsel xclip
# Bitmap
sudo apt install libpng++-dev
# Hook
# GoHook
sudo apt install xcb libxcb-xkb-dev x11-xkb-utils libx11-xcb-dev libxkbcommon-x11-dev libxkbcommon-dev
```
@ -127,7 +140,7 @@ sudo dnf install xsel xclip
# Bitmap
sudo dnf install libpng-devel
# Hook
# GoHook
sudo dnf install libxkbcommon-devel libxkbcommon-x11-devel xorg-x11-xkb-utils-devel
```
@ -165,11 +178,18 @@ Note go1.10.x C file compilation cache problem, [golang #24355](https://github.c
package main
import (
"fmt"
"github.com/go-vgo/robotgo"
)
func main() {
robotgo.MouseSleep = 100
robotgo.MouseSleep = 300
robotgo.Move(100, 100)
fmt.Println(robotgo.Location())
robotgo.Move(100, -200) // multi screen supported
robotgo.MoveSmooth(120, -150)
fmt.Println(robotgo.Location())
robotgo.ScrollDir(10, "up")
robotgo.ScrollDir(20, "right")
@ -244,6 +264,7 @@ package main
import (
"fmt"
"strconv"
"github.com/go-vgo/robotgo"
"github.com/vcaesar/imgo"
@ -268,13 +289,18 @@ func main() {
num := robotgo.DisplaysNum()
for i := 0; i < num; i++ {
robotgo.DisplayID = i
img1 := robotgo.CaptureImg()
img1, _ := robotgo.CaptureImg()
path1 := "save_" + strconv.Itoa(i)
robotgo.Save(img1, path1+".png")
robotgo.SaveJpeg(img1, path1+".jpeg", 50)
img2 := robotgo.CaptureImg(10, 10, 20, 20)
img2, _ := robotgo.CaptureImg(10, 10, 20, 20)
robotgo.Save(img2, "test_"+strconv.Itoa(i)+".png")
x, y, w, h := robotgo.GetDisplayBounds(i)
img3, err := robotgo.CaptureImg(x, y, w, h)
fmt.Println("Capture error: ", err)
robotgo.Save(img3, path1+"_1.png")
}
}
```
@ -354,8 +380,8 @@ func opencv() {
// bit1 := robotgo.CaptureScreen(10, 10, 30, 30)
// img1 := robotgo.ToImage(bit1)
// defer robotgo.FreeBitmapArr(bit0, bit1)
img := robotgo.CaptureImg()
img1 := robotgo.CaptureImg(10, 10, 30, 30)
img, _ := robotgo.CaptureImg()
img1, _ := robotgo.CaptureImg(10, 10, 30, 30)
fmt.Print("gcv find image: ")
fmt.Println(gcv.FindImg(img1, img))

View File

@ -34,7 +34,7 @@ environment:
PATH: C:\msys64\mingw32\bin\;C:\Program Files (x86)\NSIS\;%PATH%
# - COMPILER: MINGW_W64
# ARCHITECTURE: x64
GOVERSION: 1.21.0
GOVERSION: 1.23.0
# GOPATH: c:\gopath
# scripts that run after cloning repository

View File

@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
/*
Package clipboard read/write on clipboard
*/
package clipboard

View File

@ -29,23 +29,29 @@ func bitmap() {
gbitMap := robotgo.CaptureGo()
fmt.Println("Go CaptureScreen...", gbitMap.Width)
// fmt.Println("...", gbitmap.Width, gbitmap.BytesPerPixel)
// robotgo.SaveCapture("saveCapture.png", 10, 20, 100, 100)
robotgo.SaveCapture("saveCapture.png", 10, 20, 100, 100)
img := robotgo.CaptureImg()
img, err := robotgo.CaptureImg()
fmt.Println("error: ", err)
robotgo.Save(img, "save.png")
num := robotgo.DisplaysNum()
for i := 0; i < num; i++ {
robotgo.DisplayID = i
img1 := robotgo.CaptureImg()
img1, _ := robotgo.CaptureImg()
path1 := "save_" + strconv.Itoa(i)
robotgo.Save(img1, path1+".png")
robotgo.SaveJpeg(img1, path1+".jpeg", 50)
img2 := robotgo.CaptureImg(10, 10, 20, 20)
img2, _ := robotgo.CaptureImg(10, 10, 20, 20)
path2 := "test_" + strconv.Itoa(i)
robotgo.Save(img2, path2+".png")
robotgo.SaveJpeg(img2, path2+".jpeg", 50)
x, y, w, h := robotgo.GetDisplayBounds(i)
img3, err := robotgo.CaptureImg(x, y, w, h)
fmt.Println("Capture error: ", err)
robotgo.Save(img3, path2+"_1.png")
}
}

46
go.mod
View File

@ -1,34 +1,38 @@
module github.com/go-vgo/robotgo
go 1.17
go 1.23.0
toolchain go1.23.6
require (
github.com/lxn/win v0.0.0-20210218163916-a377121e959e
github.com/otiai10/gosseract v2.2.1+incompatible
github.com/otiai10/gosseract/v2 v2.4.1
// github.com/robotn/gohook v0.31.3
github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934
github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770
github.com/vcaesar/gops v0.30.2
github.com/vcaesar/imgo v0.40.0
github.com/robotn/xgb v0.10.0
github.com/robotn/xgbutil v0.10.0
github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35
github.com/vcaesar/gops v0.41.0
github.com/vcaesar/imgo v0.41.0
github.com/vcaesar/keycode v0.10.1
github.com/vcaesar/tt v0.20.0
github.com/vcaesar/tt v0.20.1
)
require (
github.com/gen2brain/shm v0.0.0-20230802011745-f2460f5984f7 // indirect
github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e // indirect
github.com/ebitengine/purego v0.8.3 // indirect
github.com/gen2brain/shm v0.1.1 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/jezek/xgb v1.1.0 // indirect
github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
github.com/otiai10/mint v1.3.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/shirou/gopsutil/v3 v3.23.8 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/image v0.12.0 // indirect
golang.org/x/sys v0.12.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/jezek/xgb v1.1.1 // indirect
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/shirou/gopsutil/v4 v4.25.4 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/vcaesar/screenshot v0.11.1
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
golang.org/x/image v0.27.0 // indirect
golang.org/x/sys v0.33.0 // indirect
)
// replace golang.org/x/sys => github.com/golang/sys v0.0.0-20190109145017-48ac38b7c8cb

147
go.sum
View File

@ -1,110 +1,71 @@
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gen2brain/shm v0.0.0-20230802011745-f2460f5984f7 h1:VLEKvjGJYAMCXw0/32r9io61tEXnMWDRxMk+peyRVFc=
github.com/gen2brain/shm v0.0.0-20230802011745-f2460f5984f7/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo=
github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e h1:L+XrFvD0vBIBm+Wf9sFN6aU395t7JROoai0qXZraA4U=
github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e/go.mod h1:SUxUaAK/0UG5lYyZR1L1nC4AaYYvSSYTWQSH3FPcxKU=
github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc=
github.com/ebitengine/purego v0.8.3/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/gen2brain/shm v0.1.1 h1:1cTVA5qcsUFixnDHl14TmRoxgfWEEZlTezpUj1vm5uQ=
github.com/gen2brain/shm v0.1.1/go.mod h1:UgIcVtvmOu+aCJpqJX7GOtiN7X2ct+TKLg4RTxwPIUA=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk=
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237 h1:YOp8St+CM/AQ9Vp4XYm4272E77MptJDHkwypQHIRl9Q=
github.com/kbinani/screenshot v0.0.0-20230812210009-b87d31814237/go.mod h1:e7qQlOY68wOz4b82D7n+DdaptZAi+SHW0+yKiWZzEYE=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/gosseract v2.2.1+incompatible h1:Ry5ltVdpdp4LAa2bMjsSJH34XHVOV7XMi41HtzL8X2I=
github.com/otiai10/gosseract v2.2.1+incompatible/go.mod h1:XrzWItCzCpFRZ35n3YtVTgq5bLAhFIkascoRo8G32QE=
github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw=
github.com/otiai10/gosseract/v2 v2.4.1/go.mod h1:1gNWP4Hgr2o7yqWfs6r5bZxAatjOIdqWxJLWsTsembk=
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934 h1:2lhSR8N3T6I30q096DT7/5AKEIcf1vvnnWAmS0wfnNY=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770 h1:2uX8QRLkkxn2EpAQ6I3KhA79BkdRZfvugJUzJadiJwk=
github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU=
github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/vcaesar/gops v0.30.2 h1:fANyUGCjLkfcYmJRVnXv+QZhT8cL2e0GWpRFZe58p/4=
github.com/vcaesar/gops v0.30.2/go.mod h1:2NSA2Q9M1irGnGD9tWdo0Z+MwKjUj4Q4EgUDukN/Vsk=
github.com/vcaesar/imgo v0.40.0 h1:okI1eonRAfGLzjqgTIBkUwhm4j/rH19qGno4eFOBQsc=
github.com/vcaesar/imgo v0.40.0/go.mod h1:E5uI53XkEfbI20VvcIZ/19G2hHidPfH9h4NtQooEY+8=
github.com/robotn/xgb v0.10.0 h1:O3kFbIwtwZ3pgLbp1h5slCQ4OpY8BdwugJLrUe6GPIM=
github.com/robotn/xgb v0.10.0/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
github.com/robotn/xgbutil v0.10.0 h1:gvf7mGQqCWQ68aHRtCxgdewRk+/KAJui6l3MJQQRCKw=
github.com/robotn/xgbutil v0.10.0/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU=
github.com/shirou/gopsutil/v4 v4.25.4 h1:cdtFO363VEOOFrUCjZRh4XVJkb548lyF0q0uTeMqYPw=
github.com/shirou/gopsutil/v4 v4.25.4/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35 h1:wAZbkTZkqDzWsqxPh2qkBd3KvFU7tcxV0BP0Rnhkxog=
github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35/go.mod h1:aMd4yDHLjbOuYP6fMxj1d9ACDQlSWwYztcpybGHCQc8=
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/vcaesar/gops v0.41.0 h1:FG748Jyw3FOuZnbzSgB+CQSx2e5LbLCPWV2JU1brFdc=
github.com/vcaesar/gops v0.41.0/go.mod h1:/3048L7Rj7QjQKTSB+kKc7hDm63YhTWy5QJ10TCP37A=
github.com/vcaesar/imgo v0.41.0 h1:kNLYGrThXhB9Dd6IwFmfPnxq9P6yat2g7dpPjr7OWO8=
github.com/vcaesar/imgo v0.41.0/go.mod h1:/LGOge8etlzaVu/7l+UfhJxR6QqaoX5yeuzGIMfWb4I=
github.com/vcaesar/keycode v0.10.1 h1:0DesGmMAPWpYTCYddOFiCMKCDKgNnwiQa2QXindVUHw=
github.com/vcaesar/keycode v0.10.1/go.mod h1:JNlY7xbKsh+LAGfY2j4M3znVrGEm5W1R8s/Uv6BJcfQ=
github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA=
github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
github.com/vcaesar/screenshot v0.11.1 h1:GgPuN89XC4Yh38dLx4quPlSo3YiWWhwIria/j3LtrqU=
github.com/vcaesar/screenshot v0.11.1/go.mod h1:gJNwHBiP1v1v7i8TQ4yV1XJtcyn2I/OJL7OziVQkwjs=
github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
github.com/vcaesar/tt v0.20.1/go.mod h1:cH2+AwGAJm19Wa6xvEa+0r+sXDJBT0QgNQey6mwqLeU=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

6
key.go
View File

@ -416,7 +416,7 @@ func keyTaps(k string, keyArr []string, pid int) error {
return nil
}
func keyToggles(k string, keyArr []string, pid int, args ...interface{}) error {
func keyToggles(k string, keyArr []string, pid int) error {
if len(keyArr) <= 0 {
keyArr = append(keyArr, "down")
}
@ -437,9 +437,7 @@ func keyToggles(k string, keyArr []string, pid int, args ...interface{}) error {
}
C.toggleKeyCode(key, C.bool(down), flags, C.uintptr(pid))
if len(args) > 0 {
MilliSleep(KeySleep)
}
MilliSleep(KeySleep)
return nil
}

View File

@ -179,7 +179,7 @@ enum _MMKeyCode {
K_SHIFT = XK_Shift_L,
K_LSHIFT = XK_Shift_L,
K_RSHIFT = XK_Shift_R,
K_CAPSLOCK = XK_Shift_Lock,
K_CAPSLOCK = XK_Caps_Lock,
K_SPACE = XK_space,
K_INSERT = XK_Insert,
K_PRINTSCREEN = XK_Print,

View File

@ -90,7 +90,8 @@ MMKeyCode keyCodeForChar(const char c) {
#if defined(IS_MACOSX)
CFStringRef createStringForKey(CGKeyCode keyCode){
TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardInputSource();
// TISInputSourceRef currentKeyboard = TISCopyCurrentASCIICapableKeyboardInputSource();
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardLayoutInputSource();
CFDataRef layoutData = (CFDataRef) TISGetInputSourceProperty(
currentKeyboard, kTISPropertyUnicodeKeyLayoutData);

View File

@ -58,7 +58,7 @@
if (pid != 0) {
CGEventPostToPid(pid, event);
} else {
CGEventPost(kCGSessionEventTap, event);
CGEventPost(kCGHIDEventTap, event);
}
CFRelease(event);
@ -179,7 +179,8 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags, uintptr pi
NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE);
assert(KERN_SUCCESS == kr);
} else {
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)code, down);
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef keyEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)code, down);
assert(keyEvent != NULL);
CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp);
@ -188,6 +189,7 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags, uintptr pi
}
SendTo(pid, keyEvent);
CFRelease(source);
}
#elif defined(IS_WINDOWS)
const DWORD dwFlags = down ? 0 : KEYEVENTF_KEYUP;
@ -273,7 +275,8 @@ void toggleKey(char c, const bool down, MMKeyFlags flags, uintptr pid) {
convert characters to a keycode, but does not support adding modifier flags.
It is only used in typeString().
-- if you need modifier keys, use the above functions instead. */
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, 0, down);
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef keyEvent = CGEventCreateKeyboardEvent(source, 0, down);
if (keyEvent == NULL) {
fputs("Could not create keyboard event.\n", stderr);
return;
@ -282,6 +285,7 @@ void toggleKey(char c, const bool down, MMKeyFlags flags, uintptr pid) {
CGEventKeyboardSetUnicodeString(keyEvent, 1, &ch);
SendTo(pid, keyEvent);
CFRelease(source);
}
#else
#define toggleUniKey(c, down) toggleKey(c, down, MOD_NONE, 0)

View File

@ -83,51 +83,37 @@
/* Move the mouse to a specific point. */
void moveMouse(MMPointInt32 point){
#if defined(IS_MACOSX)
CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved,
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef move = CGEventCreateMouseEvent(source, kCGEventMouseMoved,
CGPointFromMMPointInt32(point), kCGMouseButtonLeft);
calculateDeltas(&move, point);
CGEventPost(kCGSessionEventTap, move);
CGEventPost(kCGHIDEventTap, move);
CFRelease(move);
CFRelease(source);
#elif defined(USE_X11)
Display *display = XGetMainDisplay();
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, point.x, point.y);
XSync(display, false);
#elif defined(IS_WINDOWS)
// Mouse motion is now done using SendInput with MOUSEINPUT.
// We use Absolute mouse positioning
#define MOUSE_COORD_TO_ABS(coord, width_or_height) ( \
((65536 * coord) / width_or_height) + (coord < 0 ? -1 : 1))
MMRectInt32 rect = getScreenRect(1);
int32_t x = MOUSE_COORD_TO_ABS(point.x - rect.origin.x, rect.size.w);
int32_t y = MOUSE_COORD_TO_ABS(point.y - rect.origin.y, rect.size.h);
INPUT mouseInput;
mouseInput.type = INPUT_MOUSE;
mouseInput.mi.dx = x;
mouseInput.mi.dy = y;
mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
mouseInput.mi.time = 0; // System will provide the timestamp
mouseInput.mi.dwExtraInfo = 0;
mouseInput.mi.mouseData = 0;
SendInput(1, &mouseInput, sizeof(mouseInput));
SetCursorPos(point.x, point.y);
#endif
}
void dragMouse(MMPointInt32 point, const MMMouseButton button){
#if defined(IS_MACOSX)
const CGEventType dragType = MMMouseDragToCGEventType(button);
CGEventRef drag = CGEventCreateMouseEvent(NULL, dragType,
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef drag = CGEventCreateMouseEvent(source, dragType,
CGPointFromMMPointInt32(point), (CGMouseButton)button);
calculateDeltas(&drag, point);
CGEventPost(kCGSessionEventTap, drag);
CGEventPost(kCGHIDEventTap, drag);
CFRelease(drag);
CFRelease(source);
#else
moveMouse(point);
#endif
@ -163,10 +149,12 @@ void toggleMouse(bool down, MMMouseButton button) {
#if defined(IS_MACOSX)
const CGPoint currentPos = CGPointFromMMPointInt32(location());
const CGEventType mouseType = MMMouseToCGEventType(down, button);
CGEventRef event = CGEventCreateMouseEvent(NULL, mouseType, currentPos, (CGMouseButton)button);
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef event = CGEventCreateMouseEvent(source, mouseType, currentPos, (CGMouseButton)button);
CGEventPost(kCGSessionEventTap, event);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
CFRelease(source);
#elif defined(USE_X11)
Display *display = XGetMainDisplay();
XTestFakeButtonEvent(display, button, down ? True : False, CurrentTime);
@ -200,7 +188,8 @@ void doubleClick(MMMouseButton button){
const CGEventType mouseTypeDown = MMMouseToCGEventType(true, button);
const CGEventType mouseTypeUP = MMMouseToCGEventType(false, button);
CGEventRef event = CGEventCreateMouseEvent(NULL, mouseTypeDown, currentPos, kCGMouseButtonLeft);
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef event = CGEventCreateMouseEvent(source, mouseTypeDown, currentPos, kCGMouseButtonLeft);
/* Set event to double click. */
CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
@ -210,6 +199,7 @@ void doubleClick(MMMouseButton button){
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
CFRelease(source);
#else
/* Double click for everything else. */
clickMouse(button);
@ -226,14 +216,13 @@ void scrollMouseXY(int x, int y) {
INPUT mouseScrollInputV;
#endif
/* Direction should only be considered based on the scrollDirection. This Should not interfere. */
/* Set up the OS specific solution */
#if defined(__APPLE__)
CGEventRef event;
event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 2, y, x);
#if defined(IS_MACOSX)
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef event = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitPixel, 2, y, x);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
CFRelease(source);
#elif defined(USE_X11)
int ydir = 4; /* Button 4 is up, 5 is down. */
int xdir = 6;

View File

@ -31,8 +31,12 @@ package robotgo
/*
#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations
#cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit
#cgo darwin LDFLAGS: -framework Carbon -framework CoreFoundation
#cgo darwin LDFLAGS: -framework Cocoa -framework CoreFoundation -framework IOKit
#cgo darwin LDFLAGS: -framework Carbon -framework OpenGL
//
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 140400
#cgo darwin LDFLAGS: -framework ScreenCaptureKit
#endif
#cgo linux CFLAGS: -I/usr/src
#cgo linux LDFLAGS: -L/usr/src -lm -lX11 -lXtst
@ -46,6 +50,7 @@ package robotgo
import "C"
import (
"errors"
"image"
"runtime"
"time"
@ -68,7 +73,7 @@ var (
// MouseSleep set the mouse default millisecond sleep time
MouseSleep = 0
// KeySleep set the key default millisecond sleep time
KeySleep = 0
KeySleep = 10
// DisplayID set the screen display id
DisplayID = -1
@ -86,6 +91,8 @@ type (
CHex C.MMRGBHex
// CBitmap define CBitmap as C.MMBitmapRef type
CBitmap C.MMBitmapRef
// Handle define window Handle as C.MData type
Handle C.MData
)
// Bitmap define the go Bitmap struct
@ -359,12 +366,15 @@ func CaptureGo(args ...int) Bitmap {
return ToBitmap(bit)
}
// CaptureImg capture the screen and return image.Image
func CaptureImg(args ...int) image.Image {
// CaptureImg capture the screen and return image.Image, error
func CaptureImg(args ...int) (image.Image, error) {
bit := CaptureScreen(args...)
if bit == nil {
return nil, errors.New("Capture image not found.")
}
defer FreeBitmap(bit)
return ToImage(bit)
return ToImage(bit), nil
}
// FreeBitmap free and dealloc the C bitmap
@ -453,6 +463,11 @@ func GetXDisplayName() string {
return gname
}
// CloseMainDisplay close the main X11 display
func CloseMainDisplay() {
C.close_main_display()
}
// Deprecated: use the ScaledF(),
//
// ScaleX get the primary display horizontal DPI scale factor, drop
@ -491,7 +506,7 @@ func CheckMouse(btn string) C.MMMouseButton {
// MoveScale calculate the os scale factor x, y
func MoveScale(x, y int, displayId ...int) (int, int) {
if Scale && runtime.GOOS == "windows" {
if Scale || runtime.GOOS == "windows" {
f := ScaleF()
x, y = Scaled1(x, f), Scaled1(y, f)
}
@ -540,8 +555,6 @@ func Drag(x, y int, args ...string) {
//
// robotgo.DragSmooth(10, 10)
func DragSmooth(x, y int, args ...interface{}) {
x, y = MoveScale(x, y)
Toggle("left")
MilliSleep(50)
MoveSmooth(x, y, args...)
@ -617,7 +630,7 @@ func Location() (int, int) {
x := int(pos.x)
y := int(pos.y)
if runtime.GOOS == "windows" {
if Scale || runtime.GOOS == "windows" {
f := ScaleF()
x, y = Scaled0(x, f), Scaled0(y, f)
}
@ -868,12 +881,22 @@ func IsValid() bool {
}
// SetActive set the window active
func SetActive(win C.MData) {
func SetActive(win Handle) {
SetActiveC(C.MData(win))
}
// SetActiveC set the window active
func SetActiveC(win C.MData) {
C.set_active(win)
}
// GetActive get the active window
func GetActive() C.MData {
func GetActive() Handle {
return Handle(GetActiveC())
}
// GetActiveC get the active window
func GetActiveC() C.MData {
mdata := C.get_active()
// fmt.Println("active----", mdata)
return mdata
@ -947,8 +970,29 @@ func SetHandlePid(pid int, args ...int) {
C.set_handle_pid_mData(C.uintptr(pid), C.int8_t(isPid))
}
// GetHandById get handle mdata by id
func GetHandById(id int, args ...int) Handle {
isPid := 1
if len(args) > 0 {
isPid = args[0]
}
return GetHandByPid(id, isPid)
}
// GetHandByPid get handle mdata by pid
func GetHandByPid(pid int, args ...int) Handle {
return Handle(GetHandByPidC(pid, args...))
}
// Deprecated: use the GetHandByPid(),
//
// GetHandPid get handle mdata by pid
func GetHandPid(pid int, args ...int) C.MData {
func GetHandPid(pid int, args ...int) Handle {
return GetHandByPid(pid, args...)
}
// GetHandByPidC get handle mdata by pid
func GetHandByPidC(pid int, args ...int) C.MData {
var isPid int
if len(args) > 0 || NotPid {
isPid = 1

View File

@ -179,7 +179,8 @@ func TestImage(t *testing.T) {
err := SavePng(img, "robot_test.png")
tt.Nil(t, err)
img1 := CaptureImg(10, 10, 20, 20)
img1, err := CaptureImg(10, 10, 20, 20)
tt.Nil(t, err)
e := Save(img1, "robot_img.jpeg", 50)
tt.Nil(t, e)

View File

@ -17,7 +17,8 @@ import (
"syscall"
"unsafe"
"github.com/lxn/win"
// "github.com/lxn/win"
"github.com/tailscale/win"
)
// FindWindow find window hwnd by name
@ -57,7 +58,7 @@ func SetForeg(hwnd win.HWND) bool {
return win.SetForegroundWindow(hwnd)
}
// GetMian get the main display hwnd
// GetMain get the main display hwnd
func GetMain() win.HWND {
return win.GetActiveWindow()
}

View File

@ -190,7 +190,7 @@ func DisplaysNum() int {
return int(reply.Number)
}
// GetMianId get the main display id
// GetMainId get the main display id
func GetMainId() int {
conn, err := xgb.NewConn()
if err != nil {

View File

@ -13,16 +13,17 @@ package robotgo
import (
"image"
"github.com/kbinani/screenshot"
// "github.com/kbinani/screenshot"
"github.com/vcaesar/screenshot"
)
// GetScreenBound gets the display screen bounds
// GetDisplayBounds gets the display screen bounds
func GetDisplayBounds(i int) (x, y, w, h int) {
bs := screenshot.GetDisplayBounds(i)
return bs.Min.X, bs.Min.Y, bs.Dx(), bs.Dy()
}
// GetDisplayBounds gets the display rect
// GetDisplayRect gets the display rect
func GetDisplayRect(i int) Rect {
x, y, w, h := GetDisplayBounds(i)
return Rect{
@ -30,7 +31,7 @@ func GetDisplayRect(i int) Rect {
Size{W: w, H: h}}
}
// Capture capture the screenshot
// Capture capture the screenshot, use the CaptureImg default
func Capture(args ...int) (*image.RGBA, error) {
displayId := 0
if DisplayID != -1 {
@ -50,3 +51,13 @@ func Capture(args ...int) (*image.RGBA, error) {
return screenshot.Capture(x, y, w, h)
}
// SaveCapture capture screen and save the screenshot to image
func SaveCapture(path string, args ...int) error {
img, err := CaptureImg(args...)
if err != nil {
return err
}
return Save(img, path)
}

View File

@ -12,7 +12,6 @@
#include "../base/pubs.h"
#include "../base/rgb.h"
#include "screengrab_c.h"
#include "screen_c.h"
#include <stdio.h>
void padHex(MMRGBHex color, char* hex) {
@ -79,6 +78,14 @@ char* get_XDisplay_name() {
#endif
}
void close_main_display() {
#if defined(USE_X11)
XCloseMainDisplay();
#else
//
#endif
}
uint32_t get_num_displays() {
#if defined(IS_MACOSX)
uint32_t count = 0;

View File

@ -4,9 +4,70 @@
#include <ApplicationServices/ApplicationServices.h>
#elif defined(USE_X11)
#include <X11/Xlib.h>
#include <X11/Xresource.h>
// #include "../base/xdisplay_c.h"
#endif
intptr scaleX();
double sys_scale(int32_t display_id) {
#if defined(IS_MACOSX)
CGDirectDisplayID displayID = (CGDirectDisplayID) display_id;
if (displayID == -1) {
displayID = CGMainDisplayID();
}
CGDisplayModeRef modeRef = CGDisplayCopyDisplayMode(displayID);
double pixelWidth = CGDisplayModeGetPixelWidth(modeRef);
double targetWidth = CGDisplayModeGetWidth(modeRef);
return pixelWidth / targetWidth;
#elif defined(USE_X11)
Display *dpy = XOpenDisplay(NULL);
int scr = 0; /* Screen number */
double xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
((double) DisplayWidthMM(dpy, scr)));
char *rms = XResourceManagerString(dpy);
if (rms) {
XrmDatabase db = XrmGetStringDatabase(rms);
if (db) {
XrmValue value;
char *type = NULL;
if (XrmGetResource(db, "Xft.dpi", "String", &type, &value)) {
if (value.addr) {
xres = atof(value.addr);
}
}
XrmDestroyDatabase(db);
}
}
XCloseDisplay (dpy);
return xres / 96.0;
#elif defined(IS_WINDOWS)
double s = scaleX() / 96.0;
return s;
#endif
}
intptr scaleX(){
#if defined(IS_MACOSX)
return 0;
#elif defined(USE_X11)
return 0;
#elif defined(IS_WINDOWS)
// Get desktop dc
HDC desktopDc = GetDC(NULL);
// Get native resolution
intptr horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
return horizontalDPI;
#endif
}
MMSizeInt32 getMainDisplaySize(void) {
#if defined(IS_MACOSX)
CGDirectDisplayID displayID = CGMainDisplayID();

View File

@ -5,6 +5,7 @@
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include <ApplicationServices/ApplicationServices.h>
#include <ScreenCaptureKit/ScreenCaptureKit.h>
#elif defined(USE_X11)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -12,6 +13,56 @@
#elif defined(IS_WINDOWS)
#include <string.h>
#endif
#include "screen_c.h"
#if defined(IS_MACOSX) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 140400
static CGImageRef capture15(CGDirectDisplayID id, CGRect diIntersectDisplayLocal, CGColorSpaceRef colorSpace) {
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block CGImageRef image1 = nil;
[SCShareableContent getShareableContentWithCompletionHandler:^(SCShareableContent* content, NSError* error) {
@autoreleasepool {
if (error) {
dispatch_semaphore_signal(semaphore);
return;
}
SCDisplay* target = nil;
for (SCDisplay *display in content.displays) {
if (display.displayID == id) {
target = display;
break;
}
}
if (!target) {
dispatch_semaphore_signal(semaphore);
return;
}
SCContentFilter* filter = [[SCContentFilter alloc] initWithDisplay:target excludingWindows:@[]];
SCStreamConfiguration* config = [[SCStreamConfiguration alloc] init];
config.queueDepth = 5;
config.sourceRect = diIntersectDisplayLocal;
config.width = diIntersectDisplayLocal.size.width * sys_scale(id);
config.height = diIntersectDisplayLocal.size.height * sys_scale(id);
config.scalesToFit = false;
config.captureResolution = 1;
[SCScreenshotManager captureImageWithFilter:filter
configuration:config
completionHandler:^(CGImageRef img, NSError* error) {
if (!error) {
image1 = CGImageCreateCopyWithColorSpace(img, colorSpace);
}
dispatch_semaphore_signal(semaphore);
}];
}
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_release(semaphore);
return image1;
}
#endif
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id, int8_t isPid) {
#if defined(IS_MACOSX)
@ -25,9 +76,16 @@ MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id,
}
MMPointInt32 o = rect.origin; MMSizeInt32 s = rect.size;
CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(o.x, o.y, s.w, s.h));
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 140400
CGColorSpaceRef color = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGImageRef image = capture15(displayID, CGRectMake(o.x, o.y, s.w, s.h), color);
CGColorSpaceRelease(color);
#else
// This API is deprecated in macos 15, use ScreenCaptureKit's captureScreenshot
CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(o.x, o.y, s.w, s.h));
#endif
if (!image) { return NULL; }
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image));
if (!imageData) { return NULL; }

2
wayland_n.go Normal file
View File

@ -0,0 +1,2 @@
// +bulid linux,next
package robotgo

View File

@ -55,11 +55,11 @@ uintptr get_handle(){
uintptr b_get_handle() {
#if defined(IS_MACOSX)
return (uintptr)mData.CgID;
return (uintptr)pub_mData.CgID;
#elif defined(USE_X11)
return (uintptr)mData.XWin;
return (uintptr)pub_mData.XWin;
#elif defined(IS_WINDOWS)
return (uintptr)mData.HWnd;
return (uintptr)pub_mData.HWnd;
#endif
}

View File

@ -28,7 +28,7 @@ struct _MData{
};
typedef struct _MData MData;
MData mData;
MData pub_mData;
struct _Bounds {
int32_t X; // Top left X coordinate

View File

@ -8,70 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#if defined(USE_X11)
#include <X11/Xresource.h>
#endif
// #if defined(USE_X11)
// #include <X11/Xresource.h>
// #endif
Bounds get_client(uintptr pid, int8_t isPid);
intptr scaleX();
double sys_scale(int32_t display_id) {
#if defined(IS_MACOSX)
CGDirectDisplayID displayID = (CGDirectDisplayID) display_id;
if (displayID == -1) {
displayID = CGMainDisplayID();
}
CGDisplayModeRef modeRef = CGDisplayCopyDisplayMode(displayID);
double pixelWidth = CGDisplayModeGetPixelWidth(modeRef);
double targetWidth = CGDisplayModeGetWidth(modeRef);
return pixelWidth / targetWidth;
#elif defined(USE_X11)
Display *dpy = XOpenDisplay(NULL);
int scr = 0; /* Screen number */
double xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
((double) DisplayWidthMM(dpy, scr)));
char *rms = XResourceManagerString(dpy);
if (rms) {
XrmDatabase db = XrmGetStringDatabase(rms);
if (db) {
XrmValue value;
char *type = NULL;
if (XrmGetResource(db, "Xft.dpi", "String", &type, &value)) {
if (value.addr) {
xres = atof(value.addr);
}
}
XrmDestroyDatabase(db);
}
}
XCloseDisplay (dpy);
return xres / 96.0;
#elif defined(IS_WINDOWS)
double s = scaleX() / 96.0;
return s;
#endif
}
intptr scaleX(){
#if defined(IS_MACOSX)
return 0;
#elif defined(USE_X11)
return 0;
#elif defined(IS_WINDOWS)
// Get desktop dc
HDC desktopDc = GetDC(NULL);
// Get native resolution
intptr horizontalDPI = GetDeviceCaps(desktopDc, LOGPIXELSX);
return horizontalDPI;
#endif
}
Bounds get_bounds(uintptr pid, int8_t isPid){
// Check if the window is valid

View File

@ -24,8 +24,8 @@ uintptr initHandle = 0;
void initWindow(uintptr handle){
#if defined(IS_MACOSX)
mData.CgID = 0;
mData.AxID = 0;
pub_mData.CgID = 0;
pub_mData.AxID = 0;
#elif defined(USE_X11)
Display *rDisplay = XOpenDisplay(NULL);
// If atoms loaded
@ -34,10 +34,10 @@ void initWindow(uintptr handle){
if (rDisplay != NULL) {LoadAtoms();}
}
mData.XWin = 0;
pub_mData.XWin = 0;
XCloseDisplay(rDisplay);
#elif defined(IS_WINDOWS)
mData.HWnd = 0;
pub_mData.HWnd = 0;
#endif
setHandle(handle);
}
@ -67,33 +67,33 @@ MData set_handle_pid(uintptr pid, int8_t isPid){
void set_handle_pid_mData(uintptr pid, int8_t isPid){
MData win = set_handle_pid(pid, isPid);
mData = win;
pub_mData = win;
}
bool is_valid() {
initWindow(initHandle);
if (!IsAxEnabled(true)) {
printf("%s\n", "Window: Accessibility API is disabled!\n"
"Failed to enable access for assistive devices.");
printf("%s\n", "Window: Accessibility API is disabled! "
"Failed to enable access for assistive devices. \n");
}
MData actdata = get_active();
#if defined(IS_MACOSX)
mData.CgID = actdata.CgID;
mData.AxID = actdata.AxID;
if (mData.CgID == 0 || mData.AxID == 0) { return false; }
pub_mData.CgID = actdata.CgID;
pub_mData.AxID = actdata.AxID;
if (pub_mData.CgID == 0 || pub_mData.AxID == 0) { return false; }
CFTypeRef r = NULL;
// Attempt to get the window role
if (AXUIElementCopyAttributeValue(mData.AxID, kAXRoleAttribute, &r) == kAXErrorSuccess && r){
if (AXUIElementCopyAttributeValue(pub_mData.AxID, kAXRoleAttribute, &r) == kAXErrorSuccess && r){
CFRelease(r);
return true;
}
return false;
#elif defined(USE_X11)
mData.XWin = actdata.XWin;
if (mData.XWin == 0) { return false; }
pub_mData.XWin = actdata.XWin;
if (pub_mData.XWin == 0) { return false; }
Display *rDisplay = XOpenDisplay(NULL);
// Check for a valid X-Window display
@ -103,7 +103,7 @@ bool is_valid() {
XDismissErrors();
// Get the window PID property
void* result = GetWindowProperty(mData, WM_PID,NULL);
void* result = GetWindowProperty(pub_mData, WM_PID,NULL);
if (result == NULL) {
XCloseDisplay(rDisplay);
return false;
@ -115,12 +115,12 @@ bool is_valid() {
return true;
#elif defined(IS_WINDOWS)
mData.HWnd = actdata.HWnd;
if (mData.HWnd == 0) {
pub_mData.HWnd = actdata.HWnd;
if (pub_mData.HWnd == 0) {
return false;
}
return IsWindow(mData.HWnd) != 0;
return IsWindow(pub_mData.HWnd) != 0;
#endif
}
@ -175,13 +175,13 @@ bool IsAxEnabled(bool options){
bool setHandle(uintptr handle){
#if defined(IS_MACOSX)
// Release the AX element
if (mData.AxID != NULL) {
CFRelease(mData.AxID);
if (pub_mData.AxID != NULL) {
CFRelease(pub_mData.AxID);
}
// Reset both values
mData.CgID = 0;
mData.AxID = 0;
pub_mData.CgID = 0;
pub_mData.AxID = 0;
if (handle == 0) {
// return 0;
@ -192,8 +192,8 @@ bool setHandle(uintptr handle){
CGWindowID cgID = (CGWindowID)handle;
AXUIElementRef axID = GetUIElement(cgID);
if (axID != NULL){
mData.CgID = cgID;
mData.AxID = axID;
pub_mData.CgID = cgID;
pub_mData.AxID = axID;
// return 0;
return true;
}
@ -201,7 +201,7 @@ bool setHandle(uintptr handle){
// return 1;
return false;
#elif defined(USE_X11)
mData.XWin = (Window)handle;
pub_mData.XWin = (Window)handle;
if (handle == 0) {
return true;
}
@ -210,10 +210,10 @@ bool setHandle(uintptr handle){
return true;
}
mData.XWin = 0;
pub_mData.XWin = 0;
return false;
#elif defined(IS_WINDOWS)
mData.HWnd = (HWND)handle;
pub_mData.HWnd = (HWND)handle;
if (handle == 0) {
return true;
}
@ -222,7 +222,7 @@ bool setHandle(uintptr handle){
return true;
}
mData.HWnd = 0;
pub_mData.HWnd = 0;
return false;
#endif
}
@ -237,7 +237,7 @@ bool IsTopMost(void){
// XDismissErrors ();
// return GetState (mData.XWin, STATE_TOPMOST);
#elif defined(IS_WINDOWS)
return (GetWindowLongPtr(mData.HWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
return (GetWindowLongPtr(pub_mData.HWnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0;
#endif
}
@ -247,7 +247,7 @@ bool IsMinimized(void){
#if defined(IS_MACOSX)
CFBooleanRef data = NULL;
// Determine whether the window is minimized
if (AXUIElementCopyAttributeValue(mData.AxID, kAXMinimizedAttribute,
if (AXUIElementCopyAttributeValue(pub_mData.AxID, kAXMinimizedAttribute,
(CFTypeRef*) &data) == kAXErrorSuccess && data != NULL) {
// Convert resulting data into a bool
bool result = CFBooleanGetValue(data);
@ -261,7 +261,7 @@ bool IsMinimized(void){
// XDismissErrors();
// return GetState(mData.XWin, STATE_MINIMIZE);
#elif defined(IS_WINDOWS)
return (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MINIMIZE) != 0;
return (GetWindowLongPtr(pub_mData.HWnd, GWL_STYLE) & WS_MINIMIZE) != 0;
#endif
}
@ -276,7 +276,7 @@ bool IsMaximized(void){
// XDismissErrors();
// return GetState(mData.XWin, STATE_MAXIMIZE);
#elif defined(IS_WINDOWS)
return (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;
return (GetWindowLongPtr(pub_mData.HWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;
#endif
}
@ -367,11 +367,11 @@ MData get_active(void) {
if (focused == NULL) { return result; } // Verify
AXUIElementRef element;
CGWindowID win = 0;
// Retrieve the currently focused window
if (AXUIElementCopyAttributeValue(focused, kAXFocusedWindowAttribute, (CFTypeRef*) &element)
== kAXErrorSuccess && element) {
CGWindowID win = 0;
// Use undocumented API to get WID
if (_AXUIElementGetWindow(element, &win) == kAXErrorSuccess && win) {
// Manually set internals
@ -380,6 +380,9 @@ MData get_active(void) {
} else {
CFRelease(element);
}
} else {
result.CgID = win;
result.AxID = element;
}
CFRelease(focused);
@ -450,9 +453,9 @@ void SetTopMost(bool state){
#elif defined(USE_X11)
// Ignore X errors
// XDismissErrors();
// SetState(mData.XWin, STATE_TOPMOST, state);
// SetState(pub_mData.XWin, STATE_TOPMOST, state);
#elif defined(IS_WINDOWS)
SetWindowPos(mData.HWnd, state ? HWND_TOPMOST : HWND_NOTOPMOST,
SetWindowPos(pub_mData.HWnd, state ? HWND_TOPMOST : HWND_NOTOPMOST,
0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
#endif
}
@ -461,7 +464,7 @@ void close_main_window () {
// Check if the window is valid
if (!is_valid()) { return; }
close_window_by_Id(mData);
close_window_by_Id(pub_mData);
}
void close_window_by_PId(uintptr pid, int8_t isPid){
@ -499,7 +502,7 @@ char* get_main_title(){
// Check if the window is valid
if (!is_valid()) { return "is_valid failed."; }
return get_title_by_hand(mData);
return get_title_by_hand(pub_mData);
}
char* get_title_by_pid(uintptr pid, int8_t isPid){
@ -588,7 +591,7 @@ int32_t get_PID(void) {
#if defined(IS_MACOSX)
pid_t pid = 0;
// Attempt to retrieve the window pid
if (AXUIElementGetPid(mData.AxID, &pid)== kAXErrorSuccess) {
if (AXUIElementGetPid(pub_mData.AxID, &pid)== kAXErrorSuccess) {
return pid;
}
return 0;
@ -597,7 +600,7 @@ int32_t get_PID(void) {
XDismissErrors();
// Get the window PID
long* result = (long*)GetWindowProperty(mData, WM_PID,NULL);
long* result = (long*)GetWindowProperty(pub_mData, WM_PID,NULL);
// Check result and convert it
if (result == NULL) { return 0; }
@ -606,7 +609,7 @@ int32_t get_PID(void) {
return pid;
#elif defined(IS_WINDOWS)
DWORD id = 0;
GetWindowThreadProcessId(mData.HWnd, &id);
GetWindowThreadProcessId(pub_mData.HWnd, &id);
return id;
#endif
}

2
windows_n.go Normal file
View File

@ -0,0 +1,2 @@
// +bulid windows,next
package robotgo