Compare commits

...

85 Commits

Author SHA1 Message Date
Evans
dd208c6dd1
Merge pull request from cnwangjie/fix-window-mac
Fix: use window ref instead of app ref to get bounds on macos
2025-06-15 12:16:48 -07:00
Wang Jie
ae4390f607 Fix: use window ref instead of app ref to get bounds on macos 2025-06-15 00:05:35 +08:00
vcaesar
48706562fc Update: unify and clean License to Apache2.0 2025-06-08 10:51:14 -07:00
Evans
023426ab13
Merge pull request from go-vgo/bitmap-pr
Fix: return key
2025-06-06 09:17:35 -07:00
vcaesar
d34a1491cb Fix: return key 2025-06-03 11:25:15 -07:00
Evans
c431c8f974
Merge pull request from go-vgo/bitmap-pr
Update: simply key code
2025-06-03 11:19:24 -07:00
vcaesar
a183783e9c Update: simply key code 2025-06-03 11:16:33 -07:00
vcaesar
c1115cebc7 Update: update import 2025-05-23 19:00:53 -07:00
Evans
a8c387a070
Merge pull request from go-vgo/bitmap-pr
Update: use hid event in macos
2025-05-17 13:04:47 -07:00
vcaesar
3eef3b5879 Add: add CGEventSourceRef source 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 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 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 from go-vgo/bitmap-pr
Update: update import
2025-04-19 12:56:42 -07:00
vcaesar
8031f7f526 Update: update import 2025-04-19 12:54:47 -07:00
Evans
36bc85ad19
Merge pull request from go-vgo/bitmap-pr
Fix: fixed mac os version min required 
2025-04-19 10:06:37 -07:00
vcaesar
5fc2bd4c73 Fix: fixed mac os version min required 2025-04-19 10:05:01 -07:00
Evans
47abfac5ee
Merge pull request from go-vgo/bitmap-pr
Fixed: fixed windows Scale  and Update readme.md
2025-04-11 14:37:12 -07:00
vcaesar
df0731c4df Fixed: fixed windows Scale and Update readme.md 2025-04-11 14:34:15 -07:00
Evans
03432155c1
Merge pull request from go-vgo/bitmap-pr
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 2025-03-08 15:02:39 -08:00
Evans
e924f25fe1
Merge pull request from go-vgo/bitmap-pr
Update: updated go mod
2025-02-17 15:56:32 -08:00
vcaesar
d300eedf54 Update: updated go mod 2025-02-17 15:54:57 -08:00
Evans
c07f3f0171
Merge pull request from ronaldpetty/patch-1
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 from go-vgo/bitmap-pr
Update: update go mod
2024-10-07 14:17:46 -07:00
vcaesar
a84a195c4c Update: update go mod 2024-10-07 14:15:17 -07:00
Evans
c8df366f89
Merge pull request 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 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 ()
* 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 from go-vgo/bitmap-pr
Fixed: default use high capture resolution in macos15
2024-10-06 18:12:41 -07:00
vcaesar
75fd24ea0a Fixed: Fixed x11 build 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 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 from go-vgo/bitmap-pr
Add: export Handle data and add more window handle function 
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 2024-09-17 13:32:46 -07:00
Evans
0110b85d40
Merge pull request 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 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 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 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 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 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 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 from nzlov/patch-1
fix: DragSmooth Repeat Call MoveScale
2024-04-15 10:14:33 -07:00
Evans
ffbf4f875b
Merge pull request 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 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 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 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 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 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 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 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
Evans
ef191f2dfd
Merge pull request from go-vgo/bitmap-pr
Update: update gomod and fixed warning
2023-09-03 12:16:46 -07:00
vcaesar
44b2715de0 Merge remote-tracking branch 'origin/master' into bitmap-pr 2023-09-03 12:13:17 -07:00
vcaesar
90f41269da Update: update gomod and fixed warning 2023-09-03 12:12:56 -07:00
44 changed files with 588 additions and 442 deletions

View File

@ -5,7 +5,7 @@ jobs:
docker: docker:
# using custom image, see .circleci/images/primary/Dockerfile # using custom image, see .circleci/images/primary/Dockerfile
# - image: govgo/robotgoci:1.10.3 # - 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 working_directory: /gopath/src/github.com/go-vgo/robotgo
steps: steps:
- checkout - checkout

View File

@ -1,5 +1,5 @@
# FROM golang:1.10.1 # 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 # FROM govgo/go:1.11.1
RUN apt update && apt install -y --no-install-recommends \ RUN apt update && apt install -y --no-install-recommends \

View File

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

View File

@ -30,7 +30,6 @@ Before sending code out for review, run all the tests for the whole tree to make
In addition to the owner, Changes to Robotgo must be reviewed before they are accepted, no matter who makes the change even if it is a maintainer. We use GitHub's pull request workflow to do that and we also use [LGTM](http://lgtm.co) to ensure every PR is reviewed by vz or least 2 maintainers. In addition to the owner, Changes to Robotgo must be reviewed before they are accepted, no matter who makes the change even if it is a maintainer. We use GitHub's pull request workflow to do that and we also use [LGTM](http://lgtm.co) to ensure every PR is reviewed by vz or least 2 maintainers.
## Sign your work ## Sign your work
The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch. The sign-off is a simple line at the end of the explanation for the patch. Your signature certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch.
@ -43,7 +42,6 @@ To make sure every PR is checked, we got team maintainers. A maintainer should b
Since Robotgo is a pure community organization without any company support, Copyright 2016 The go-vgo Project Developers. Since Robotgo is a pure community organization without any company support, Copyright 2016 The go-vgo Project Developers.
## Versions ## Versions
Robotgo has the `master` branch as a tip branch and has version branches such as `v0.30.0`. `v0.40.0` is a release branch and we will tag `v0.40.0` for binary download. If `v0.40.0` has bugs, we will accept pull requests on the `v0.40.0` branch and publish a `v0.40.1` tag, after bringing the bug fix also to the master branch. Robotgo has the `master` branch as a tip branch and has version branches such as `v0.30.0`. `v0.40.0` is a release branch and we will tag `v0.40.0` for binary download. If `v0.40.0` has bugs, we will accept pull requests on the `v0.40.0` branch and publish a `v0.40.1` tag, after bringing the bug fix also to the master branch.
@ -60,9 +58,9 @@ Code that you contribute should use the standard copyright header:
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
``` ```

View File

@ -10,7 +10,7 @@
[![Build Status](https://travis-ci.org/go-vgo/robotgo.svg)](https://travis-ci.org/go-vgo/robotgo) [![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) ![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) [![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) [![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) [![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)
@ -62,7 +62,11 @@ GCC
#### For MacOS: #### For MacOS:
Xcode Command Line Tools (And Privacy setting: [#277](https://github.com/go-vgo/robotgo/issues/277) ) ```
brew install go
```
Xcode Command Line Tools (And Privacy setting: [#277](https://github.com/go-vgo/robotgo/issues/277))
``` ```
xcode-select --install xcode-select --install
@ -70,12 +74,20 @@ xcode-select --install
#### For Windows: #### For Windows:
[MinGW-w64](https://sourceforge.net/projects/mingw-w64/files) (Use recommended) ```
winget install Golang.go
```
```
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. 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). [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: #### For everything else:
@ -87,15 +99,18 @@ X11 with the XTest extension (the Xtst library)
"Clipboard": xsel xclip "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: ##### Ubuntu:
```yml ```yml
# sudo apt install golang
sudo snap install go --classic
# gcc # gcc
sudo apt install gcc libc6-dev sudo apt install gcc libc6-dev
@ -109,7 +124,7 @@ sudo apt install xsel xclip
# Bitmap # Bitmap
sudo apt install libpng++-dev 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 sudo apt install xcb libxcb-xkb-dev x11-xkb-utils libx11-xcb-dev libxkbcommon-x11-dev libxkbcommon-dev
``` ```
@ -127,7 +142,7 @@ sudo dnf install xsel xclip
# Bitmap # Bitmap
sudo dnf install libpng-devel sudo dnf install libpng-devel
# Hook # GoHook
sudo dnf install libxkbcommon-devel libxkbcommon-x11-devel xorg-x11-xkb-utils-devel sudo dnf install libxkbcommon-devel libxkbcommon-x11-devel xorg-x11-xkb-utils-devel
``` ```
@ -165,11 +180,18 @@ Note go1.10.x C file compilation cache problem, [golang #24355](https://github.c
package main package main
import ( import (
"fmt"
"github.com/go-vgo/robotgo" "github.com/go-vgo/robotgo"
) )
func main() { 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(10, "up")
robotgo.ScrollDir(20, "right") robotgo.ScrollDir(20, "right")
@ -244,6 +266,7 @@ package main
import ( import (
"fmt" "fmt"
"strconv"
"github.com/go-vgo/robotgo" "github.com/go-vgo/robotgo"
"github.com/vcaesar/imgo" "github.com/vcaesar/imgo"
@ -268,13 +291,18 @@ func main() {
num := robotgo.DisplaysNum() num := robotgo.DisplaysNum()
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
robotgo.DisplayID = i robotgo.DisplayID = i
img1 := robotgo.CaptureImg() img1, _ := robotgo.CaptureImg()
path1 := "save_" + strconv.Itoa(i) path1 := "save_" + strconv.Itoa(i)
robotgo.Save(img1, path1+".png") robotgo.Save(img1, path1+".png")
robotgo.SaveJpeg(img1, path1+".jpeg", 50) 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") 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 +382,8 @@ func opencv() {
// bit1 := robotgo.CaptureScreen(10, 10, 30, 30) // bit1 := robotgo.CaptureScreen(10, 10, 30, 30)
// img1 := robotgo.ToImage(bit1) // img1 := robotgo.ToImage(bit1)
// defer robotgo.FreeBitmapArr(bit0, bit1) // defer robotgo.FreeBitmapArr(bit0, bit1)
img := robotgo.CaptureImg() img, _ := robotgo.CaptureImg()
img1 := robotgo.CaptureImg(10, 10, 30, 30) img1, _ := robotgo.CaptureImg(10, 10, 30, 30)
fmt.Print("gcv find image: ") fmt.Print("gcv find image: ")
fmt.Println(gcv.FindImg(img1, img)) fmt.Println(gcv.FindImg(img1, img))
@ -509,6 +537,6 @@ func main() {
## License ## License
Robotgo is primarily distributed under the terms of "both the MIT license and the Apache License (Version 2.0)", with portions covered by various BSD-like licenses. Robotgo is primarily distributed under the terms of "the Apache License (Version 2.0)", with portions covered by various BSD-like licenses.
See [LICENSE-APACHE](http://www.apache.org/licenses/LICENSE-2.0), [LICENSE-MIT](https://github.com/go-vgo/robotgo/blob/master/LICENSE). See [LICENSE-APACHE](http://www.apache.org/licenses/LICENSE-2.0), [LICENSE](https://github.com/go-vgo/robotgo/blob/master/LICENSE).

View File

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

View File

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

6
doc.go
View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package main package main

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package main package main

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package main package main

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package main package main
@ -29,23 +29,29 @@ func bitmap() {
gbitMap := robotgo.CaptureGo() gbitMap := robotgo.CaptureGo()
fmt.Println("Go CaptureScreen...", gbitMap.Width) fmt.Println("Go CaptureScreen...", gbitMap.Width)
// fmt.Println("...", gbitmap.Width, gbitmap.BytesPerPixel) // 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") robotgo.Save(img, "save.png")
num := robotgo.DisplaysNum() num := robotgo.DisplaysNum()
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
robotgo.DisplayID = i robotgo.DisplayID = i
img1 := robotgo.CaptureImg() img1, _ := robotgo.CaptureImg()
path1 := "save_" + strconv.Itoa(i) path1 := "save_" + strconv.Itoa(i)
robotgo.Save(img1, path1+".png") robotgo.Save(img1, path1+".png")
robotgo.SaveJpeg(img1, path1+".jpeg", 50) 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) path2 := "test_" + strconv.Itoa(i)
robotgo.Save(img2, path2+".png") robotgo.Save(img2, path2+".png")
robotgo.SaveJpeg(img2, path2+".jpeg", 50) 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")
} }
} }

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package main package main

49
go.mod
View File

@ -1,33 +1,38 @@
module github.com/go-vgo/robotgo module github.com/go-vgo/robotgo
go 1.17 go 1.23.0
toolchain go1.23.6
require ( require (
github.com/lxn/win v0.0.0-20210218163916-a377121e959e github.com/otiai10/gosseract/v2 v2.4.1
github.com/otiai10/gosseract v2.2.1+incompatible
// github.com/robotn/gohook v0.31.3 // github.com/robotn/gohook v0.31.3
github.com/robotn/xgb v0.0.0-20190912153532-2cb92d044934 github.com/robotn/xgb v0.10.0
github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770 github.com/robotn/xgbutil v0.10.0
github.com/vcaesar/gops v0.30.1 github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35
github.com/vcaesar/imgo v0.30.2 github.com/vcaesar/gops v0.41.0
github.com/vcaesar/keycode v0.10.0 github.com/vcaesar/imgo v0.41.0
github.com/vcaesar/tt v0.20.0 github.com/vcaesar/keycode v0.10.1
github.com/vcaesar/tt v0.20.1
) )
require ( require (
github.com/gen2brain/shm v0.0.0-20221026125803-c33c9e32b1c8 // indirect github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/ebitengine/purego v0.8.3 // indirect
github.com/jezek/xgb v1.1.0 // indirect github.com/gen2brain/shm v0.1.1 // indirect
github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329 github.com/go-ole/go-ole v1.3.0 // indirect
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/otiai10/mint v1.3.0 // indirect github.com/jezek/xgb v1.1.1 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
github.com/shirou/gopsutil/v3 v3.23.1 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/shirou/gopsutil/v4 v4.25.4 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/tklauser/numcpus v0.10.0 // indirect
golang.org/x/image v0.5.0 // indirect github.com/vcaesar/screenshot v0.11.1
golang.org/x/sys v0.5.0 // indirect 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 // replace golang.org/x/sys => github.com/golang/sys v0.0.0-20190109145017-48ac38b7c8cb

146
go.sum
View File

@ -1,99 +1,71 @@
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ= 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/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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo= github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e h1:L+XrFvD0vBIBm+Wf9sFN6aU395t7JROoai0qXZraA4U=
github.com/gen2brain/shm v0.0.0-20221026125803-c33c9e32b1c8 h1:u4/UVF0sNxlqDwCptjIUTUkZW4UoZDrcHzvd2kNnF/k= github.com/dblohm7/wingoes v0.0.0-20240820181039-f2b84150679e/go.mod h1:SUxUaAK/0UG5lYyZR1L1nC4AaYYvSSYTWQSH3FPcxKU=
github.com/gen2brain/shm v0.0.0-20221026125803-c33c9e32b1c8/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo= github.com/ebitengine/purego v0.8.3 h1:K+0AjQp63JEZTEMZiwsI9g0+hAMNohwUOtY0RPGexmc=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 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.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240/go.mod h1:3P4UH/k22rXyHIJD2w4h2XMqPX4Of/eySEZq9L6wqc4= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/jezek/xgb v1.1.0 h1:wnpxJzP1+rkbGclEkmwpVFQWpuE2PUGNUzP8SbfFobk= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/jezek/xgb v1.1.0/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329 h1:qq2nCpSrXrmvDGRxW0ruW9BVEV1CN2a9YDOExdt+U0o= github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329/go.mod h1:2VPVQDR4wO7KXHwP+DAypEy67rXf+okUx2zjgpCxZw4= github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 h1:PpXWgLPs+Fqr325bN2FD2ISlRRztXibcX6e8f5FR5Dc=
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de h1:V53FWzU6KAZVi1tPp5UIsMoUWJ2/PNwYIDXnu7QuBCE= github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= github.com/otiai10/gosseract/v2 v2.4.1 h1:G8AyBpXEeSlcq8TI85LH/pM5SXk8Djy2GEXisgyblRw=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/gosseract/v2 v2.4.1/go.mod h1:1gNWP4Hgr2o7yqWfs6r5bZxAatjOIdqWxJLWsTsembk=
github.com/otiai10/gosseract v2.2.1+incompatible h1:Ry5ltVdpdp4LAa2bMjsSJH34XHVOV7XMi41HtzL8X2I= github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
github.com/otiai10/gosseract v2.2.1+incompatible/go.mod h1:XrzWItCzCpFRZ35n3YtVTgq5bLAhFIkascoRo8G32QE= github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 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/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-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
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/robotn/xgb v0.0.0-20190912153532-2cb92d044934/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ= 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/xgb v0.10.0 h1:O3kFbIwtwZ3pgLbp1h5slCQ4OpY8BdwugJLrUe6GPIM=
github.com/robotn/xgbutil v0.0.0-20190912154524-c861d6f87770/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU= github.com/robotn/xgb v0.10.0/go.mod h1:SxQhJskUJ4rleVU44YvnrdvxQr0tKy5SRSigBrCgyyQ=
github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4= github.com/robotn/xgbutil v0.10.0 h1:gvf7mGQqCWQ68aHRtCxgdewRk+/KAJui6l3MJQQRCKw=
github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA= github.com/robotn/xgbutil v0.10.0/go.mod h1:svkDXUDQjUiWzLrA0OZgHc4lbOts3C+uRfP6/yjwYnU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/shirou/gopsutil/v4 v4.25.4 h1:cdtFO363VEOOFrUCjZRh4XVJkb548lyF0q0uTeMqYPw=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/shirou/gopsutil/v4 v4.25.4/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35 h1:wAZbkTZkqDzWsqxPh2qkBd3KvFU7tcxV0BP0Rnhkxog=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/tailscale/win v0.0.0-20250213223159-5992cb43ca35/go.mod h1:aMd4yDHLjbOuYP6fMxj1d9ACDQlSWwYztcpybGHCQc8=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/vcaesar/gops v0.30.1 h1:MmTJhcCz0xTLSxOv4bmqbXQBPYVZpFLDzwN9Jdp/FR0= github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/vcaesar/gops v0.30.1/go.mod h1:F/8aazx2wGZ69ruziZcNGnlq/rehITYTqZ6ewVLDiyk= github.com/vcaesar/gops v0.41.0 h1:FG748Jyw3FOuZnbzSgB+CQSx2e5LbLCPWV2JU1brFdc=
github.com/vcaesar/imgo v0.30.2 h1:JUTKt9Og95RJ7ANjNtjW1NSO0jWMWxHCbryriNYooQE= github.com/vcaesar/gops v0.41.0/go.mod h1:/3048L7Rj7QjQKTSB+kKc7hDm63YhTWy5QJ10TCP37A=
github.com/vcaesar/imgo v0.30.2/go.mod h1:8mJleCPHDTqMmyRHFFim+S+B+1ighHqAETvuf7WCnZI= github.com/vcaesar/imgo v0.41.0 h1:kNLYGrThXhB9Dd6IwFmfPnxq9P6yat2g7dpPjr7OWO8=
github.com/vcaesar/keycode v0.10.0 h1:Qx5QE8ZXHyRyjoA2QOxBp25OKMKB+zxMVqm0FWGV0d4= github.com/vcaesar/imgo v0.41.0/go.mod h1:/LGOge8etlzaVu/7l+UfhJxR6QqaoX5yeuzGIMfWb4I=
github.com/vcaesar/keycode v0.10.0/go.mod h1:JNlY7xbKsh+LAGfY2j4M3znVrGEm5W1R8s/Uv6BJcfQ= github.com/vcaesar/keycode v0.10.1 h1:0DesGmMAPWpYTCYddOFiCMKCDKgNnwiQa2QXindVUHw=
github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA= github.com/vcaesar/keycode v0.10.1/go.mod h1:JNlY7xbKsh+LAGfY2j4M3znVrGEm5W1R8s/Uv6BJcfQ=
github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg= github.com/vcaesar/screenshot v0.11.1 h1:GgPuN89XC4Yh38dLx4quPlSo3YiWWhwIria/j3LtrqU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/vcaesar/screenshot v0.11.1/go.mod h1:gJNwHBiP1v1v7i8TQ4yV1XJtcyn2I/OJL7OziVQkwjs=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/vcaesar/tt v0.20.1/go.mod h1:cH2+AwGAJm19Wa6xvEa+0r+sXDJBT0QgNQey6mwqLeU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.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/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/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/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=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

8
img.go
View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo
@ -55,7 +55,7 @@ func SaveJpeg(img image.Image, path string, quality ...int) error {
// ToByteImg convert image.Image to []byte // ToByteImg convert image.Image to []byte
func ToByteImg(img image.Image, fm ...string) []byte { func ToByteImg(img image.Image, fm ...string) []byte {
return imgo.ToByteImg(img, fm...) return imgo.ToByte(img, fm...)
} }
// ToStringImg convert image.Image to string // ToStringImg convert image.Image to string

83
key.go
View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo
@ -416,7 +416,7 @@ func keyTaps(k string, keyArr []string, pid int) error {
return nil return nil
} }
func keyToggles(k string, keyArr []string, pid int, args ...interface{}) error { func getKeyDown(keyArr []string) (bool, []string) {
if len(keyArr) <= 0 { if len(keyArr) <= 0 {
keyArr = append(keyArr, "down") keyArr = append(keyArr, "down")
} }
@ -429,20 +429,26 @@ func keyToggles(k string, keyArr []string, pid int, args ...interface{}) error {
if keyArr[0] == "up" || keyArr[0] == "down" { if keyArr[0] == "up" || keyArr[0] == "down" {
keyArr = keyArr[1:] keyArr = keyArr[1:]
} }
flags := getFlagsFromValue(keyArr) return down, keyArr
}
func keyTogglesB(k string, down bool, keyArr []string, pid int) error {
flags := getFlagsFromValue(keyArr)
key, err := checkKeyCodes(k) key, err := checkKeyCodes(k)
if err != nil { if err != nil {
return err return err
} }
C.toggleKeyCode(key, C.bool(down), flags, C.uintptr(pid)) C.toggleKeyCode(key, C.bool(down), flags, C.uintptr(pid))
if len(args) > 0 {
MilliSleep(KeySleep) MilliSleep(KeySleep)
}
return nil return nil
} }
func keyToggles(k string, keyArr []string, pid int) error {
down, keyArr1 := getKeyDown(keyArr)
return keyTogglesB(k, down, keyArr1, pid)
}
/* /*
__ ___ ___________ ____ .______ ______ ___ .______ _______ __ ___ ___________ ____ .______ ______ ___ .______ _______
| |/ / | ____\ \ / / | _ \ / __ \ / \ | _ \ | \ | |/ / | ____\ \ / / | _ \ / __ \ / \ | _ \ | \
@ -480,6 +486,22 @@ func toErr(str *C.char) error {
return errors.New(gstr) return errors.New(gstr)
} }
func appendShift(key string, len1 int, args ...interface{}) (string, []interface{}) {
if len(key) > 0 && unicode.IsUpper([]rune(key)[0]) {
args = append(args, "shift")
}
key = strings.ToLower(key)
if _, ok := Special[key]; ok {
key = Special[key]
if len(args) <= len1 {
args = append(args, "shift")
}
}
return key, args
}
// KeyTap taps the keyboard code; // KeyTap taps the keyboard code;
// //
// See keys supported: // See keys supported:
@ -498,18 +520,7 @@ func toErr(str *C.char) error {
// robotgo.KeyTap("k", pid int) // robotgo.KeyTap("k", pid int)
func KeyTap(key string, args ...interface{}) error { func KeyTap(key string, args ...interface{}) error {
var keyArr []string var keyArr []string
key, args = appendShift(key, 0, args...)
if len(key) > 0 && unicode.IsUpper([]rune(key)[0]) {
args = append(args, "shift")
}
key = strings.ToLower(key)
if _, ok := Special[key]; ok {
key = Special[key]
if len(args) <= 0 {
args = append(args, "shift")
}
}
pid := 0 pid := 0
if len(args) > 0 { if len(args) > 0 {
@ -528,6 +539,16 @@ func KeyTap(key string, args ...interface{}) error {
return keyTaps(key, keyArr, pid) return keyTaps(key, keyArr, pid)
} }
func getToggleArgs(args ...interface{}) (pid int, keyArr []string) {
if len(args) > 0 && reflect.TypeOf(args[0]) == reflect.TypeOf(pid) {
pid = args[0].(int)
keyArr = ToStrings(args[1:])
} else {
keyArr = ToStrings(args)
}
return
}
// KeyToggle toggles the keyboard, if there not have args default is "down" // KeyToggle toggles the keyboard, if there not have args default is "down"
// //
// See keys: // See keys:
@ -542,28 +563,8 @@ func KeyTap(key string, args ...interface{}) error {
// robotgo.KeyToggle("a", "up", "alt", "cmd") // robotgo.KeyToggle("a", "up", "alt", "cmd")
// robotgo.KeyToggle("k", pid int) // robotgo.KeyToggle("k", pid int)
func KeyToggle(key string, args ...interface{}) error { func KeyToggle(key string, args ...interface{}) error {
key, args = appendShift(key, 1, args...)
if len(key) > 0 && unicode.IsUpper([]rune(key)[0]) { pid, keyArr := getToggleArgs(args...)
args = append(args, "shift")
}
key = strings.ToLower(key)
if _, ok := Special[key]; ok {
key = Special[key]
if len(args) <= 1 {
args = append(args, "shift")
}
}
pid := 0
var keyArr []string
if len(args) > 0 && reflect.TypeOf(args[0]) == reflect.TypeOf(pid) {
pid = args[0].(int)
keyArr = ToStrings(args[1:])
} else {
keyArr = ToStrings(args)
}
return keyToggles(key, keyArr, pid) return keyToggles(key, keyArr, pid)
} }

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package key package key

View File

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

View File

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

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#include "../base/deadbeef_rand_c.h" #include "../base/deadbeef_rand_c.h"
@ -58,7 +58,7 @@
if (pid != 0) { if (pid != 0) {
CGEventPostToPid(pid, event); CGEventPostToPid(pid, event);
} else { } else {
CGEventPost(kCGSessionEventTap, event); CGEventPost(kCGHIDEventTap, event);
} }
CFRelease(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); NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE);
assert(KERN_SUCCESS == kr); assert(KERN_SUCCESS == kr);
} else { } else {
CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)code, down); CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef keyEvent = CGEventCreateKeyboardEvent(source, (CGKeyCode)code, down);
assert(keyEvent != NULL); assert(keyEvent != NULL);
CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp); CGEventSetType(keyEvent, down ? kCGEventKeyDown : kCGEventKeyUp);
@ -188,6 +189,7 @@ void toggleKeyCode(MMKeyCode code, const bool down, MMKeyFlags flags, uintptr pi
} }
SendTo(pid, keyEvent); SendTo(pid, keyEvent);
CFRelease(source);
} }
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
const DWORD dwFlags = down ? 0 : KEYEVENTF_KEYUP; 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. convert characters to a keycode, but does not support adding modifier flags.
It is only used in typeString(). It is only used in typeString().
-- if you need modifier keys, use the above functions instead. */ -- 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) { if (keyEvent == NULL) {
fputs("Could not create keyboard event.\n", stderr); fputs("Could not create keyboard event.\n", stderr);
return; return;
@ -282,6 +285,7 @@ void toggleKey(char c, const bool down, MMKeyFlags flags, uintptr pid) {
CGEventKeyboardSetUnicodeString(keyEvent, 1, &ch); CGEventKeyboardSetUnicodeString(keyEvent, 1, &ch);
SendTo(pid, keyEvent); SendTo(pid, keyEvent);
CFRelease(source);
} }
#else #else
#define toggleUniKey(c, down) toggleKey(c, down, MOD_NONE, 0) #define toggleUniKey(c, down) toggleKey(c, down, MOD_NONE, 0)

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package mouse package mouse

View File

@ -83,51 +83,37 @@
/* Move the mouse to a specific point. */ /* Move the mouse to a specific point. */
void moveMouse(MMPointInt32 point){ void moveMouse(MMPointInt32 point){
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
CGEventRef move = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef move = CGEventCreateMouseEvent(source, kCGEventMouseMoved,
CGPointFromMMPointInt32(point), kCGMouseButtonLeft); CGPointFromMMPointInt32(point), kCGMouseButtonLeft);
calculateDeltas(&move, point); calculateDeltas(&move, point);
CGEventPost(kCGSessionEventTap, move); CGEventPost(kCGHIDEventTap, move);
CFRelease(move); CFRelease(move);
CFRelease(source);
#elif defined(USE_X11) #elif defined(USE_X11)
Display *display = XGetMainDisplay(); Display *display = XGetMainDisplay();
XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, point.x, point.y); XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, point.x, point.y);
XSync(display, false); XSync(display, false);
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
// Mouse motion is now done using SendInput with MOUSEINPUT. SetCursorPos(point.x, point.y);
// 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));
#endif #endif
} }
void dragMouse(MMPointInt32 point, const MMMouseButton button){ void dragMouse(MMPointInt32 point, const MMMouseButton button){
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
const CGEventType dragType = MMMouseDragToCGEventType(button); const CGEventType dragType = MMMouseDragToCGEventType(button);
CGEventRef drag = CGEventCreateMouseEvent(NULL, dragType, CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef drag = CGEventCreateMouseEvent(source, dragType,
CGPointFromMMPointInt32(point), (CGMouseButton)button); CGPointFromMMPointInt32(point), (CGMouseButton)button);
calculateDeltas(&drag, point); calculateDeltas(&drag, point);
CGEventPost(kCGSessionEventTap, drag); CGEventPost(kCGHIDEventTap, drag);
CFRelease(drag); CFRelease(drag);
CFRelease(source);
#else #else
moveMouse(point); moveMouse(point);
#endif #endif
@ -163,10 +149,12 @@ void toggleMouse(bool down, MMMouseButton button) {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
const CGPoint currentPos = CGPointFromMMPointInt32(location()); const CGPoint currentPos = CGPointFromMMPointInt32(location());
const CGEventType mouseType = MMMouseToCGEventType(down, button); 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(event);
CFRelease(source);
#elif defined(USE_X11) #elif defined(USE_X11)
Display *display = XGetMainDisplay(); Display *display = XGetMainDisplay();
XTestFakeButtonEvent(display, button, down ? True : False, CurrentTime); XTestFakeButtonEvent(display, button, down ? True : False, CurrentTime);
@ -200,7 +188,8 @@ void doubleClick(MMMouseButton button){
const CGEventType mouseTypeDown = MMMouseToCGEventType(true, button); const CGEventType mouseTypeDown = MMMouseToCGEventType(true, button);
const CGEventType mouseTypeUP = MMMouseToCGEventType(false, 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. */ /* Set event to double click. */
CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2); CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2);
@ -210,6 +199,7 @@ void doubleClick(MMMouseButton button){
CGEventPost(kCGHIDEventTap, event); CGEventPost(kCGHIDEventTap, event);
CFRelease(event); CFRelease(event);
CFRelease(source);
#else #else
/* Double click for everything else. */ /* Double click for everything else. */
clickMouse(button); clickMouse(button);
@ -226,14 +216,13 @@ void scrollMouseXY(int x, int y) {
INPUT mouseScrollInputV; INPUT mouseScrollInputV;
#endif #endif
/* Direction should only be considered based on the scrollDirection. This Should not interfere. */ #if defined(IS_MACOSX)
/* Set up the OS specific solution */ CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
#if defined(__APPLE__) CGEventRef event = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitPixel, 2, y, x);
CGEventRef event;
event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 2, y, x);
CGEventPost(kCGHIDEventTap, event); CGEventPost(kCGHIDEventTap, event);
CFRelease(event); CFRelease(event);
CFRelease(source);
#elif defined(USE_X11) #elif defined(USE_X11)
int ydir = 4; /* Button 4 is up, 5 is down. */ int ydir = 4; /* Button 4 is up, 5 is down. */
int xdir = 6; int xdir = 6;

6
ps.go
View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo_test package robotgo_test

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
/* /*
@ -31,8 +31,12 @@ package robotgo
/* /*
#cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations #cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations
#cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit #cgo darwin LDFLAGS: -framework Cocoa -framework CoreFoundation -framework IOKit
#cgo darwin LDFLAGS: -framework Carbon -framework CoreFoundation #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 CFLAGS: -I/usr/src
#cgo linux LDFLAGS: -L/usr/src -lm -lX11 -lXtst #cgo linux LDFLAGS: -L/usr/src -lm -lX11 -lXtst
@ -46,6 +50,7 @@ package robotgo
import "C" import "C"
import ( import (
"errors"
"image" "image"
"runtime" "runtime"
"time" "time"
@ -68,7 +73,7 @@ var (
// MouseSleep set the mouse default millisecond sleep time // MouseSleep set the mouse default millisecond sleep time
MouseSleep = 0 MouseSleep = 0
// KeySleep set the key default millisecond sleep time // KeySleep set the key default millisecond sleep time
KeySleep = 0 KeySleep = 10
// DisplayID set the screen display id // DisplayID set the screen display id
DisplayID = -1 DisplayID = -1
@ -86,6 +91,8 @@ type (
CHex C.MMRGBHex CHex C.MMRGBHex
// CBitmap define CBitmap as C.MMBitmapRef type // CBitmap define CBitmap as C.MMBitmapRef type
CBitmap C.MMBitmapRef CBitmap C.MMBitmapRef
// Handle define window Handle as C.MData type
Handle C.MData
) )
// Bitmap define the go Bitmap struct // Bitmap define the go Bitmap struct
@ -359,12 +366,15 @@ func CaptureGo(args ...int) Bitmap {
return ToBitmap(bit) return ToBitmap(bit)
} }
// CaptureImg capture the screen and return image.Image // CaptureImg capture the screen and return image.Image, error
func CaptureImg(args ...int) image.Image { func CaptureImg(args ...int) (image.Image, error) {
bit := CaptureScreen(args...) bit := CaptureScreen(args...)
if bit == nil {
return nil, errors.New("Capture image not found.")
}
defer FreeBitmap(bit) defer FreeBitmap(bit)
return ToImage(bit) return ToImage(bit), nil
} }
// FreeBitmap free and dealloc the C bitmap // FreeBitmap free and dealloc the C bitmap
@ -453,6 +463,11 @@ func GetXDisplayName() string {
return gname return gname
} }
// CloseMainDisplay close the main X11 display
func CloseMainDisplay() {
C.close_main_display()
}
// Deprecated: use the ScaledF(), // Deprecated: use the ScaledF(),
// //
// ScaleX get the primary display horizontal DPI scale factor, drop // 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 // MoveScale calculate the os scale factor x, y
func MoveScale(x, y int, displayId ...int) (int, int) { func MoveScale(x, y int, displayId ...int) (int, int) {
if Scale && runtime.GOOS == "windows" { if Scale || runtime.GOOS == "windows" {
f := ScaleF() f := ScaleF()
x, y = Scaled1(x, f), Scaled1(y, f) x, y = Scaled1(x, f), Scaled1(y, f)
} }
@ -540,8 +555,6 @@ func Drag(x, y int, args ...string) {
// //
// robotgo.DragSmooth(10, 10) // robotgo.DragSmooth(10, 10)
func DragSmooth(x, y int, args ...interface{}) { func DragSmooth(x, y int, args ...interface{}) {
x, y = MoveScale(x, y)
Toggle("left") Toggle("left")
MilliSleep(50) MilliSleep(50)
MoveSmooth(x, y, args...) MoveSmooth(x, y, args...)
@ -617,7 +630,7 @@ func Location() (int, int) {
x := int(pos.x) x := int(pos.x)
y := int(pos.y) y := int(pos.y)
if runtime.GOOS == "windows" { if Scale || runtime.GOOS == "windows" {
f := ScaleF() f := ScaleF()
x, y = Scaled0(x, f), Scaled0(y, f) x, y = Scaled0(x, f), Scaled0(y, f)
} }
@ -868,12 +881,22 @@ func IsValid() bool {
} }
// SetActive set the window active // 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) C.set_active(win)
} }
// GetActive get the active window // 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() mdata := C.get_active()
// fmt.Println("active----", mdata) // fmt.Println("active----", mdata)
return 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)) 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 // 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 var isPid int
if len(args) > 0 || NotPid { if len(args) > 0 || NotPid {
isPid = 1 isPid = 1

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build darwin //go:build darwin

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build !windows //go:build !windows

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build darwin || windows //go:build darwin || windows

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build ocr //go:build ocr
@ -14,7 +14,7 @@
package robotgo package robotgo
import ( import (
"github.com/otiai10/gosseract" "github.com/otiai10/gosseract/v2"
) )
// GetText get the image text by tesseract ocr // GetText get the image text by tesseract ocr

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build darwin || windows //go:build darwin || windows
@ -179,7 +179,8 @@ func TestImage(t *testing.T) {
err := SavePng(img, "robot_test.png") err := SavePng(img, "robot_test.png")
tt.Nil(t, err) 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) e := Save(img1, "robot_img.jpeg", 50)
tt.Nil(t, e) tt.Nil(t, e)

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build windows //go:build windows
@ -17,7 +17,8 @@ import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/lxn/win" // "github.com/lxn/win"
"github.com/tailscale/win"
) )
// FindWindow find window hwnd by name // FindWindow find window hwnd by name
@ -57,7 +58,7 @@ func SetForeg(hwnd win.HWND) bool {
return win.SetForegroundWindow(hwnd) return win.SetForegroundWindow(hwnd)
} }
// GetMian get the main display hwnd // GetMain get the main display hwnd
func GetMain() win.HWND { func GetMain() win.HWND {
return win.GetActiveWindow() return win.GetActiveWindow()
} }

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
//go:build !darwin && !windows //go:build !darwin && !windows
@ -190,7 +190,7 @@ func DisplaysNum() int {
return int(reply.Number) return int(reply.Number)
} }
// GetMianId get the main display id // GetMainId get the main display id
func GetMainId() int { func GetMainId() int {
conn, err := xgb.NewConn() conn, err := xgb.NewConn()
if err != nil { if err != nil {

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
package robotgo package robotgo
@ -13,16 +13,17 @@ package robotgo
import ( import (
"image" "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) { func GetDisplayBounds(i int) (x, y, w, h int) {
bs := screenshot.GetDisplayBounds(i) bs := screenshot.GetDisplayBounds(i)
return bs.Min.X, bs.Min.Y, bs.Dx(), bs.Dy() 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 { func GetDisplayRect(i int) Rect {
x, y, w, h := GetDisplayBounds(i) x, y, w, h := GetDisplayBounds(i)
return Rect{ return Rect{
@ -30,7 +31,7 @@ func GetDisplayRect(i int) Rect {
Size{W: w, H: h}} Size{W: w, H: h}}
} }
// Capture capture the screenshot // Capture capture the screenshot, use the CaptureImg default
func Capture(args ...int) (*image.RGBA, error) { func Capture(args ...int) (*image.RGBA, error) {
displayId := 0 displayId := 0
if DisplayID != -1 { if DisplayID != -1 {
@ -50,3 +51,13 @@ func Capture(args ...int) (*image.RGBA, error) {
return screenshot.Capture(x, y, w, h) 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

@ -3,16 +3,15 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#include "../base/types.h" #include "../base/types.h"
#include "../base/pubs.h" #include "../base/pubs.h"
#include "../base/rgb.h" #include "../base/rgb.h"
#include "screengrab_c.h" #include "screengrab_c.h"
#include "screen_c.h"
#include <stdio.h> #include <stdio.h>
void padHex(MMRGBHex color, char* hex) { void padHex(MMRGBHex color, char* hex) {
@ -79,6 +78,14 @@ char* get_XDisplay_name() {
#endif #endif
} }
void close_main_display() {
#if defined(USE_X11)
XCloseMainDisplay();
#else
//
#endif
}
uint32_t get_num_displays() { uint32_t get_num_displays() {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
uint32_t count = 0; uint32_t count = 0;

View File

@ -4,9 +4,70 @@
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#elif defined(USE_X11) #elif defined(USE_X11)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xresource.h>
// #include "../base/xdisplay_c.h" // #include "../base/xdisplay_c.h"
#endif #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) { MMSizeInt32 getMainDisplaySize(void) {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
CGDirectDisplayID displayID = CGMainDisplayID(); CGDirectDisplayID displayID = CGMainDisplayID();

View File

@ -5,6 +5,7 @@
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#include <ScreenCaptureKit/ScreenCaptureKit.h>
#elif defined(USE_X11) #elif defined(USE_X11)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
@ -12,6 +13,56 @@
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
#include <string.h> #include <string.h>
#endif #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) { MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id, int8_t isPid) {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
@ -25,7 +76,14 @@ MMBitmapRef copyMMBitmapFromDisplayInRect(MMRectInt32 rect, int32_t display_id,
} }
MMPointInt32 o = rect.origin; MMSizeInt32 s = rect.size; MMPointInt32 o = rect.origin; MMSizeInt32 s = rect.size;
#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)); CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(o.x, o.y, s.w, s.h));
#endif
if (!image) { return NULL; } if (!image) { return NULL; }
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image)); CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image));

2
wayland_n.go Normal file
View File

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

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#include "alert_c.h" #include "alert_c.h"
@ -55,11 +55,11 @@ uintptr get_handle(){
uintptr b_get_handle() { uintptr b_get_handle() {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
return (uintptr)mData.CgID; return (uintptr)pub_mData.CgID;
#elif defined(USE_X11) #elif defined(USE_X11)
return (uintptr)mData.XWin; return (uintptr)pub_mData.XWin;
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
return (uintptr)mData.HWnd; return (uintptr)pub_mData.HWnd;
#endif #endif
} }

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// #include "../base/os.h" // #include "../base/os.h"
@ -28,7 +28,7 @@ struct _MData{
}; };
typedef struct _MData MData; typedef struct _MData MData;
MData mData; MData pub_mData;
struct _Bounds { struct _Bounds {
int32_t X; // Top left X coordinate int32_t X; // Top left X coordinate

View File

@ -3,75 +3,16 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#if defined(USE_X11) // #if defined(USE_X11)
#include <X11/Xresource.h> // #include <X11/Xresource.h>
#endif // #endif
Bounds get_client(uintptr pid, int8_t isPid); 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){ Bounds get_bounds(uintptr pid, int8_t isPid){
// Check if the window is valid // Check if the window is valid
@ -83,33 +24,45 @@ Bounds get_bounds(uintptr pid, int8_t isPid){
AXValueRef axp = NULL; AXValueRef axp = NULL;
AXValueRef axs = NULL; AXValueRef axs = NULL;
AXUIElementRef AxID = AXUIElementCreateApplication(pid); AXUIElementRef AxID = AXUIElementCreateApplication(pid);
AXUIElementRef AxWin = NULL;
// Get the window from the application
if (AXUIElementCopyAttributeValue(AxID, kAXFocusedWindowAttribute, (CFTypeRef *)&AxWin)
!= kAXErrorSuccess || AxWin == NULL) {
// If no focused window, try to get the main window
if (AXUIElementCopyAttributeValue(AxID, kAXMainWindowAttribute, (CFTypeRef *)&AxWin)
!= kAXErrorSuccess || AxWin == NULL) {
goto exit;
}
}
// Determine the current point of the window // Determine the current point of the window
if (AXUIElementCopyAttributeValue(AxID, kAXPositionAttribute, (CFTypeRef*) &axp) if (AXUIElementCopyAttributeValue(AxWin, kAXPositionAttribute, (CFTypeRef*) &axp)
!= kAXErrorSuccess || axp == NULL){ != kAXErrorSuccess || axp == NULL) {
goto exit; goto exit;
} }
// Determine the current size of the window // Determine the current size of the window
if (AXUIElementCopyAttributeValue(AxID, kAXSizeAttribute, (CFTypeRef*) &axs) if (AXUIElementCopyAttributeValue(AxWin, kAXSizeAttribute, (CFTypeRef*) &axs)
!= kAXErrorSuccess || axs == NULL){ != kAXErrorSuccess || axs == NULL) {
goto exit; goto exit;
} }
CGPoint p; CGSize s; CGPoint p; CGSize s;
// Attempt to convert both values into atomic types // Attempt to convert both values into atomic types
if (AXValueGetValue(axp, kAXValueCGPointType, &p) && if (AXValueGetValue(axp, kAXValueCGPointType, &p) &&
AXValueGetValue(axs, kAXValueCGSizeType, &s)){ AXValueGetValue(axs, kAXValueCGSizeType, &s)) {
bounds.X = p.x; bounds.X = p.x;
bounds.Y = p.y; bounds.Y = p.y;
bounds.W = s.width; bounds.W = s.width;
bounds.H = s.height; bounds.H = s.height;
} }
// return bounds;
exit: exit:
if (axp != NULL) { CFRelease(axp); } if (axp != NULL) { CFRelease(axp); }
if (axs != NULL) { CFRelease(axs); } if (axs != NULL) { CFRelease(axs); }
if (AxWin != NULL) { CFRelease(AxWin); }
if (AxID != NULL) { CFRelease(AxID); }
return bounds; return bounds;
#elif defined(USE_X11) #elif defined(USE_X11)

View File

@ -3,9 +3,9 @@
// https://github.com/go-vgo/robotgo/blob/master/LICENSE // https://github.com/go-vgo/robotgo/blob/master/LICENSE
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // http://www.apache.org/licenses/LICENSE-2.0>
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your //
// option. This file may not be copied, modified, or distributed // This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#include "pub.h" #include "pub.h"
@ -15,7 +15,7 @@ bool is_valid();
bool IsAxEnabled(bool options); bool IsAxEnabled(bool options);
MData get_active(void); MData get_active(void);
void initWindow(); void initWindow(uintptr handle);
char* get_title_by_hand(MData m_data); char* get_title_by_hand(MData m_data);
void close_window_by_Id(MData m_data); void close_window_by_Id(MData m_data);
@ -24,8 +24,8 @@ uintptr initHandle = 0;
void initWindow(uintptr handle){ void initWindow(uintptr handle){
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
mData.CgID = 0; pub_mData.CgID = 0;
mData.AxID = 0; pub_mData.AxID = 0;
#elif defined(USE_X11) #elif defined(USE_X11)
Display *rDisplay = XOpenDisplay(NULL); Display *rDisplay = XOpenDisplay(NULL);
// If atoms loaded // If atoms loaded
@ -34,10 +34,10 @@ void initWindow(uintptr handle){
if (rDisplay != NULL) {LoadAtoms();} if (rDisplay != NULL) {LoadAtoms();}
} }
mData.XWin = 0; pub_mData.XWin = 0;
XCloseDisplay(rDisplay); XCloseDisplay(rDisplay);
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
mData.HWnd = 0; pub_mData.HWnd = 0;
#endif #endif
setHandle(handle); 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){ void set_handle_pid_mData(uintptr pid, int8_t isPid){
MData win = set_handle_pid(pid, isPid); MData win = set_handle_pid(pid, isPid);
mData = win; pub_mData = win;
} }
bool is_valid() { bool is_valid() {
initWindow(initHandle); initWindow(initHandle);
if (!IsAxEnabled(true)) { if (!IsAxEnabled(true)) {
printf("%s\n", "Window: Accessibility API is disabled!\n" printf("%s\n", "Window: Accessibility API is disabled! "
"Failed to enable access for assistive devices."); "Failed to enable access for assistive devices. \n");
} }
MData actdata = get_active(); MData actdata = get_active();
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
mData.CgID = actdata.CgID; pub_mData.CgID = actdata.CgID;
mData.AxID = actdata.AxID; pub_mData.AxID = actdata.AxID;
if (mData.CgID == 0 || mData.AxID == 0) { return false; } if (pub_mData.CgID == 0 || pub_mData.AxID == 0) { return false; }
CFTypeRef r = NULL; CFTypeRef r = NULL;
// Attempt to get the window role // 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); CFRelease(r);
return true; return true;
} }
return false; return false;
#elif defined(USE_X11) #elif defined(USE_X11)
mData.XWin = actdata.XWin; pub_mData.XWin = actdata.XWin;
if (mData.XWin == 0) { return false; } if (pub_mData.XWin == 0) { return false; }
Display *rDisplay = XOpenDisplay(NULL); Display *rDisplay = XOpenDisplay(NULL);
// Check for a valid X-Window display // Check for a valid X-Window display
@ -103,7 +103,7 @@ bool is_valid() {
XDismissErrors(); XDismissErrors();
// Get the window PID property // Get the window PID property
void* result = GetWindowProperty(mData, WM_PID,NULL); void* result = GetWindowProperty(pub_mData, WM_PID,NULL);
if (result == NULL) { if (result == NULL) {
XCloseDisplay(rDisplay); XCloseDisplay(rDisplay);
return false; return false;
@ -115,12 +115,12 @@ bool is_valid() {
return true; return true;
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
mData.HWnd = actdata.HWnd; pub_mData.HWnd = actdata.HWnd;
if (mData.HWnd == 0) { if (pub_mData.HWnd == 0) {
return false; return false;
} }
return IsWindow(mData.HWnd) != 0; return IsWindow(pub_mData.HWnd) != 0;
#endif #endif
} }
@ -175,13 +175,13 @@ bool IsAxEnabled(bool options){
bool setHandle(uintptr handle){ bool setHandle(uintptr handle){
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
// Release the AX element // Release the AX element
if (mData.AxID != NULL) { if (pub_mData.AxID != NULL) {
CFRelease(mData.AxID); CFRelease(pub_mData.AxID);
} }
// Reset both values // Reset both values
mData.CgID = 0; pub_mData.CgID = 0;
mData.AxID = 0; pub_mData.AxID = 0;
if (handle == 0) { if (handle == 0) {
// return 0; // return 0;
@ -192,8 +192,8 @@ bool setHandle(uintptr handle){
CGWindowID cgID = (CGWindowID)handle; CGWindowID cgID = (CGWindowID)handle;
AXUIElementRef axID = GetUIElement(cgID); AXUIElementRef axID = GetUIElement(cgID);
if (axID != NULL){ if (axID != NULL){
mData.CgID = cgID; pub_mData.CgID = cgID;
mData.AxID = axID; pub_mData.AxID = axID;
// return 0; // return 0;
return true; return true;
} }
@ -201,7 +201,7 @@ bool setHandle(uintptr handle){
// return 1; // return 1;
return false; return false;
#elif defined(USE_X11) #elif defined(USE_X11)
mData.XWin = (Window)handle; pub_mData.XWin = (Window)handle;
if (handle == 0) { if (handle == 0) {
return true; return true;
} }
@ -210,10 +210,10 @@ bool setHandle(uintptr handle){
return true; return true;
} }
mData.XWin = 0; pub_mData.XWin = 0;
return false; return false;
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
mData.HWnd = (HWND)handle; pub_mData.HWnd = (HWND)handle;
if (handle == 0) { if (handle == 0) {
return true; return true;
} }
@ -222,7 +222,7 @@ bool setHandle(uintptr handle){
return true; return true;
} }
mData.HWnd = 0; pub_mData.HWnd = 0;
return false; return false;
#endif #endif
} }
@ -237,7 +237,7 @@ bool IsTopMost(void){
// XDismissErrors (); // XDismissErrors ();
// return GetState (mData.XWin, STATE_TOPMOST); // return GetState (mData.XWin, STATE_TOPMOST);
#elif defined(IS_WINDOWS) #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 #endif
} }
@ -247,7 +247,7 @@ bool IsMinimized(void){
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
CFBooleanRef data = NULL; CFBooleanRef data = NULL;
// Determine whether the window is minimized // Determine whether the window is minimized
if (AXUIElementCopyAttributeValue(mData.AxID, kAXMinimizedAttribute, if (AXUIElementCopyAttributeValue(pub_mData.AxID, kAXMinimizedAttribute,
(CFTypeRef*) &data) == kAXErrorSuccess && data != NULL) { (CFTypeRef*) &data) == kAXErrorSuccess && data != NULL) {
// Convert resulting data into a bool // Convert resulting data into a bool
bool result = CFBooleanGetValue(data); bool result = CFBooleanGetValue(data);
@ -261,7 +261,7 @@ bool IsMinimized(void){
// XDismissErrors(); // XDismissErrors();
// return GetState(mData.XWin, STATE_MINIMIZE); // return GetState(mData.XWin, STATE_MINIMIZE);
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
return (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MINIMIZE) != 0; return (GetWindowLongPtr(pub_mData.HWnd, GWL_STYLE) & WS_MINIMIZE) != 0;
#endif #endif
} }
@ -276,7 +276,7 @@ bool IsMaximized(void){
// XDismissErrors(); // XDismissErrors();
// return GetState(mData.XWin, STATE_MAXIMIZE); // return GetState(mData.XWin, STATE_MAXIMIZE);
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
return (GetWindowLongPtr(mData.HWnd, GWL_STYLE) & WS_MAXIMIZE) != 0; return (GetWindowLongPtr(pub_mData.HWnd, GWL_STYLE) & WS_MAXIMIZE) != 0;
#endif #endif
} }
@ -367,11 +367,11 @@ MData get_active(void) {
if (focused == NULL) { return result; } // Verify if (focused == NULL) { return result; } // Verify
AXUIElementRef element; AXUIElementRef element;
CGWindowID win = 0;
// Retrieve the currently focused window // Retrieve the currently focused window
if (AXUIElementCopyAttributeValue(focused, kAXFocusedWindowAttribute, (CFTypeRef*) &element) if (AXUIElementCopyAttributeValue(focused, kAXFocusedWindowAttribute, (CFTypeRef*) &element)
== kAXErrorSuccess && element) { == kAXErrorSuccess && element) {
CGWindowID win = 0;
// Use undocumented API to get WID // Use undocumented API to get WID
if (_AXUIElementGetWindow(element, &win) == kAXErrorSuccess && win) { if (_AXUIElementGetWindow(element, &win) == kAXErrorSuccess && win) {
// Manually set internals // Manually set internals
@ -380,6 +380,9 @@ MData get_active(void) {
} else { } else {
CFRelease(element); CFRelease(element);
} }
} else {
result.CgID = win;
result.AxID = element;
} }
CFRelease(focused); CFRelease(focused);
@ -450,9 +453,9 @@ void SetTopMost(bool state){
#elif defined(USE_X11) #elif defined(USE_X11)
// Ignore X errors // Ignore X errors
// XDismissErrors(); // XDismissErrors();
// SetState(mData.XWin, STATE_TOPMOST, state); // SetState(pub_mData.XWin, STATE_TOPMOST, state);
#elif defined(IS_WINDOWS) #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); 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
#endif #endif
} }
@ -461,7 +464,7 @@ void close_main_window () {
// Check if the window is valid // Check if the window is valid
if (!is_valid()) { return; } 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){ void close_window_by_PId(uintptr pid, int8_t isPid){
@ -499,7 +502,7 @@ char* get_main_title(){
// Check if the window is valid // Check if the window is valid
if (!is_valid()) { return "is_valid failed."; } 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){ char* get_title_by_pid(uintptr pid, int8_t isPid){
@ -588,7 +591,7 @@ int32_t get_PID(void) {
#if defined(IS_MACOSX) #if defined(IS_MACOSX)
pid_t pid = 0; pid_t pid = 0;
// Attempt to retrieve the window pid // Attempt to retrieve the window pid
if (AXUIElementGetPid(mData.AxID, &pid)== kAXErrorSuccess) { if (AXUIElementGetPid(pub_mData.AxID, &pid)== kAXErrorSuccess) {
return pid; return pid;
} }
return 0; return 0;
@ -597,7 +600,7 @@ int32_t get_PID(void) {
XDismissErrors(); XDismissErrors();
// Get the window PID // 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 // Check result and convert it
if (result == NULL) { return 0; } if (result == NULL) { return 0; }
@ -606,7 +609,7 @@ int32_t get_PID(void) {
return pid; return pid;
#elif defined(IS_WINDOWS) #elif defined(IS_WINDOWS)
DWORD id = 0; DWORD id = 0;
GetWindowThreadProcessId(mData.HWnd, &id); GetWindowThreadProcessId(pub_mData.HWnd, &id);
return id; return id;
#endif #endif
} }

2
windows_n.go Normal file
View File

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