20

I'm using the following code to simulate a click of the mouse:

void PostMouseEvent(CGMouseButton button, CGEventType type, const CGPoint point) 
{
 CGEventRef theEvent = CGEventCreateMouseEvent(NULL, type, point, button);
 CGEventSetType(theEvent, type);
 CGEventPost(kCGHIDEventTap, theEvent);
 CFRelease(theEvent);
}

void LeftClick(const CGPoint point) 
{
 PostMouseEvent(kCGMouseButtonLeft, kCGEventMouseMoved, point);
 NSLog(@"Click!");
 PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseDown, point);
 PostMouseEvent(kCGMouseButtonLeft, kCGEventLeftMouseUp, point);
}

I can use basically the same code to do a control-click (right click) by changing:

kCGEventLeftMouseDown

kCGEventLeftMouseUp

kCGMouseButtonLeft

to their respective "Right" events. The function looks something like:

void RightClick(const CGPoint point) 
{
 PostMouseEvent(kCGMouseButtonRight, kCGEventMouseMoved, point);
 NSLog(@"Click Right");
 PostMouseEvent(kCGMouseButtonRight, kCGEventRightMouseDown, point);
 PostMouseEvent(kCGMouseButtonRight, kCGEventRightMouseUp, point);
}

But, how about a double click? I tried sending 2 leftclicks and calling PostMouseEvent() twice in a row but no luck. How do you perform a double click?

thanks!

STW
  • 44,917
  • 17
  • 105
  • 161
Uri
  • 1,275
  • 6
  • 17
  • 26

2 Answers2

18

Look into CGEventSetIntegerValueField(event, kCGMouseEventClickState, clickCount). Also, even after setting the clickCount to 2, you may have to perform 2 events in some cases, for legacy apps.

So basically:

  1. Create event
  2. Set click count to 2
  3. Set event type to mousedown and send
  4. Set event type to mouseup and send
  5. Repeat 3 and 4

Edit:

void doubleClick(int clickCount) {
    CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, point, kCGMouseButtonLeft);  
    CGEventSetIntegerValueField(theEvent, kCGMouseEventClickState, clickCount);  
    CGEventPost(kCGHIDEventTap, theEvent);  
    CGEventSetType(theEvent, kCGEventLeftMouseUp);  
    CGEventPost(kCGHIDEventTap, theEvent);  
    CGEventSetType(theEvent, kCGEventLeftMouseDown);  
    CGEventPost(kCGHIDEventTap, theEvent);  
    CGEventSetType(theEvent, kCGEventLeftMouseUp); 
    CGEventPost(kCGHIDEventTap, theEvent); 
    CFRelease(theEvent); 
}
summea
  • 7,390
  • 4
  • 32
  • 48
phoebus
  • 14,673
  • 2
  • 33
  • 35
  • like: CGEventSetIntegerValueField(kCGMouseButtonLeft, kCGEventLeftMouseDown, 2) do I need to reset it to 1 after that? – Uri Sep 27 '09 at 14:27
  • 1
    You need to pass in a reference to the actual event object, in your case to "theEvent", as the first parameter. At that point, that event's click count is set to 2, and you want to leave it to 2 for all 4 CGEventPosts that you need to do (down, up, down, up). – phoebus Sep 27 '09 at 14:31
  • like this: CGEventSetIntegerValueField(kCGEventLeftMouseDown, kCGMouseEventClickState, 2); I get several warning... can you post a snippet? thanks! – Uri Sep 27 '09 at 14:34
  • 1
    Thanks. One problem, once you perform the double click it won't click anywhere else. I pass as a parameter the current location of the mouse (point) but it still performs the double click on same point as before or the same application, regardless of whether it has focus. I'm assuming clickCount is 2, right? it's not declared anywhere. – Uri Sep 27 '09 at 23:21
  • I added CGEventSetType(theEvent, kCGEventLeftMouseDown); CGEventPost(kCGHIDEventTap, theEvent); becuase I thought it was missing but that wasn't the problem – Uri Sep 27 '09 at 23:26
  • 1
    You need not post the event twice with clickCount == 2, just once. In other words, post a MouseDown with clickCount = 2, then a MouseUp with clickCount = 2, and you're done. I just tested this (actually my code sends the first Down/Up with count=1 but the second one triggers the double click, as desired). – Jared Updike Jan 08 '11 at 00:25
  • 1
    This works for me in iTerm2, but not finder or other apps. It pretty much only works in iTerm2. Any idea why? – Jason Stallings Apr 28 '15 at 14:36
  • ok it works but testing in IntelliJ Clion I need to add single click before double click in order to Clion window get focus first – Michał Ziobro Aug 21 '16 at 11:15
5

This is sample code to simulate a double click.

CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, CGPointMake(x, y), kCGMouseButtonLeft);  
CGEventPost(kCGHIDEventTap, theEvent);  
CGEventSetType(theEvent, kCGEventLeftMouseUp);  
CGEventPost(kCGHIDEventTap, theEvent);  

CGEventSetIntegerValueField(theEvent, kCGMouseEventClickState, 2);

CGEventSetType(theEvent, kCGEventLeftMouseDown);  
CGEventPost(kCGHIDEventTap, theEvent);  

CGEventSetType(theEvent, kCGEventLeftMouseUp); 
CGEventPost(kCGHIDEventTap, theEvent); 

CFRelease(theEvent); 

Notice that CGEventSetIntegerValueField(theEvent, kCGMouseEventClickState, 2);goes after the first set of down,up clicks.

Tom Dev
  • 1,114
  • 8
  • 18