首先是一点上下文。从本质上讲,我有一个覆盖桌面的窗口。在它上面,我有一些WebKit WebView视图,允许用户交互。通过deafult,正如人们所期望的,当另一个应用程序处于活动状态时,它不会接收到这些事件(例如悬停、鼠标输入和单击)。我可以先点击我的窗口,然后移动鼠标来让它工作,但这对可用性不好。我还设法让它在光标进入时激活窗口,但它远非理想,而且相当粗糙。
所以我试着使用一个追踪区域。目前在WebViews超级视图上,我有这个跟踪区域:
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
owner:self
userInfo:nil];
这是我想要的,我正在接收所有的鼠标事件。然而,WebViews似乎没有按预期做出响应。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。
发布一个示例Xcode项目,让人们更容易测试这个问题的解决方案。
我也在做类似的事情,花了很多时间才找到解决方案。您可能需要子类化NSWindow并添加- (BOOL)canBecomeKeyWindow { return YES; }
,然后每当您检测到鼠标在您的窗口上时,您可以调用[window orderFrontRegardless]
,这样它就可以正确地捕捉鼠标事件。