AIR workarounds: drag and drop
This post, the 1st of many, concerns differences in drag and drop functionality in AIR versus just Flex (in a browser or other wrapper). One of a few bug reports associated with these differences can be found here. If this has affected you, please vote on it.
The core issue from my perspective was that components which already support drag and drop end up using the operating systems native drag and drop behavior. So say you built 2 tile lists and wanted to drag tiles from one to the other. In Flex, you get a preview of the tile while it’s being dragged and indicator icons without having to write much code at all. Once that same bit is run in AIR, you lose the Flex indicator icons in favor of the native system’s indicators and lose the tile preview unless you create your own drag proxy. If you want to specify the alpha for a drag proxy, you’re now out of luck. Also, if you have written your own methods for dragOver and/or dragEnter, you’ll find some inconsistancies with the behavior here too. I was most annoyed to find that the DragManager.showFeedback method wasn’t working correctly. By my estimate, in AIR this call only works the first time and subsequent calls are ignored. That’s clearly bad news if you have complicated business rules attempting to control regions which allow for drag-drop and others which do not. I consider this a pretty big bug.
So what we really need is a way to tell AIR that we’d like to use DragManager or that we’d like to use NativeDragManager as opposed to being stuck with native drag functionality. I’m sure if we all hold our breath long enough, this will all be addressed in a future sdk release. However, waiting sucks and is often not an option. Ok then, so maybe we can subclass or monkeypatch something, but what… where does the logic that should make the distinction go? Take a look at mx.managers.SystemManager. There’s a mx_internal method in there called docFrameHandler. It’s basically forcing NativeDragManager down your throat when you make an AIR app. See this line:
dragManagerClass = Class(getDefinitionByName("mx.managers::NativeDragManagerImpl"));
Change it to read the following:
dragManagerClass = Class(getDefinitionByName("mx.managers::NativeDragManagerImpl"));
This will force it to stop using the native drag and drop, thus problem solved… sort of. What if you have a need to use both drag and drop and natvie drag and drop. Well, that’s a tad more complicated.
Rather than going into what all needs to be changed, I’ll instead make a very happy announcement. Andrew Westberg of Flex Junk has been all over this one for a while. I was digging through the latest Flex sdk pulling my hair out when I found this post of his. Without it, I’d probably still be digging. As his post mentions, he has everything you need on google code. Good man, Andrew! Just checkout everything from the svn, grab his src/mx folder containing the patched classes, and toss it in your source folder. Now you’re patched. He’s commented the changes so you can see what all was needed. I’d recommend at least seeing what he’s done to SystemManager’s docFrameHandler method, allowing for drag/drop versus native drag/drop behaviors conditionally.
Once again, I’d like to thank Andrew for being on top of this one. I also would like to again encourage anyone affected by this vote for the bug.


May 20th, 2009 at 3:55 pm
David,
I’m glad to see I’m not the only one who see’s Adobe’s huge gap in functionality when it comes to DragManagers in AIR. More visibility to this issue can only help matters.