mirror of
https://github.com/go-vgo/robotgo.git
synced 2025-05-31 06:13:55 +00:00
Compare commits
70 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a8c387a070 | ||
![]() |
3eef3b5879 | ||
![]() |
b731094f61 | ||
![]() |
8d4679db07 | ||
![]() |
02c668a946 | ||
![]() |
5c2864485d | ||
![]() |
f101b10497 | ||
![]() |
73c07dc991 | ||
![]() |
fc47bc8216 | ||
![]() |
912ddcbfe4 | ||
![]() |
57b5e5bca2 | ||
![]() |
8031f7f526 | ||
![]() |
36bc85ad19 | ||
![]() |
5fc2bd4c73 | ||
![]() |
47abfac5ee | ||
![]() |
df0731c4df | ||
![]() |
03432155c1 | ||
![]() |
6a1f060a8c | ||
![]() |
e924f25fe1 | ||
![]() |
d300eedf54 | ||
![]() |
c07f3f0171 | ||
![]() |
0b18fa5058 | ||
![]() |
471f7ba05f | ||
![]() |
a84a195c4c | ||
![]() |
c8df366f89 | ||
![]() |
70f811ce53 | ||
![]() |
ecc260ea31 | ||
![]() |
78d01703b8 | ||
![]() |
47cde13dab | ||
![]() |
8db59aac2d | ||
![]() |
217d6cf1f1 | ||
![]() |
75fd24ea0a | ||
![]() |
bed6776ca2 | ||
![]() |
1923d7bb48 | ||
![]() |
ead43d062e | ||
![]() |
3258566802 | ||
![]() |
0de26ecee4 | ||
![]() |
c48e3d072c | ||
![]() |
b1ad7db6be | ||
![]() |
0110b85d40 | ||
![]() |
3e5b10f720 | ||
![]() |
cb51e2aa10 | ||
![]() |
85f2702683 | ||
![]() |
5b9871b063 | ||
![]() |
b201ab9f80 | ||
![]() |
d3e364fa26 | ||
![]() |
1f437d12e4 | ||
![]() |
c5110d0ac8 | ||
![]() |
f98b4c52bd | ||
![]() |
f1db2ede4a | ||
![]() |
d90493e63e | ||
![]() |
63eb594ea5 | ||
![]() |
8a990ac042 | ||
![]() |
bf1758b424 | ||
![]() |
9424b71a73 | ||
![]() |
6c137427db | ||
![]() |
ffbf4f875b | ||
![]() |
05c54c6f25 | ||
![]() |
3171c5bdff | ||
![]() |
b718cf4a8c | ||
![]() |
bfc28d12fa | ||
![]() |
e9421b58b6 | ||
![]() |
4d780b9908 | ||
![]() |
39818d41fa | ||
![]() |
eacf74f488 | ||
![]() |
61b77ce3e1 | ||
![]() |
01e4fffcb8 | ||
![]() |
e2f5f54804 | ||
![]() |
f22f063926 | ||
![]() |
722feb7ba3 |
@ -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
|
||||
|
@ -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 \
|
||||
|
4
.github/workflows/go.yml
vendored
4
.github/workflows/go.yml
vendored
@ -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
|
||||
|
52
README.md
52
README.md
@ -10,7 +10,7 @@
|
||||
[](https://travis-ci.org/go-vgo/robotgo)
|
||||

|
||||
[](https://goreportcard.com/report/github.com/go-vgo/robotgo)
|
||||
[](https://godoc.org/github.com/go-vgo/robotgo)
|
||||
[](https://pkg.go.dev/github.com/go-vgo/robotgo?tab=doc)
|
||||
[](https://github.com/go-vgo/robotgo/releases/latest)
|
||||
[](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))
|
||||
|
@ -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
|
||||
|
@ -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
46
go.mod
@ -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
147
go.sum
@ -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
6
key.go
@ -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
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
70
robotgo.go
70
robotgo.go
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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 {
|
||||
|
19
screen.go
19
screen.go
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
2
wayland_n.go
Normal file
@ -0,0 +1,2 @@
|
||||
// +bulid linux,next
|
||||
package robotgo
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ struct _MData{
|
||||
};
|
||||
|
||||
typedef struct _MData MData;
|
||||
MData mData;
|
||||
MData pub_mData;
|
||||
|
||||
struct _Bounds {
|
||||
int32_t X; // Top left X coordinate
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
@ -453,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
|
||||
}
|
||||
@ -464,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){
|
||||
@ -502,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){
|
||||
@ -591,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;
|
||||
@ -600,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; }
|
||||
|
||||
@ -609,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
2
windows_n.go
Normal file
@ -0,0 +1,2 @@
|
||||
// +bulid windows,next
|
||||
package robotgo
|
Loading…
Reference in New Issue
Block a user