Simulating mouse input programmatically in OS X

前端 未结 4 1279
悲&欢浪女
悲&欢浪女 2020-12-07 08:26

Is it possible to simulate the actions of a mouse from a program in OS X? Specifically, the short version is that I\'m trying to simulate a touchscreen using two webcams. So

相关标签:
4条回答
  • 2020-12-07 08:26

    Swift mouse move and click example:

    func mouseMoveAndClick(onPoint point: CGPoint) { 
        guard let moveEvent = CGEvent(mouseEventSource: nil, mouseType: .mouseMoved, mouseCursorPosition: point, mouseButton: .left) else {
            return
        }
        guard let downEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left) else {
            return
        }
        guard let upEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left) else {
            return
        }
        moveEvent.post(tap: CGEventTapLocation.cghidEventTap)
        downEvent.post(tap: CGEventTapLocation.cghidEventTap)
        upEvent.post(tap: CGEventTapLocation.cghidEventTap)
    }
    
    0 讨论(0)
  • 2020-12-07 08:41

    Yes, it is possible. You can use the Quartz Event Services to simulate input events.

    Assuming C, I wrote this quick example:

    #include <ApplicationServices/ApplicationServices.h>
    #include <unistd.h>
    
    int main() {
        // Move to 200x200
        CGEventRef move1 = CGEventCreateMouseEvent(
            NULL, kCGEventMouseMoved,
            CGPointMake(200, 200),
            kCGMouseButtonLeft // ignored
        );
        // Move to 250x250
        CGEventRef move2 = CGEventCreateMouseEvent(
            NULL, kCGEventMouseMoved,
            CGPointMake(250, 250),
            kCGMouseButtonLeft // ignored
        );
        // Left button down at 250x250
        CGEventRef click1_down = CGEventCreateMouseEvent(
            NULL, kCGEventLeftMouseDown,
            CGPointMake(250, 250),
            kCGMouseButtonLeft
        );
        // Left button up at 250x250
        CGEventRef click1_up = CGEventCreateMouseEvent(
            NULL, kCGEventLeftMouseUp,
            CGPointMake(250, 250),
            kCGMouseButtonLeft
        );
    
        // Now, execute these events with an interval to make them noticeable
        CGEventPost(kCGHIDEventTap, move1);
        sleep(1);
        CGEventPost(kCGHIDEventTap, move2);
        sleep(1);
        CGEventPost(kCGHIDEventTap, click1_down);
        CGEventPost(kCGHIDEventTap, click1_up);
    
        // Release the events
        CFRelease(click1_up);
        CFRelease(click1_down);
        CFRelease(move2);
        CFRelease(move1);
    
        return 0;
    }
    

    And assuming GCC, compile with:

    gcc -o program program.c -Wall -framework ApplicationServices

    Enjoy the magic.

    0 讨论(0)
  • 2020-12-07 08:46

    If you don't want to compile things and are looking for a shell-based tool, Cliclick may be the solution.

    0 讨论(0)
  • 2020-12-07 08:53

    Here is a working C program based on jweyrick's answer:

    // Compile instructions:
    //
    // gcc -o click click.c -Wall -framework ApplicationServices
    
    #include <ApplicationServices/ApplicationServices.h>
    #include <unistd.h>
    
    int main(int argc, char *argv[]) {
      int x = 0, y = 0, n = 1;
      float duration = 0.1;
    
      if (argc < 3) {
        printf("USAGE: click X Y [N] [DURATION]\n");
        exit(1);
      }
    
      x = atoi(argv[1]);
      y = atoi(argv[2]);
    
      if (argc >= 4) {
        n = atoi(argv[3]);
      }
    
      if (argc >= 5) {
        duration = atof(argv[4]);
      }
    
      CGEventRef click_down = CGEventCreateMouseEvent(
        NULL, kCGEventLeftMouseDown,
        CGPointMake(x, y),
        kCGMouseButtonLeft
      );
    
      CGEventRef click_up = CGEventCreateMouseEvent(
        NULL, kCGEventLeftMouseUp,
        CGPointMake(x, y),
        kCGMouseButtonLeft
      );
    
      // Now, execute these events with an interval to make them noticeable
      for (int i = 0; i < n; i++) {
        CGEventPost(kCGHIDEventTap, click_down);
        sleep(duration);
        CGEventPost(kCGHIDEventTap, click_up);
        sleep(duration);
      }
    
      // Release the events
      CFRelease(click_down);
      CFRelease(click_up);
    
      return 0;
    }
    

    Hosted at https://gist.github.com/Dorian/5ae010cd70f02adf2107

    0 讨论(0)
提交回复
热议问题