使用事件点击消耗OSX鼠标/触控板事件

vic*_*irk 6 macos cocoa objective-c

我正在尝试添加一个事件陷阱来启用/禁用魔术触控板上的事件.我认为这将是直截了当的,即注册事件陷阱,并在需要时通过返回丢弃事件NULL.我们的想法是使用pad进行一些特定的,耗时的数据输入,输入数据的应用程序是第三方的,所以我不能只是添加代码来实现我想要的.所以我想我会监视系统事件,然后通过一堆CGEventCreateKeyboardEvents 发送所需的输入.

问题是返回null似乎没有丢弃事件,更多的调查表明,这不仅限于来自触控板的那些,而且也是我的默认USB鼠标.

我的代码如下.以下是我希望不能移动鼠标,如果我改变(A)使用kCGEventScrollWheelkCGEventLeftMouseDragged然后消耗事件,即滚动或左btn拖动不会发生.这是否意味着并非所有事件都可以丢弃?希望我在这里错过了一些明显的东西

  #define case_print(a) case a: printf("%s - %d\n",#a,a); break;


  CGEventRef eventOccurred(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* refcon) {
    int subType =  CGEventGetIntegerValueField(event, kCGMouseEventSubtype);
    if (type == NSEventTypeGesture || subType == NX_SUBTYPE_MOUSE_TOUCH) {
        printf("touchpad\n");

        switch(type) {
                case_print(kCGEventNull)
                case_print(kCGEventLeftMouseDown)
                case_print(kCGEventLeftMouseUp)
                case_print(kCGEventRightMouseDown)
                case_print(kCGEventRightMouseUp)
                case_print(kCGEventMouseMoved)
                case_print(kCGEventLeftMouseDragged)
                case_print(kCGEventRightMouseDragged)
                case_print(kCGEventScrollWheel)
                case_print(kCGEventOtherMouseDown)
                case_print(kCGEventOtherMouseUp)
                case_print(kCGEventOtherMouseDragged)
                case_print(kCGEventTapDisabledByTimeout)
                case_print(kCGEventTapDisabledByUserInput)
                case_print(NSEventTypeGesture)
                case_print(NSEventTypeMagnify)
                case_print(NSEventTypeSwipe)
                case_print(NSEventTypeRotate)
                case_print(NSEventTypeBeginGesture)
                case_print(NSEventTypeEndGesture)
            default:
                printf("default: %d\n",type);
                break;    
        }

        event = NULL;
    }  else {
        if (type == kCGEventMouseMoved) {  // (A)
            printf("discarding mouse event");
            event = NULL;
        }
    }

    return event;
}


CFMachPortRef createEventTap() {  
    CGEventMask eventMask = NSAnyEventMask;

    if (!AXAPIEnabled() && !AXIsProcessTrusted()) { 
        printf("axapi not enabled");
    } 

    return CGEventTapCreate(kCGHIDEventTap, 
                            kCGHeadInsertEventTap, 
                            kCGEventTapOptionDefault, 
                            eventMask, 
                            eventOccurred, 
                            NULL); 
}

int main (int argc, const char * argv[]) {
    CFMachPortRef tap = createEventTap();

    if (tap) {
        CFRunLoopSourceRef rl = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0);
        CFRunLoopAddSource(CFRunLoopGetMain(), rl, kCFRunLoopCommonModes);
        CGEventTapEnable(tap, true);
        CFRunLoopRun();

        printf("Tap created.\n");
        sleep(-1);
    } else {
        printf("failed!\n");
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,虽然我认为辅助功能选项不会影响除键盘事件之外的任何内容,但不会输出"未启用axapi".

顺便说一句,我已经看过一些关于如何从触摸板获取事件的类似帖子,只是没有适用于丢弃它们(除了返回null应该工作).

Gra*_*iln 1

如果您的点击是被动的,则返回 NULL 将使事件流不受影响。来自CGEventTapCallBack参考文档:

“如果事件点击是被动侦听器,则您的回调函数可能会返回传入的事件或 NULL。在任何一种情况下,事件流都不会受到影响。”

但是,您的水龙头似乎处于活动状态。因此,您返回的 NULL 应该删除该事件。您是否考虑过修改事件以使操作无效?

另请注意,调用 CGEventTapCreate 需要 root 用户权限才能拦截所有事件。您的进程是否以 root 身份运行?

  • 为什么这被标记为答案?您能够停止处理鼠标事件吗?我能够停止关键事件,但不能停止鼠标移动...... (3认同)