[Regression] How to make AcceptFileDrop with Aliases work again?

So, with older RS & Xojo versions, it was possible to accept Alias files to be dropped onto windows and controls. I used the “special/any” filetype for that.

Now, with 2019r3, Xojo appears to resolve them on its own.

That may be convenient for the lazy and unexperienced programmers who forgot to handle Aliases, but it’s kind of deadly for my range of tools that explicitly need to know when an Alias gets dropped on them.

Is there a way to get the old behavior back, so that I always get the “True” item, and I can then test whether it’s an Alias and resolve it myself?

This is kind of a two part question in some ways

  1. getting ONLY aliases reported and accepted as aliases
  2. how to NOT resolve the alias

As for #1 in theory a file type with the macOS type set to ‘alis’ should be an alias
At least according to https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
But something about the matching is wrong and if you ONLY fill in the macOS type every file matches as though ANY extension, mime type, etc is what you asked for

#2 may be entirely in the Xojo framework and possibly if #1 can be sorted out then #2 may be a bug ???
Not knowing what OS api they’re using it could be that they do not get the chance to tell the OS NOT to resolve it ?

A “alis” type would only be needed if I weren’t able to drop an Alias. But I can.

And even if I added a filetype for Mac Type “alis”, with UTI com.apple.alias-file, it still lets me drop any kind of file, so the filtering has no affect on Aliases.

In the past, using AcceptRawDataDrop ("public.data") would help in similar situations, but now, even though the control accepts the alias, the Framework appears to resolve it without giving me a chance to prevent it.

Turns out someone else has already reported this: <https://xojo.com/issue/57966>

This is a regression, and those should have top priority in bug fixing, over any new features. When it breaks existing apps, without a work-around, that’s much worse than not having a new feature. Of course, Xojo already has our money, and we can certainly not get it back because of regressions (I wish that was a law, though).

As usual, this is the difference between laws and good sense. A lot of people would do things when it’s otherwise forbidden rather than just because it’s more appropriate.

Have you checked in the various DragItem’s RawData if there’s a trace of the alias details?

Good idea!

Here’s the code I tried:

dim furl as String = obj.RawData("public.file-url")
dim f as FolderItem = GetTrueFolderItem (furl, FolderItem.PathTypeURL)

When I build with an older Xojo version (RS 2012, in fact), I get the correct path to the Alias in the “furl” string.

With Xojo 2019r3, though, I get a file ID (“file:///.file/id=6571367.1024526”), and when I resolve that with the GetTrueFolderItem call, I end up getting the target. But I suspect that this is a bug in GetTrueFolderItem, because the File ID does seem to be the one for the Alias, not the target. And when I look at the properties of “f” in the Debugger, there is some nonsense in it: Alias is false, NativePath points to the Target, but Type says “Alias” - although the target is certainly no an Alias. There’s clearly something wrong there, too.

I’ll have to look further into this. If it’s the right file ID, I can solve this with declares, probably.

Thanks for suggesting that method, I had totally forgotten about the fact that RawData contains the original Pasteboard data.

Alright, with the helpful hint from Arnaud I figured out a work-around:

In your DropObject event handler, instead of this code:

dim f as FolderItem = obj.FolderItem // gives nil if there's no FolderItem

You’ll need this code:

dim f as FolderItem
dim furl as String = obj.RawData("public.file-url")
if furl <> "" then
  declare function NSClassFromString lib "Cocoa" (name as CFStringRef) as Ptr
  declare function URLWithString lib "Cocoa" selector "URLWithString:" (cls as Ptr, url as CFStringRef) as Ptr
  declare function NSURLPath lib "Cocoa" selector "path" (obj as Ptr) as CFStringRef
  dim urlRef as Ptr = URLWithString (NSClassFromString("NSURL"), furl)
  if urlRef <> nil then
    dim path as String = NSURLPath (urlRef)
    f = GetTrueFolderItem (path, FolderItem.PathTypeNative)
  end if
end if

Note that while GetTrueFolderItem works correctly with native paths for a Alias file, it doesn’t work correctly when passing a file URL instead (then it resolves the Alias, which is incorrect behavior). See also this related report from 9 years ago: <https://xojo.com/issue/12362>

You’re welcome. Glad it was finally doable and the framework doesn’t resolve or strip out these raw data as well.
Thank you for sharing your code; a useful reference as long as the bug isn’t fixed.

Are you seeing this same behavior with the new constructor?

http://documentation.xojo.com/api/files/folderitem.html.Constructor(path_as_String,_pathMode_as_FolderItem.PathModes,_followAlias_as_Boolean_%3D_true)

Sorry, no, because I’m not using the new APIs yet. Does it work for you, Greg?