mirror of
https://github.com/go-vgo/robotgo
synced 2026-05-24 10:19:01 +00:00
Add: add toogle error check and MultiClikck, optimize the code and api
This commit is contained in:
parent
dafd29e5ea
commit
4c439be11f
2 changed files with 63 additions and 67 deletions
|
|
@ -54,7 +54,6 @@
|
|||
}
|
||||
|
||||
#elif defined(IS_WINDOWS)
|
||||
|
||||
DWORD MMMouseUpToMEventF(MMMouseButton button) {
|
||||
if (button == LEFT_BUTTON) { return MOUSEEVENTF_LEFTUP; }
|
||||
if (button == RIGHT_BUTTON) { return MOUSEEVENTF_RIGHTUP; }
|
||||
|
|
@ -99,7 +98,6 @@ void moveMouse(MMPointInt32 point){
|
|||
CGPointFromMMPointInt32(point), kCGMouseButtonLeft);
|
||||
|
||||
calculateDeltas(&move, point);
|
||||
|
||||
CGEventPost(kCGHIDEventTap, move);
|
||||
CFRelease(move);
|
||||
CFRelease(source);
|
||||
|
|
@ -156,7 +154,7 @@ MMPointInt32 location() {
|
|||
}
|
||||
|
||||
/* Press down a button, or release it. */
|
||||
int toggleMouseErr(bool down, MMMouseButton button) {
|
||||
int toggleMouse(bool down, MMMouseButton button) {
|
||||
#if defined(IS_MACOSX)
|
||||
const CGPoint currentPos = CGPointFromMMPointInt32(location());
|
||||
const CGEventType mouseType = MMMouseToCGEventType(down, button);
|
||||
|
|
@ -167,20 +165,17 @@ int toggleMouseErr(bool down, MMMouseButton button) {
|
|||
CFRelease(source);
|
||||
return (int)kCGErrorCannotComplete;
|
||||
}
|
||||
|
||||
|
||||
CGEventPost(kCGHIDEventTap, event);
|
||||
CFRelease(event);
|
||||
CFRelease(source);
|
||||
|
||||
return 0;
|
||||
#elif defined(USE_X11)
|
||||
Display *display = XGetMainDisplay();
|
||||
Status status = XTestFakeButtonEvent(display, button, down ? True : False, CurrentTime);
|
||||
XSync(display, false);
|
||||
|
||||
return status ? 0 : 1;
|
||||
#elif defined(IS_WINDOWS)
|
||||
// mouse_event(MMMouseToMEventF(down, button), 0, 0, 0, 0);
|
||||
INPUT mouseInput;
|
||||
|
||||
mouseInput.type = INPUT_MOUSE;
|
||||
|
|
@ -195,26 +190,18 @@ int toggleMouseErr(bool down, MMMouseButton button) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void toggleMouse(bool down, MMMouseButton button) {
|
||||
toggleMouseErr(down, button);
|
||||
}
|
||||
|
||||
int clickMouseErr(MMMouseButton button){
|
||||
int err = toggleMouseErr(true, button);
|
||||
int clickMouse(MMMouseButton button){
|
||||
int err = toggleMouse(true, button);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
microsleep(5.0);
|
||||
|
||||
return toggleMouseErr(false, button);
|
||||
return toggleMouse(false, button);
|
||||
}
|
||||
|
||||
void clickMouse(MMMouseButton button){
|
||||
clickMouseErr(button);
|
||||
}
|
||||
|
||||
int doubleClickErr(MMMouseButton button){
|
||||
/* Special function for sending double clicks, needed for MacOS. */
|
||||
int doubleClick(MMMouseButton button){
|
||||
#if defined(IS_MACOSX)
|
||||
/* Double click for Mac. */
|
||||
const CGPoint currentPos = CGPointFromMMPointInt32(location());
|
||||
|
|
@ -223,7 +210,6 @@ int doubleClickErr(MMMouseButton button){
|
|||
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventRef event = CGEventCreateMouseEvent(source, mouseTypeDown, currentPos, kCGMouseButtonLeft);
|
||||
|
||||
if (event == NULL) {
|
||||
CFRelease(source);
|
||||
return (int)kCGErrorCannotComplete;
|
||||
|
|
@ -238,26 +224,18 @@ int doubleClickErr(MMMouseButton button){
|
|||
|
||||
CFRelease(event);
|
||||
CFRelease(source);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
/* Double click for everything else. */
|
||||
int err = clickMouseErr(button);
|
||||
int err = clickMouse(button);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
microsleep(200);
|
||||
|
||||
return clickMouseErr(button);
|
||||
return clickMouse(button);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Special function for sending double clicks, needed for MacOS. */
|
||||
void doubleClick(MMMouseButton button){
|
||||
doubleClickErr(button);
|
||||
}
|
||||
|
||||
/* Function used to scroll the screen in the required direction. */
|
||||
void scrollMouseXY(int x, int y) {
|
||||
#if defined(IS_WINDOWS)
|
||||
|
|
@ -268,7 +246,7 @@ void scrollMouseXY(int x, int y) {
|
|||
|
||||
#if defined(IS_MACOSX)
|
||||
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
CGEventRef event = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitPixel, 2, y, x);
|
||||
CGEventRef event = CGEventCreateScrollWheelEvent(source, kCGScrollEventUnitPixel, 2, y, x);
|
||||
CGEventPost(kCGHIDEventTap, event);
|
||||
|
||||
CFRelease(event);
|
||||
|
|
@ -351,10 +329,10 @@ bool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed)
|
|||
velo_y /= veloDistance;
|
||||
|
||||
pos.x += floor(velo_x + 0.5);
|
||||
pos.y += floor(velo_y + 0.5);
|
||||
pos.y += floor(velo_y + 0.5);
|
||||
|
||||
/* Make sure we are in the screen boundaries! (Strange things will happen if we are not.) */
|
||||
// if (pos.x >= screenSize.w || pos.y >= screenSize.h) {
|
||||
/* Make sure we are in the screen boundaries! */
|
||||
// if (pos.x >= screenSize.w || pos.y >= screenSize.h) {
|
||||
// return false;
|
||||
// }
|
||||
moveMouse(pos);
|
||||
|
|
@ -363,6 +341,5 @@ bool smoothlyMoveMouse(MMPointInt32 endPoint, double lowSpeed, double highSpeed)
|
|||
microsleep(DEADBEEF_UNIFORM(lowSpeed, highSpeed));
|
||||
// microsleep(DEADBEEF_UNIFORM(1.0, 3.0));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
81
robotgo.go
81
robotgo.go
|
|
@ -659,7 +659,7 @@ func Location() (int, int) {
|
|||
return x, y
|
||||
}
|
||||
|
||||
// Click click the mouse button
|
||||
// ClickV1 click the mouse button
|
||||
//
|
||||
// robotgo.Click(button string, double bool)
|
||||
//
|
||||
|
|
@ -668,7 +668,7 @@ func Location() (int, int) {
|
|||
// robotgo.Click() // default is left button
|
||||
// robotgo.Click("right")
|
||||
// robotgo.Click("wheelLeft")
|
||||
func Click(args ...interface{}) {
|
||||
func ClickV1(args ...interface{}) {
|
||||
var (
|
||||
button C.MMMouseButton = C.LEFT_BUTTON
|
||||
double bool
|
||||
|
|
@ -691,18 +691,19 @@ func Click(args ...interface{}) {
|
|||
MilliSleep(MouseSleep)
|
||||
}
|
||||
|
||||
// ClickE click the mouse button and return error
|
||||
// Click click the mouse button and return error
|
||||
//
|
||||
// robotgo.ClickE(button string, double bool)
|
||||
// robotgo.Click(button string, double bool)
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// err := robotgo.ClickE() // default is left button
|
||||
// err := robotgo.ClickE("right")
|
||||
func ClickE(args ...interface{}) error {
|
||||
// err := robotgo.Click() // default is left button
|
||||
// err := robotgo.Click("right")
|
||||
func Click(args ...interface{}) error {
|
||||
var (
|
||||
button C.MMMouseButton = C.LEFT_BUTTON
|
||||
double bool
|
||||
count int
|
||||
)
|
||||
|
||||
if len(args) > 0 {
|
||||
|
|
@ -720,30 +721,46 @@ func ClickE(args ...interface{}) error {
|
|||
}
|
||||
double = dbl
|
||||
}
|
||||
|
||||
defer MilliSleep(MouseSleep)
|
||||
|
||||
if !double {
|
||||
if code := C.toggleMouseErr(true, button); code != 0 {
|
||||
return formatClickError(int(code), button, "down", false)
|
||||
}
|
||||
|
||||
// match clickMouse timing
|
||||
C.microsleep(C.double(5.0))
|
||||
|
||||
if code := C.toggleMouseErr(false, button); code != 0 {
|
||||
return formatClickError(int(code), button, "up", false)
|
||||
}
|
||||
} else {
|
||||
if code := C.doubleClickErr(button); code != 0 {
|
||||
return formatClickError(int(code), button, "double", true)
|
||||
}
|
||||
if len(args) > 3 {
|
||||
count = args[3].(int)
|
||||
}
|
||||
|
||||
defer MilliSleep(MouseSleep)
|
||||
if !double {
|
||||
if code := C.toggleMouse(true, button); code != 0 {
|
||||
return formatClickError(int(code), button, "down", count)
|
||||
}
|
||||
MilliSleep(5)
|
||||
if code := C.toggleMouse(false, button); code != 0 {
|
||||
return formatClickError(int(code), button, "up", count)
|
||||
}
|
||||
} else {
|
||||
if code := C.doubleClick(button); code != 0 {
|
||||
return formatClickError(int(code), button, "double", 2)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatClickError(code int, button C.MMMouseButton, stage string, double bool) error {
|
||||
// MultiClick performs multiple clicks and returns error
|
||||
//
|
||||
// robotgo.MultiClick(button string, count int)
|
||||
func MultiClick(button string, count int) error {
|
||||
if count < 1 {
|
||||
return nil
|
||||
}
|
||||
btn := CheckMouse(button)
|
||||
defer MilliSleep(MouseSleep)
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
if err := Click(btn, false, count); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatClickError(code int, button C.MMMouseButton, stage string, count int) error {
|
||||
btnName := MouseButtonString(button)
|
||||
detail := ""
|
||||
|
||||
|
|
@ -776,10 +793,9 @@ func formatClickError(code int, button C.MMMouseButton, stage string, double boo
|
|||
}
|
||||
|
||||
if detail != "" {
|
||||
return fmt.Errorf("click %s failed (%s, double=%v): %s (code=%d)", stage, btnName, double, detail, code)
|
||||
return fmt.Errorf("click %s failed (%s, count=%d): %s (code=%d)", stage, btnName, count, detail, code)
|
||||
}
|
||||
|
||||
return fmt.Errorf("click %s failed (%s, double=%v), code=%d", stage, btnName, double, code)
|
||||
return fmt.Errorf("click %s failed (%s, count=%d), code=%d", stage, btnName, count, code)
|
||||
}
|
||||
|
||||
// MoveClick move and click the mouse
|
||||
|
|
@ -824,11 +840,14 @@ func Toggle(key ...interface{}) error {
|
|||
if len(key) > 1 && key[1].(string) == "up" {
|
||||
down = false
|
||||
}
|
||||
C.toggleMouse(C.bool(down), button)
|
||||
code := C.toggleMouse(C.bool(down), button)
|
||||
if code != 0 {
|
||||
return formatClickError(int(code), button, "down", 1)
|
||||
}
|
||||
|
||||
if len(key) > 2 {
|
||||
MilliSleep(MouseSleep)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue