0

我在 NSView 中创建了一个跟踪区域,它应该只在窗口是关键窗口时跟踪鼠标移动事件。但是,我注意到有时,当窗口与另一个当前为键的窗口重叠时,不再是键窗口的背景窗口仍会收到 mouseMoved: 事件。

这是我在 NSView 子类中的代码:

if (_trackingArea != nil) {
    [self removeTrackingArea:_trackingArea];
}
_trackingArea = [[NSTrackingArea alloc]
                 initWithRect:trackingFrame
                 options:(NSTrackingAreaOptions)(NSTrackingMouseMoved | NSTrackingActiveInKeyWindow)
                 owner:self
                 userInfo:nil];
[self addTrackingArea:_trackingArea];

我添加NSLog(@"is window key %d", [[self window] isKeyWindow])-mouseMoved:它,它清楚地表明背景窗口不是关键,尽管它仍然接收鼠标移动事件。

在我单击背景窗口使其成为键,然后再次单击前景窗口使其成为键后,此工件消失了。然后后台窗口停止接收鼠标移动事件。

这是 NSTrackingArea 的错误,有什么办法可以解决吗?

更新:我注意到此错误仅在后台窗口以编程方式调整大小时出现,而前台窗口具有键盘焦点。

4

1 回答 1

0

我解释文档的方式与您的匹配,我希望 TA在父窗口是关键时才会激活。但是,显然情况并非如此,这不是一个新错误,因为我能够在 10.14 上重现它

在内部,有许多私有方法可以控制安装的内容和时间:

  • -[NSView _installTrackingArea:]/-[NSView _uninstallTrackingArea:]
  • -[NSView _enableTrackingArea:]/-[NSView disableTrackingArea:]
  • -[NSWindow _addMouseMovedListener:]/-[NSWindow _removeMouseMovedListener:]

如果您向它们添加符号断点并记录正在传递的对象,您将在按下按钮后看到以下内容:

-updateTrackingAreas 0x600002148c80
Uninstall TA 0x60000213f3e0
Remove MML 0x60000213f3e0
Install TA 0x600002148c80
Disable TA 0x600002148c80
Remove MML 0x600002148c80
Add MML 0x600002148c80
Uninstall TA 0x6000021447d0
Install TA 0x60000212d7c0

0x600002148c80是添加到视图中的跟踪区域。正如您在安装过程中看到的那样,它被禁用并且关联的鼠标移动侦听器(MML)被删除以立即添加回来。

这是一个错误或缺少文档。

我建议重写-[NSView updateTrackingAreas]

  • 打电话[super updateTrackingAreas]是因为文档建议
  • 仅重新添加 TA 以反映框架、选项或所有者的更改
  • 不要单独依赖助教的选项,并仔细检查条件是否正确(窗口是关键,应用程序处于活动状态等)。换句话说,将 TA 的选项处理为对未来的状态变化采取行动。
  • 检查(或断言)事件处理程序中的状态:它们可能会被调用以响应其他事情
于 2020-11-25T11:55:54.247 回答