【问题标题】:AXWindowMoved (via AXObserver) - continuous updates?AXWindowMoved(通过 AXObserver) - 持续更新?
【发布时间】:2013-02-24 14:04:30
【问题描述】:
是否有任何其他方法可用于获取持续更新,而不是 kAXWindowMovedNotification(可访问性 api - 通过 AXObserver 侦听),它发送通知的时间要比拖动开始时晚得多?如果可能的话,我需要持续更新。
或者是否有任何替代方法来检测窗口移动(在另一个应用程序中)?实际上我只需要准确的拖动开始和结束时间。在这之间,我真的不在乎。 kAXWindowMovedNotification 报告开始时间太晚。
【问题讨论】:
标签:
objective-c
xcode
cocoa
nswindow
accessibility-api
【解决方案1】:
这在使用 Accessibility API 时是不可能的。 AXWIndowMoved 只发送通知after the window has finished moving。
此外,轮询窗口的kAXPositionAttribute 也不起作用。在被拖动时,窗口会报告它之前的位置,直到窗口完成移动。
CGWindowListCopyWindowInfo 但是,在拖动过程中确实会返回窗口的位置。不幸的是,没有与此相关的通知机制,因此您必须定期调用此函数以检测任何更改。显然,以这种方式轮询比接收通知更占用 CPU。
您可以减少轮询的一种方法是使用CGEventTapCreate 监听鼠标事件。您可以检查kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent 事件字段以找到针对鼠标按下事件的窗口,然后在鼠标移动事件上轮询该窗口的位置。如果您检测到更改,您将开始拖动,并在鼠标向上事件时结束。
当然,这不能检测由其他操作引起的窗口位置变化(例如,按下缩放按钮,窗口以编程方式移动)。在鼠标开始移动之前它也无法检测到拖动,因此如果用户在移动前按住鼠标按钮一段时间,您将延迟检测到拖动。
为了完整起见,如果您针对特定应用程序,可以使用mach_inject 检测窗口移动。您绝对不应发布执行此操作的代码,因为它可能导致目标应用程序崩溃,并且可能无法在不允许您附加调试器的 iTunes 和 DVD 播放器等应用程序上运行。
为此,您需要在目标应用中注入一个注册NSWindowWillMoveNotification 和NSWindowDidMoveNotification 的函数,然后将它们发送回您的应用,可能使用分布式通知。
选择权在你,而且只有你自己。祝你好运。