我有一个非常基本的小命令行应用程序,下次单击鼠标时会捕获鼠标坐标。

#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/

10-12 03:15