Skip to content

fix(bundle): list Markpad in Finder's Open With for .mdown and .mkd - #1027

Merged
PathGao merged 1 commit into
masterfrom
fix/macos-mdown-uti
Oct 24, 2026
Merged

PathGao merged 1 commit into
masterfrom
fix/macos-mdown-uti

Conversation

@PathGao

@PathGao PathGao commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

What this is

After #1019, a macOS build still did not show Markpad in Finder's Open With for .mdown and .mkd files. .md and .markdown were fine. This moves the two extensions into a second file association that macOS matches by extension.

Mechanism

Tauri writes each fileAssociations entry as one CFBundleDocumentTypes item. The Markdown entry has contentTypes, so it gets LSItemContentTypes, and when that key is present macOS ignores CFBundleTypeExtensions. The entry only claims net.daringfireball.markdown and public.markdown.

The system declares net.daringfireball.markdown itself (CoreTypes, exported) with the tags .md, .markdown and text/markdown. .mdown and .mkd are not in it, so macOS gives them dynamic UTIs (dyn.ah62d4rv4ge8043dts71a, dyn.ah62d4rv4ge80445e) and no association claimed those.

I first tried the usual fix, a UTImportedTypeDeclarations entry for net.daringfireball.markdown with all four extensions, merged in through src-tauri/Info.plist. Tauri has no config key for an imported type, only exportedType. It did not work: Launch Services registered the import as inactive imported, because the system's exported declaration wins. Xcode's and Claude's imports of the same type are inactive the same way. UTType(filenameExtension: "mdown") stayed dynamic and Open With did not change. Exporting the type would mean claiming a type Markpad does not own, and the system export would still win.

Fix

fileAssociations now has two entries. md and markdown keep the content types and MIME type. mdown and mkd go in an entry with no contentTypes and no mimeType. Tauri infers no UTI for those extensions, so it writes a document type with only CFBundleTypeExtensions, and Launch Services claims their dynamic UTIs by extension.

Other platforms produce the same output as before. The NSIS template runs APP_ASSOCIATE per extension with the association's name and description, and both entries use Markdown File, the ProgID hooks.nsi registers under. Linux .desktop files list only MIME types, and text/markdown is still listed once.

Tests

scripts/fileAssociations.test.ts adds one test: an association with contentTypes lists only md and markdown, any other association has no mimeType, and every association is named Markdown File. With the old tauri.conf.json it fails (actual has mdown and mkd in the content-typed entry). With this one it passes. The existing test still pins the full extension list to MARKDOWN_LINK_EXTENSIONS minus txt.

Verification

On macOS 27.0.1, I built --bundles app with a separate identifier (dev.pathgao.markpad.utitest), registered it with lsregister -f, and asked NSWorkspace.urlsForApplications(toOpen:) for newly created files. Launch Services does not list apps under /private/tmp in Open With, even for .md, so I copied the bundle to a folder in my home directory first.

Before (master):

CFBundleDocumentTypes: [{"CFBundleTypeExtensions":["md","markdown","mdown","mkd"],"LSItemContentTypes":["net.daringfireball.markdown","public.markdown"],...}]
claimed UTIs:  net.daringfireball.markdown, public.markdown
before.mdown -> ["Cursor.app"]
before.mkd   -> ["Cursor.app"]

Imported type tried and dropped:

CoreTypes         active  apple-internal  exported  core  trusted   .md, .markdown, text/markdown
Markpad UTI Test  inactive  imported  untrusted                     .md, .markdown, .mdown, .mkd, text/markdown
UTType(filenameExtension: "mdown") -> dyn.ah62d4rv4ge8043dts71a
imp.mdown -> ["Cursor.app"]

After (this branch):

CFBundleDocumentTypes: [{"CFBundleTypeExtensions":["md","markdown"],"LSItemContentTypes":["public.markdown","net.daringfireball.markdown"],...},
                        {"CFBundleTypeExtensions":["mdown","mkd"],"CFBundleTypeName":"Markdown File","CFBundleTypeRole":"Editor",...}]
claimed UTIs:  net.daringfireball.markdown, dyn.ah62d4rv4ge8043dts71a (.mdown), dyn.ah62d4rv4ge80445e (.mkd), public.markdown
final.mdown -> ["Cursor.app", "Markpad UTI Test.app"]
final.mkd   -> ["Cursor.app", "Markpad UTI Test.app"]

mdls still reports the dynamic UTI for .mdown and .mkd. That is expected, because the file type does not change. Markpad now claims it.

npm run check, npm test, npx vitest run, cargo fmt --check, cargo clippy --all-targets -D warnings and cargo test pass. npm audit reports the same three dev-dependency findings as master (--omit=dev: 0).

Not verified: I did not click through Finder's Open With menu by hand. I checked the same Launch Services query it relies on. I also did not build the Windows or Linux installers. Their output is unchanged by reading the bundler templates.

#1019 added both extensions to the Markdown file association, but on macOS
an association with LSItemContentTypes ignores CFBundleTypeExtensions. The
system's net.daringfireball.markdown only tags .md and .markdown, so .mdown
and .mkd get dynamic UTIs that no association claimed.

Move them to a second association with no content or MIME type, which Tauri
emits as an extension-only document type. Windows registers the same ProgID
and Linux the same MIME type as before.
@PathGao
PathGao merged commit 94947ce into master Oct 24, 2026
3 of 4 checks passed
@PathGao
PathGao deleted the fix/macos-mdown-uti branch October 24, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant