4

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

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

4

1 回答 1

6

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

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

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

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

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

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

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

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

于 2013-03-22T21:36:19.020 回答