Skip to content

fix(macos): match mode applications when Finder shows extensions - #66

Merged
kitlangton merged 1 commit into
anomalyco:mainfrom
skidlucas:fix/mode-application-bundle-extension
Sep 3, 2026
Merged

fix(macos): match mode applications when Finder shows extensions#66
kitlangton merged 1 commit into
anomalyco:mainfrom
skidlucas:fix/mode-application-bundle-extension

Conversation

@skidlucas

@skidlucas skidlucas commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Disclaimer : this has been heavily generated by IA, I am not familiar with Rust but I proof read everything and made sure everything passed.

I found a workaround by closing Hex, removing the ".app" in the settings.json and reopening Hex so this is not urgent.

Problem

A dictation mode that activates on an application never matches when Finder's "Show all filename extensions" preference is enabled. Every dictation falls back to the Global mode.

The application picker names an app with NSFileManager.displayNameAtPath, which honors that Finder preference and returns Ghostty.app. Mode selection compares that stored name with the frontmost application's NSRunningApplication.localizedName, which is always Ghostty. The comparison in context.rs is a plain case-insensitive equality, so Ghostty.app never equals Ghostty.

Observed on 2.1.13 with AppleShowAllExtensions = 1: settings.json held "applications": ["Ghostty.app", "Slack.app", ...], live.ndjson reported "application": "Ghostty", and process.log logged profile="Global" for every dictation.

The existing finder_has_native_picker_metadata_and_an_icon test also fails on such a machine before this change, because metadata returns Finder.app.

Fix

  • application_catalog::metadata strips a trailing .app from the picker name, so new activations are stored the way the foreground context reports them.
  • context::application_names_equal strips the suffix on both sides, so activations written by either form keep matching. The helper is shared.
  • app_settings::load_from rewrites already persisted .app activations on load and persists the migration like the existing microphone and transcription migrations, so affected users are repaired without touching settings.json by hand.
  • docs/features/README.md records the matching rule, the checks, and the released-version defect with its workaround, per AGENTS.md.

Checks

  • cargo fmt --all --check
  • cargo test --locked --bin voice-control: 439 passed, 0 failed (macOS 26, Xcode 26.6, Apple M4 Pro)
  • cargo clippy --locked --bin voice-control --tests -- -D warnings
  • git diff --check

New tests: application_matching_ignores_finder_bundle_extensions, bundle_extension_stripping_only_removes_a_trailing_suffix, loading_strips_finder_bundle_extensions_from_mode_applications.

Not covered: the picker UI still compares mode.applications.contains(&name) with the catalog name; both sides are now suffix-free, but no GPUI test drives the picker.

The application picker names an app with NSFileManager.displayNameAtPath,
which honors Finder's "Show all filename extensions" preference and returns
"Ghostty.app", while mode selection compares it with the frontmost
application's localizedName, "Ghostty". Modes saved on such a Mac never
activated and every dictation fell back to Global.

Strip the bundle extension when the picker builds the catalog entry and on
both sides of the application comparison, and rewrite already persisted
activations on settings load like the other migrations. Record the rule and
the released-version defect in the feature map.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@kitlangton
kitlangton merged commit 0dfb4b0 into anomalyco:main Sep 3, 2026
@kitlangton

Copy link
Copy Markdown
Collaborator

Merged, thanks for tracking this down and including the settings migration. I verified 439 passing tests (9 opt-in tests skipped), all 12 keyboard-layout regression scenarios, formatting, and Clippy across all targets and features.

The fix is on main and will be included in a future app release. I did not run a live Finder-preference/picker interaction test.

@skidlucas
skidlucas deleted the fix/mode-application-bundle-extension branch September 3, 2026 16:11
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.

2 participants