我有一个非常基本的小命令行应用程序,下次单击鼠标时会捕获鼠标坐标。
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
CGFloat displayScale = 1.0f;
if ([[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)])
{
displayScale = [NSScreen mainScreen].backingScaleFactor;
}
CGPoint loc = CGEventGetLocation(event);
CFRelease(event);
printf("%dx%d\n", (int)roundf(loc.x * displayScale), (int)roundf(loc.y * displayScale) );
exit(0);
return event;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
CFMachPortRef eventTap;
CGEventMask eventMask;
CFRunLoopSourceRef runLoopSource;
eventMask = 1 << kCGEventLeftMouseDown;
eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
1, eventMask, myCGEventCallback, @"mydata");
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource,
kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
}
return 0;
}
我用cmake用以下文件构建它:
cmake_minimum_required(VERSION 3.0.0)
project (location)
set(CMAKE_C_FLAGS "-arch x86_64 -mmacosx-version-min=10.12 -std=gnu11 -fobjc-arc -fmodules")
在升级到Mojave之前,所有这些工作都很好。
稍作回想表明这是最新的安全更新集,还有一些hints(除了
CGEventTapCreate()
不返回null以外)有关设置Info.plist
中的某些值以允许应用程序使用可访问性API的信息。但是我正在努力找出将其放置在哪里,因为我只有一个带有代码的.m文件。编辑
这需要以非root用户身份运行(公司策略)
如果是获取许可的唯一途径,则可以将其扩展为具有最小UI的“ GUI”应用
该应用程序只是抓住屏幕区域的左上角,以馈送到第二个应用程序,该应用程序将屏幕的该区域流式传输到第二个设备。流媒体的代码在Win / Linux / MacOS中是通用的,因此请尝试使屏幕坐标集合完全独立
最佳答案
如您所料,如果没有访问权限,事件水龙头将无法在Mojave上使用。从documentation:
如果满足以下任一条件,则事件点击会接收按键上升和按键下降事件
条件为true:当前进程以root用户身份运行。
启用辅助设备的访问权限。在OS X v10.4中,您可以启用
使用“系统偏好设置”,“通用访问”面板,
键盘视图。
GUI应用程序将在第一次需要时提示用户启用可访问性,但看起来CLI应用程序没有执行此操作(这很有意义)。
无法以编程方式或通过脚本启用此功能;用户必须自己做。
以root
运行工具应该可以工作-您可以强制执行吗?
否则,您可以将用户定向到“系统偏好设置”中的正确位置:
tell application "System Preferences"
reveal anchor "Privacy_Accessibility" of pane id "com.apple.preference.security"
activate
end tell
如果您的应用未沙箱化,则可以使用Carbon。
最后,快速测试显示至少使用IOHID可以做到这一点。我无耻地从answer借用了
KeyboardWatcher
类。然后,修改设备类型:[self watchDevicesOfType:kHIDUsage_GD_Keyboard];
变成:
[self watchDevicesOfType:kHIDUsage_GD_Mouse];
最后,我的回调如下所示:
static void Handle_DeviceEventCallback (void *inContext, IOReturn inResult, void *inSender, IOHIDValueRef value)
{
IOHIDElementRef element = IOHIDValueGetElement(value);
IOHIDElementType elemType = IOHIDElementGetType(element);
if (elemType == kIOHIDElementTypeInput_Button)
{
int elementValue = (int) IOHIDValueGetIntegerValue(value);
// 1 == down 0 == up
if (elementValue == 1)
{
CGEventRef ourEvent = CGEventCreate(NULL);
CGPoint point = CGEventGetLocation(ourEvent);
printf("Mouse Position: %.2f, y = %.2f \n", (float) point.x, (float) point.y);
}
}
}
这确实是一项快速的黑客工作,但它证明了这是可能的,并希望您可以根据需要对其进行完善。
关于macos - 在Mojave上获取鼠标坐标,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54037083/