Rank Start Menu shortcuts so the primary launcher wins - #2
Open
rodchristiansen wants to merge 1 commit into
Open
Rank Start Menu shortcuts so the primary launcher wins#2rodchristiansen wants to merge 1 commit into
rodchristiansen wants to merge 1 commit into
Conversation
Resolving an app took the first Start Menu shortcut that matched, in
directory enumeration order. That order is alphabetical, and an app's
uninstaller, documentation link, safe-mode variant or reduced edition
frequently sorts ahead of the launcher itself, so those got pinned
instead:
Uninstall <app> beat <app> (U before the app's initial)
<app> Apprentice beat <app> Education
<app> in Safe Mode beat <app>
<app> Documentation beat <app>
Firefox Private Browsing beat Firefox
The last three are one comparison: the unwanted name continues with a
space (0x20) where the launcher continues with the dot (0x2E) of its
extension, and space sorts first.
Matching was also a bare case-insensitive substring test, so the "Code"
alias of Visual Studio Code matched Adobe Media En-code-r and pinned an
unrelated application.
ShortcutRanker scores a candidate on how well it matches -- exact, at the
start, or on a word boundary -- then demotes shortcuts whose name carries
a marker word (uninstall, documentation, safe mode, apprentice, trial and
similar) or whose target opens a document rather than a program. Ties go
to the shortest name, which is the launcher whenever a variant is a
suffix. Penalties are sized so a demoted shortcut can never outrank a
primary one.
Matching now requires a word boundary at the leading edge, so an alias no
longer matches inside a longer word. A trailing digit is still allowed so
a version number running straight on ("Photoshop9") keeps matching. Where
this finds nothing it now resolves nothing rather than falling back to a
loose substring hit -- pinning no app is better than pinning the wrong one.
An exact name match is returned as-is, so asking for a variant by its full
name still works and no app becomes unpinnable.
AppResolver applies the ranking in both paths: the known-app lookup, which
returned the first file matching any alias, and the broader search, whose
confidence score was flat across all non-exact matches. Reading a
shortcut's target is left behind a pre-filter so the COM call only happens
for candidates that could plausibly win.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolving an app took the first Start Menu shortcut that matched, in directory enumeration order. That order is alphabetical, and an app's uninstaller, documentation link, safe-mode variant or reduced edition frequently sorts ahead of the launcher itself — so those got pinned instead.
Uninstall ZBrush …ZBrush …Rhino … in Safe ModeRhino …Nuke … DocumentationNuke …Houdini Apprentice …Houdini FX/Education …Firefox Private BrowsingFirefoxAdobe Media Encoder …Visual Studio CodeThe Rhino/Nuke/Firefox rows are one comparison: the unwanted name continues with a space (0x20) where the launcher continues with the dot (0x2E) of its extension, and space sorts first.
The last row is a second, separate defect. Matching was a bare case-insensitive substring test, so the
Codealias of Visual Studio Code matched Adobe Media Encoder and pinned an unrelated application.What changed
ShortcutRankerscores a candidate on match quality — exact, at the start, or on a word boundary — then demotes shortcuts thatuninstall,documentation,safe mode,apprentice,trial, …), matched as whole words soAssistdoes not fire onAssistant; or.html,.chm,.url, …), which catches a documentation shortcut whose name gives nothing away.Ties go to the shortest name — the launcher, whenever a variant is a suffix of it. Penalties are sized so a demoted shortcut can never outrank a primary one; there is a test asserting that property directly rather than trusting the arithmetic.
Matching now requires a word boundary at the leading edge, so an alias no longer matches inside a longer word. A trailing digit is still allowed, so a version number running straight on (
Photoshop9) keeps matching. Where this finds nothing, it now resolves nothing rather than falling back to a loose substring hit — pinning no app is better than pinning the wrong one.An exact name match is returned as-is, so asking for a variant by its full name still works and no app becomes unpinnable.
AppResolverapplies the ranking in both paths — the known-app lookup, which returned the first file matching any alias, and the broader search, whose confidence was flat across all non-exact matches. Reading a shortcut's target stays behind a pre-filter, so the COM call only happens for candidates that could plausibly win.Verification
15 new unit tests, one per reported failure plus the boundary rules; 38 pass in total.
Confirmed against a real Start Menu, resolving
Firefoxwhere both shortcuts exist:Uninstall GoandUninstall Node.jslikewise drop below their real launchers infindoutput.