Repository navigation
fix(macos): convert the file a Finder alias points to - #551
Conversation
Dropping a Finder alias on the donut, or picking one in Finder, sent the alias file itself to Filee, which reported it as unsupported. Windows already follows .lnk shortcuts (KnifeLemon#159); macOS now does the same through CFURLCreateBookmarkDataFromFile / CFURLCreateByResolvingBookmarkData. Resolution never shows UI or mounts a volume, so a drag never waits on a server. A broken alias, or a file that isn't an alias, stays as it is. The resolved path is NFC so it matches dropped paths ("보고서" names). Co-Authored-By: Claude <noreply@anthropic.com>
|
Hi @KnifeLemon, thanks for Filee! This PR is small and self-contained (macOS only, no UI strings, tests mirror I've been comparing Filee on macOS with other Mac file utilities and would like to keep contributing. Below is what I'd propose, roughly in order. Could you tell me which of these you'd welcome, so I open an issue with a plan first for the bigger ones (as in #524) and don't send PRs you don't want? macOS
Small wins from open issues New features Thanks again! |
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks @mendax-iitm, and welcome! This fills the gap IPlatformServices called out, using only CoreFoundation and no Automation permission. Resolving without UI or mounting is the right call for something a drag waits on, and the tests mirror WindowsShortcutTests closely. A few things before it goes in:
- Please try a real drag. The tests call
ShortcutTargetandResolveShortcutsdirectly. The point of the change is what arrives through Avalonia's drop (DraggedFiles.Localon the donut and the Home drop zone) plusRadialController.ShowForFilesfor the Finder selection shortcut and the Services menu. Could you drag a file alias, a folder alias and a broken alias from Finder onto the donut, and use the selection shortcut on an alias, and say what you saw? NativeMethods.CreateAliasreleases the error twice whenCFURLCreateBookmarkDatafails.Release(error)runs right after the call, and again in theif (data == 0)block on the sameCFErrorRef, which crashes the test host instead of throwing theIOException. Release it once.- Every dropped path is opened to look for a bookmark. Windows only reads files ending in
.lnk. HereCFURLCreateBookmarkDataFromFileruns for every path, twice per drag (DragEnter, thenDrop) and on the UI thread, so a drop of a few hundred photos (or files on a slow network share) pays for it before the donut reacts. CheckingkCFURLIsAliasFileKeyfirst withCFURLCopyResourcePropertyForKey(metadata only) and calling the bookmark APIs only when it's true would keep non-aliases free. - An alias whose original is in the Trash. Bookmarks follow a moved file, so such an alias may resolve into
~/.Trash, and Filee would convert the trashed file and save the result inside the Trash, where nobody will find it. Could you check, and if so, treat a target inside a Trash folder (~/.Trash,/Volumes/*/.Trashes) as broken?
Once those are done it's ready to merge when CI is green.
|
Thanks for the list, and for offering to plan first. Here's where things stand:
First, though, the points in the review on this PR. Once those are in, it's ready to merge. |
…irst, Trash targets broken - CreateAlias released the CFErrorRef twice when CFURLCreateBookmarkData failed. - Check kCFURLIsAliasFileKey (metadata only) before reading a bookmark, so ordinary dropped files never open on the UI thread. - A bookmark follows its file into ~/.Trash or a volume's .Trashes; treat such a target as broken instead of converting into the Trash.
|
Thanks for the careful review. All four points are addressed in 23b17d1:
|
KnifeLemon
left a comment
There was a problem hiding this comment.
Thanks @mendax-iitm, 23b17d1 covers all four. The drag results are what we were after. The error is now released once, with a test for the missing-target case. Ordinary files stop at the kCFURLIsAliasFileKey check before any bookmark call, and a target in ~/.Trash or a volume's .Trashes counts as broken. The Finder selection shortcut goes through the same ResolveShortcuts as the drop, so a separate run there isn't needed. It can be merged once CI is green.
What does this change?
Finder aliases dropped on the donut (or selected in Finder) now convert the file they point to, the way Windows already follows
.lnkshortcuts (#159). Before, the alias file itself reached Filee and was reported as unsupported;IPlatformServices.ShortcutTargetnoted that macOS aliases "aren't followed yet".MacOSPlatformServices.ShortcutTarget→NativeMethods.AliasTarget, usingCFURLCreateBookmarkDataFromFile+CFURLCreateByResolvingBookmarkData(CoreFoundation only, no Finder Automation permission needed).kCFURLBookmarkResolutionWithoutUIMask | WithoutMountingMask, so a drag never waits on a dialog or a network volume. A broken alias, or a file that isn't an alias, returns null and stays as it is (same contract as Windows).ResolveShortcutswould miss.NativeMethods.CreateAliaswrites real alias files for the tests (likeShellLinks.Createon Windows).No UI strings, no new dependencies.
Type of change
How was it tested?
dotnet format --verify-no-changesdotnet test—Filee.Platform.Tests(80 passed, 27 skipped for other OSes, including the 2 newMacOSAliasTests) andFilee.Core.Tests(602 passed) on macOS 27 arm64. The new tests mirrorWindowsShortcutTests: file, folder, broken alias, non-alias, missing path, and an alias dropped together with its target.Checklist
src/Filee.App/Assets/i18n/*.jsonfiles (none added)THIRD-PARTY-NOTICES.md(none)