使用事件点击消耗OSX鼠标/触控板事件 [英] Consuming OSX mouse/trackpad events with an event tap

查看:990
本文介绍了使用事件点击消耗OSX鼠标/触控板事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加一个事件陷阱来启用/禁用我的魔术触控板中的事件。我认为这是直接的,即注册事件陷阱,并在需要时,通过返回 NULL 丢弃事件。这个想法是使用pad为一些特定的,耗时的数据输入,应用程序输入数据是第三方的所以我不能只是添加代码做我想要的那里。所以我想我会监控系统事件,然后通过一堆 CGEventCreateKeyboardEvent 发送所需的输入。

I'm trying to add an event trap to enable/disable event from my magic trackpad. I thought this would be straight forward, i.e. register an event trap and when required, discard the event by returning NULL. The idea is to use the pad for some specific, time consuming data entry, the applications to enter the data into are third party ones so I can't just add code to do want I want there. So i figured I'd monitor the system events and then send the desired input via a bunch of CGEventCreateKeyboardEvents.

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

The problem is returning null does not seem to discard the events, a bit more investigation suggests that this is not restricted to those coming from the trackpad but also my default usb mouse.

我的代码如下。下面是我期望不能移动鼠标,如果我改变(A)使用 kCGEventScrollWheel kCGEventLeftMouseDragged 然后事件被消耗,即滚动或左btn拖动不发生。这是否意味着不是所有的事件都可以丢弃?希望我只是缺少一些明显的这里

My code is below. With what is below i'd expect not to be able to move the mouse, if I change (A) to use kCGEventScrollWheel or kCGEventLeftMouseDragged then event is consumed, i.e. scrolling or left btn drag don't occur. Does this mean that not all events can be discarded? Hopefully I'm just missing something obvious here

  #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;
}

请注意,axapi未启用该辅助功能选项会影响除键盘事件之外的任何内容。

Note, "axapi not enabled" is not output although i don't think the accessibility option affects anything but the keyboard events.

BTW,我已经看到了几个类似的帖子,如何从触摸板获取事件,

BTW, I've seen a few similar posts on how to get the events from the touch pad, just nothing applicable to discarding them (other than returning null should work).

推荐答案

如果你的tap是被动的,返回NULL将留下事件流不受影响。从 CGEventTapCallBack 参考文档:

If your tap is passive, returning NULL will leave the event stream unaffected. From the CGEventTapCallBack reference documentation:


如果事件敲击是被动
listener,你的回调函数可以
返回传入的事件,或
NULL。在任一种情况下,事件流
不受影响。

"If the event tap is an passive listener, your callback function may return the event that is passed in, or NULL. In either case, the event stream is not affected."

但是,看起来您的水龙头是活动的。因此,您返回的NULL应该删除事件。您是否已考虑修改事件以使操作无效?

However, it looks like your tap is active. Thus your returning NULL should delete the event. Have you considered modifying the event to nullify the action?

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

Also note that the call CGEventTapCreate requires root user permissions to intercept all events. Is your process running as root?

这篇关于使用事件点击消耗OSX鼠标/触控板事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆