AXWindowMoved(通过 AXObserver) - 持续更新?

4 xcode cocoa objective-c accessibility-api nswindow

是否有任何其他方法可用于获取持续更新而不是 kAXWindowMovedNotification(可访问性 api - 通过 AXObserver 侦听),它只是在拖动开始时晚得多地发送通知?如果可能的话,我需要持续更新。

或者是否有任何替代方法来检测窗口移动(在另一个应用程序中)?实际上我只需要拖动的准确开始和结束时间。介于两者之间,我真的不在乎。kAXWindowMovedNotification 报告开始时间太晚。

Mic*_*ley 6

使用 Accessibility API 真的不可能做到这一点。AXWIndowMoved仅在窗口完成移动后发送通知。

此外,轮询窗口kAXPositionAttribute也不起作用。在被拖动时,窗口会报告其先前的位置,直到窗口完成移动。

CGWindowListCopyWindowInfo但是,在拖动过程中会返回窗口的位置。不幸的是,没有与此相关的通知机制,因此您必须定期调用此函数以检测任何更改。显然,以这种方式进行轮询比接收通知占用更多 CPU。

您可能能够减少轮询的一种方法是使用CGEventTapCreate. 您可以检查kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent事件字段以找到鼠标按下事件的目标窗口,然后在鼠标移动事件上轮询该窗口的位置。如果您检测到更改,您将开始拖动,并在鼠标抬起事件时结束。

当然,这不适用于检测由其他操作(例如,按下缩放按钮,窗口以编程方式移动)引起的窗口位置更改。它也无法在鼠标开始移动之前检测到拖动,因此如果用户在移动之前按住鼠标按钮一段时间,您将检测到拖动延迟。

为完整起见,如果您针对特定应用程序,则可以使用mach_inject检测窗口移动。您绝对不应该发布执行此操作的代码,因为它可能会导致目标应用程序崩溃,并且可能无法在诸如 iTunes 和 DVD 播放器等不允许您附加调试器的应用程序上运行。

为此,您需要注入一个在目标应用程序中注册NSWindowWillMoveNotification和的函数,NSWindowDidMoveNotification然后将它们发送回您的应用程序,可能使用分布式通知。

选择是你的,而且是你一个人的选择。祝你好运。