Seen
Seen

Reputation: 53

Simulated Mouseevents ignored on macOS in OpenGL

I have a larger project for which I want to have function that if run, clicks 10 times as fast as possible at the current cursor location.

This kind of works on my desktop, for example I tried running the program in my terminal and had my cursor on the menu bar. But if I switch to another application however (I tried it with a game in window mode) (I first let my program sleep for 4 seconds so I have enough time to switch), it just clicks once. The game is a shooter, so it should fire a couple of times fast but it just fires once and ignores all other events.

If I let my program sleep for 1 sec between cycles, it works.

Maybe I used the CGEvents wrong? Is there a difference between using MouseEvents and actually clicking? I mean shouldn't it be exactly the same for the game?

Here is my isolated code:

// Compile with: gcc -o click test.c -Wall -framework ApplicationServices

#include <ApplicationServices/ApplicationServices.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    // To click on current position (seems to work)
    CGEventRef event = CGEventCreate(NULL);
    CGPoint cursor = CGEventGetLocation(event);


    CGEventRef click_down = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, cursor, kCGMouseButtonLeft);

    CGEventRef click_up = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseUp, cursor, kCGMouseButtonLeft);

    // Tried adding usleep between both events but anything under 1s doesnt work
    for(int i = 0; i < 10; i++){
        CGEventPost(kCGSessionEventTap, click_down);
        // usleep(500);
        CGEventPost(kCGSessionEventTap, click_up);
        // usleep(500);
    }

    // Release the events
    CFRelease(event);
    CFRelease(click_down);
    CFRelease(click_up);

}

What I read and tried but didn't help:

Simulate mouse on Mac

Simulating mouse clicks on Mac OS X does not work for some applications -> Unfortunately didn't help or fix the problem

Synthetic click doesn't switch application's menu bar (Mac OS X)

Upvotes: 1

Views: 198

Answers (1)

Seen
Seen

Reputation: 53

I found the solution myself and it is really simple:

First of all I forgot that usleep is in microseconds and not miliseconds.

Furthermore apparently macOS buffers the clicks or keyboard inputs in the native environment but OpenGL doesn't. So of course it works if you pause for 1 second between clicks/keyboard presses but in OpenGL it just discards them if they are too fast. The solution is to wait the a small amount between clicks or keypresses. For me worked 100ms, that means usleep(100000), before and after the press down.

Upvotes: 1

Related Questions