NSTrackingArea在没有关键窗口时没有完全工作

时间:2015-03-28 04:28:50

标签: cocoa webview nsevent nstrackingarea

首先是一些背景。基本上我有一个覆盖桌面的窗口。在它上面我有一些允许用户交互的WebKit WebView视图。通过聋人,正如人们所期望的那样,当另一个应用程序处于活动状态时,它不会收到这些事件(例如悬停,鼠标输入和点击)。我可以通过先点击我的窗口,然后移动鼠标来使其工作,但这对可用性不利。我还设法让它在光标进入时激活窗口,但它远非理想而且非常黑客。

所以我试图使用跟踪区域。目前在WebViews超级视图中我有这个跟踪区域:

NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
                                                                options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
                                                                owner:self
                                                                userInfo:nil];

这就像我想要的那样,我收到了所有的鼠标事件。但是,WebView似乎没有按预期响应。 JavaScript鼠标移动事件仅在我按住并拖动时触发,而不仅仅是悬停和拖动。

我尝试过使用hitTest来获取正确的视图,但似乎没有任何效果。这是一个示例方法,我使用isHandlingMouse布尔值,因为没有它,似乎由于某种原因创建了无限循环:

- (NSView *)handleTrackedMouseEvent: (NSEvent *)theEvent{
    if(isHandlingMouse)
        return nil;
    isHandlingMouse = true;
    NSView *hit = [self hitTest: theEvent.locationInWindow];
    if (hit && hit != self) {
        return hit;
    }
    return nil;
}

- (void)mouseMoved:(NSEvent *)theEvent{
    NSView *hit = [self handleTrackedMouseEvent: theEvent];
    if (hit){
        [hit mouseMoved: theEvent];
    }
    isHandlingMouse = false;
}

“点击”视图是一个WebHTMLView,它似乎是一个私有类。一切似乎都应该有效,但也许我正在做的事情正在破坏它,或者我正在将事件发送到WebHTMLView。

1 个答案:

答案 0 :(得分:2)

发布一个示例Xcode项目,以便人们更容易测试此问题的解决方案。

我做了类似的事情,并且需要大量的试验和错误才能找到解决方案。您可能需要子类化NSWindow并添加- (BOOL)canBecomeKeyWindow { return YES; },然后每当您检测到鼠标在窗口上时,您可以调用[window orderFrontRegardless]以便它可以正确捕获鼠标事件。