奇怪的 CGEventPost 鼠标点击行为

发布于 2024-10-26 00:38:14 字数 2359 浏览 1 评论 0原文

在我的 Mac 应用程序中,我尝试使用 CG 事件点击来拦截鼠标右键向下/向上事件。我有注册为监听器的代码,工作得很好。我想做的是拦截用户用鼠标右键单击时的情况,并暂时吃掉该事件。当他们放开鼠标右键时,如果他们自原始鼠标按下事件以来没有移动鼠标,我想发布鼠标右键按下事件。如果他们移动了鼠标,我希望我的应用程序的代码执行不同的操作。如果我使用触控板在 Macbook 上运行代码,这一切都非常有效。但是,当我将鼠标插入同一台计算机时,所有其他鼠标按下事件都不会触发我的回调。

这样做的基本逻辑是我跟踪“忽略下一个事件”布尔值。当我的程序第一次运行时,它被设置为 false。当我收到鼠标右键按下事件时,我返回 NULL。当鼠标右键按下事件触发时,我创建并发布一个新的鼠标右键按下事件,并将ignoreNext设置为true。然后我返回鼠标右键松开事件。

这是我的代码:

CGPoint mouseDownPoint;
bool ignoreNext;

//---------------------------------------------------------------------------
CGEventRef MouseTapCallback( CGEventTapProxy aProxy, CGEventType aType, CGEventRef aEvent, void* aRefcon ) 
//---------------------------------------------------------------------------
{
    if( aType == kCGEventRightMouseDown ) NSLog( @"down" );
    else if( aType == kCGEventRightMouseUp ) NSLog( @"up" );
    else NSLog( @"other" );

    NSLog( @"ignored: %d", ignoreNext );

    CGPoint theLocation = CGEventGetLocation(aEvent);

    if( !ignoreNext )
    {
        if( aType == kCGEventRightMouseDown )
        {
            mouseDownPoint = theLocation;

            return NULL;
        }
        else if( aType == kCGEventRightMouseUp )
        {
            if( abs( theLocation.x - mouseDownPoint.x ) < 1 &&
                abs( theLocation.y - mouseDownPoint.y ) < 1 )
            {
                ignoreNext = true;

                CGEventRef theNewEvent = CGEventCreateMouseEvent( NULL,
                                                                 kCGEventRightMouseDown, 
                                                                 mouseDownPoint, 
                                                                 kCGMouseButtonRight );

                CGEventSetType( theNewEvent, kCGEventRightMouseDown );
                CGEventPost( kCGHIDEventTap, theNewEvent );

                return aEvent;
            }
            else
            {
                // execute my app's code here...

                return NULL;
            }
        }
    }

    ignoreNext = false;
    return aEvent; 
}

当我用触控板测试它时,输出是(工作正常):

down 忽略:0 向上 忽略:0 向下 忽略:1

当我用实际鼠标测试它时的输出(注意:第二次运行时缺少鼠标按下事件):

第一次单击向下然后向上...

向下 忽略:0 向上 忽略:0 向下 被忽略:1

第二次,鼠标按下事件没有触发我的回调...

向上 ignored: 0

有没有人见过这样的事情,如果有的话,你做了什么来解决这个问题?感谢您抽出时间。

In my Mac application I am trying to intercept right mouse down/up events using CG Event Taps. I have the code that is registering as a listener working just fine. What I am trying to do is intercept when the user clicks down with the right mouse button, and eat the event temporarily. When they let go of the right mouse button I want to post a right mouse down event if they haven't moved the mouse since the original mouse down event. If they have moved the mouse I want my app's code to do something different. This all works great if I run the code on my Macbook using the trackpad. However, when I plug a mouse into the same computer every other mouse down event does not trigger my callback.

The basic logic for doing this is I keep track of an "ignore next event" bool. When my program first runs this is set to false. When I get a right mouse down event I return NULL. When the right mouse up event triggers I create and post a new right mouse down event with ignoreNext to true. I then return the right mouse up event.

Here is my code:

CGPoint mouseDownPoint;
bool ignoreNext;

//---------------------------------------------------------------------------
CGEventRef MouseTapCallback( CGEventTapProxy aProxy, CGEventType aType, CGEventRef aEvent, void* aRefcon ) 
//---------------------------------------------------------------------------
{
    if( aType == kCGEventRightMouseDown ) NSLog( @"down" );
    else if( aType == kCGEventRightMouseUp ) NSLog( @"up" );
    else NSLog( @"other" );

    NSLog( @"ignored: %d", ignoreNext );

    CGPoint theLocation = CGEventGetLocation(aEvent);

    if( !ignoreNext )
    {
        if( aType == kCGEventRightMouseDown )
        {
            mouseDownPoint = theLocation;

            return NULL;
        }
        else if( aType == kCGEventRightMouseUp )
        {
            if( abs( theLocation.x - mouseDownPoint.x ) < 1 &&
                abs( theLocation.y - mouseDownPoint.y ) < 1 )
            {
                ignoreNext = true;

                CGEventRef theNewEvent = CGEventCreateMouseEvent( NULL,
                                                                 kCGEventRightMouseDown, 
                                                                 mouseDownPoint, 
                                                                 kCGMouseButtonRight );

                CGEventSetType( theNewEvent, kCGEventRightMouseDown );
                CGEventPost( kCGHIDEventTap, theNewEvent );

                return aEvent;
            }
            else
            {
                // execute my app's code here...

                return NULL;
            }
        }
    }

    ignoreNext = false;
    return aEvent; 
}

The output for this when I test it with the track pad is (working correctly):

down
ignored: 0
up
ignored: 0
down
ignored: 1

The output for this when I test it with an actual mouse (note: the mouse down event is missing on the second run through):

First time clicking down then up...

down
ignored: 0
up
ignored: 0
down
ignored: 1

Second time, the mouse down event doesn't trigger my callback...

up
ignored: 0

Has anyone seen anything like this before, and if so, what did you do to solve this problem? Thanks for your time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文