Question

Is there any other method available to get continuous updates instead of kAXWindowMovedNotification (accessibility api - listened to via AXObserver) that just sends the notification much later than when dragging started? I need continuous updates if at all possible.

Or are there any alternative methods to detect window movement (in another app)? Actually I only need accurate start and end times of the drag. In between I don't really care. kAXWindowMovedNotification reports the start time too late.

Was it helpful?

Solution

This isn't really possible using the Accessibility API. AXWIndowMoved only sends a notification after the window has finished moving.

In addition, polling the window for its kAXPositionAttribute won't work either. While being dragged, the window will report its previous position until the window has finished moving.

CGWindowListCopyWindowInfo, however, does return the position of the windows during a drag. Unfortunately, there's no notification mechanism tied to this, so you'll have to call this function at regular intervals to detect any changes. Polling in this manner is, obviously, a lot more CPU-intensive than receiving a notification.

One way you might be able to cut down on polling is by listening for mouse events using CGEventTapCreate. You may be able to check the kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent event field to find the window being targeted for a mouse down event, and then poll that window's position on a mouse moved event. If you detect a change, you have the start of your drag, and it ends on a mouse up event.

Of course, this won't work to detect changes to window position caused by other actions (e.g., pressing the zoom button, the window getting moved programmatically). It also can't detect the drag until the mouse starts moving, so if the user holds the mouse button down for a while before moving, you'll be detecting the drag late.

For the sake of completeness, if you are targeting a specific application, it is possible to detect window movement using mach_inject. You definitely should not ship code that does this, as it may cause the targeted application to crash, and may not work on applications like iTunes and DVD Player, which do not allow you to attach a debugger.

To do this, you would inject a function that registers for NSWindowWillMoveNotification and and NSWindowDidMoveNotification in the target app, and then send them back to your app, perhaps using distributed notifications.

The choices are yours, and yours alone. Good luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top