Search code examples
macoscocoadrag-and-dropmacos-carbonnsevent

Register for global file drag events in Cocoa


I'm trying to be notified when a OS X user is dragging any file in OS X, not only in my app.

My current approach was using addGlobalMonitorForEventsMatchingMask:handler: on NSEvent, as follows:

[NSEvent addGlobalMonitorForEventsMatchingMask:NSLeftMouseDraggedMask handler:^(NSEvent* event) {
    NSPasteboard* pb = [NSPasteboard pasteboardWithName:NSDragPboard];
    NSLog(@"%@", [pb propertyListForType:NSFilenamesPboardType]);
}];

This works partially - the handler is being called when I start dragging a file from my desktop or Finder, however it also is being called when I perform every other operation that contains a left-mouse-drag, e.g. moving a window. The issue is that the NSDragPboard still seems to contain the latest dragged file URL e.g. when I let off the file and start moving a window, which makes it hard to distinguish between these operations.

TL;DR - I am interested in file drag operations system-wide. I do not need any information about the dragged file itself, just the information that a file drag operation has been started or stopped. I would appreciate any hint to a possible solution for this question.


Solution

  • After having talked to Apple DTS, this is most likely a bug. I have filed rdar://25892115 for this issue. There currently seems to be no way to solve my original question with the given API.

    To solve my problem, I am now using the Accessibility API to figure out if the item below the cursor is a file (kAXFilenameAttribute is not NULL).