I have completed a method for Windows ( https://forum.xojo.com/12259-move-mouse-position-click-by-code )
Now I want to do the same for Mac OS X. The old AppleScript command click at {x,y}
has been brutally retired with Mavericks, so it cannot be used.
I scoured the Internet and found Mousetools which is meant to be used from the command line. I extracted the useful methods from the source and am trying to slowly find my way to Xojo declares.
I found the Apple doc page for what is used : https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html
Unfortunately, I find that documentation a lot harder to adapt than MS. To start with, I do not know what the library is, so I do not see how to build the declare. I searched for the function names in this forum unsuccessfully, and all I found was in http://forums.realsoftware.com/viewtopic.php?f=7&t=25915&hilit=CGEventTapOptions but no solution was ever found there. Interestingly, it all started from the impossibility to give focus to the HTMLViewer, and like the OP there, I want to click in it so it gets the focus.
My inspiration about Mac declares comes from the brilliant teachings of Sam Rowlands in https://forum.xojo.com/5179-mac-os-custom-fonts where I found at least this :
// - As we had a valid CFURLRef from a 'Create' or 'Copy' API, we must release it.
declare sub CFRelease lib "Cocoa" ( ref as ptr )
CFRelease CFUrlRef
So I believe this is the way to CFRelease(moveMouse);
and the like.
Now, for other functions.
Apple says for one of the functions :
[code]CGEventCreateMouseEvent
Returns a new Quartz mouse event.
CGEventRef CGEventCreateMouseEvent (
CGEventSourceRef source,
CGEventType mouseType,
CGPoint mouseCursorPosition,
CGMouseButton mouseButton
);
Parameters
source
An event source taken from another event, or NULL.
mouseType
A mouse event type. Pass one of the constants listed in Event Types.
mouseCursorPosition
The position of the mouse cursor in global coordinates.
mouseButton
The button thats changing state. Pass one of the constants listed in Mouse Buttons. This parameter is ignored unless the mouseType parameter is kCGEventOtherMouseDown, kCGEventOtherMouseDragged, or kCGEventOtherMouseUp.
Return Value
A new mouse event, or NULL if the event could not be created. When you no longer need the event, you should release it using the function CFRelease.[/code]
Here below CGEventRef moveMouse = CGEventCreateMouseEvent(sourceRef, kCGEventMouseMoved, CGPointMake(x, y), 0);
SourceRef is in a type that does not seem to exist in Xojo. Is it possible to synthesize a Quartz event source ?
declare function CGEventCreateMouseEvent lib "Cocoa" ( sourceRef as ?, mouseType as MouseEvent, mouseCursorPosition as RealBasic.Point, MouseButton as integer )
I am stuck there.
Any help will be greatly appreciated.
Of course, I can still call Mousetools from the command line, but it would be great to be able to do a declare.
[code]// global variables
CGEventTapLocation tapLocation;
CGEventSourceRef sourceRef;
// Variables
sourceRef = CGEventSourceCreate(kCGEventSourceStatePrivate); // kCGEventSourceStatePrivate is a constant ? Value ?
kCGEventMouseMoved // constant NX_MOUSEMOVED, not found value ?
CGPointMake(x, y) // = new realbasic.point(x,y)
tapLocation = kCGHIDEventTap; // used when specifying the tap location for CGEventPost
moveMouse // constant ? Value ?
mouseEvent // constant ? Found this : CGEventRef mouseEvent = CGEventCreate(NULL);
void moveMouseToPoint(float x, float y) {
//CGWarpMouseCursorPosition(CGPointMake(x, y));
CGEventRef moveMouse = CGEventCreateMouseEvent(sourceRef, kCGEventMouseMoved, CGPointMake(x, y), 0);
CGEventPost(tapLocation, moveMouse);
CFRelease(moveMouse);
} // mouse jumps directly from its current position to the new position and becomes visible, origin of CGPoint must be top-left
void performLeftClick(CGEventFlags modKeys) {
// get the current mouse location
CGEventRef mouseEvent = CGEventCreate(NULL);
CGPoint mouseLoc = CGEventGetLocation(mouseEvent);
CFRelease(mouseEvent);
// click mouse
CGEventRef clickMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseDown, mouseLoc, 0);
if (!modKeys == 0) CGEventSetFlags(clickMouse, modKeys);
CGEventPost(tapLocation, clickMouse);
CFRelease(clickMouse);
// release mouse
CGEventRef releaseMouse = CGEventCreateMouseEvent(sourceRef, kCGEventLeftMouseUp, mouseLoc, 0);
CGEventPost(tapLocation, releaseMouse);
CFRelease(releaseMouse);
} // left-click at current mouse location, we pass the modifier keys mask in case we want to shift-click[/code]