diff --git a/mouse/mouse_c.h b/mouse/mouse_c.h index fc8bdb4..7bbd38f 100644 --- a/mouse/mouse_c.h +++ b/mouse/mouse_c.h @@ -195,42 +195,26 @@ 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); - if (err != 0) { - return err; +/* Multi-click function supporting any click count (1=single, 2=double, 3=triple, etc.) */ +int multiClickErr(MMMouseButton button, int clickCount){ + if (clickCount < 1) { + return 0; } - microsleep(5.0); - - return toggleMouseErr(false, button); -} - -void clickMouse(MMMouseButton button){ - clickMouseErr(button); -} - -int doubleClickErr(MMMouseButton button){ #if defined(IS_MACOSX) - /* Double click for Mac. */ const CGPoint currentPos = CGPointFromMMPointInt32(location()); const CGEventType mouseTypeDown = MMMouseToCGEventType(true, button); const CGEventType mouseTypeUP = MMMouseToCGEventType(false, button); CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); - CGEventRef event = CGEventCreateMouseEvent(source, mouseTypeDown, currentPos, kCGMouseButtonLeft); + CGEventRef event = CGEventCreateMouseEvent(source, mouseTypeDown, currentPos, (CGMouseButton)button); if (event == NULL) { CFRelease(source); return (int)kCGErrorCannotComplete; } - /* Set event to double click. */ - CGEventSetIntegerValueField(event, kCGMouseEventClickState, 2); + CGEventSetIntegerValueField(event, kCGMouseEventClickState, clickCount); CGEventPost(kCGHIDEventTap, event); CGEventSetType(event, mouseTypeUP); @@ -241,23 +225,25 @@ int doubleClickErr(MMMouseButton button){ return 0; #else - /* Double click for everything else. */ - int err = clickMouseErr(button); - if (err != 0) { - return err; + int i; + for (i = 0; i < clickCount; i++) { + int err = toggleMouseErr(true, button); + if (err != 0) { + return err; + } + microsleep(5.0); + err = toggleMouseErr(false, button); + if (err != 0) { + return err; + } + if (i < clickCount - 1) { + microsleep(200); + } } - - microsleep(200); - - return clickMouseErr(button); + return 0; #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) diff --git a/robotgo.go b/robotgo.go index a875790..d5b7a4e 100644 --- a/robotgo.go +++ b/robotgo.go @@ -683,9 +683,9 @@ func Click(args ...interface{}) { } if !double { - C.clickMouse(button) + C.multiClickErr(button, 1) } else { - C.doubleClick(button) + C.multiClickErr(button, 2) } MilliSleep(MouseSleep) @@ -723,27 +723,19 @@ func ClickE(args ...interface{}) error { defer MilliSleep(MouseSleep) - if !double { - if code := C.toggleMouseErr(true, button); code != 0 { - return formatClickError(int(code), button, "down", false) - } + clickCount := 1 + if double { + clickCount = 2 + } - // 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 code := C.multiClickErr(button, C.int(clickCount)); code != 0 { + return formatClickError(int(code), button, clickCount) } return nil } -func formatClickError(code int, button C.MMMouseButton, stage string, double bool) error { +func formatClickError(code int, button C.MMMouseButton, clickCount int) error { btnName := MouseButtonString(button) detail := "" @@ -776,10 +768,28 @@ 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 failed (%s, count=%d): %s (code=%d)", btnName, clickCount, detail, code) } - return fmt.Errorf("click %s failed (%s, double=%v), code=%d", stage, btnName, double, code) + return fmt.Errorf("click failed (%s, count=%d), code=%d", btnName, clickCount, code) +} + +// MultiClickE performs multiple clicks and returns error +// +// robotgo.MultiClickE(button string, clickCount int) +func MultiClickE(button string, clickCount int) error { + if clickCount < 1 { + return nil + } + + btn := CheckMouse(button) + defer MilliSleep(MouseSleep) + + if code := C.multiClickErr(btn, C.int(clickCount)); code != 0 { + return formatClickError(int(code), btn, clickCount) + } + + return nil } // MoveClick move and click the mouse @@ -824,7 +834,7 @@ func Toggle(key ...interface{}) error { if len(key) > 1 && key[1].(string) == "up" { down = false } - C.toggleMouse(C.bool(down), button) + C.toggleMouseErr(C.bool(down), button) if len(key) > 2 { MilliSleep(MouseSleep) }