Skip to content

feat: native Windows file, folder and drive icons - #116

Merged
nextestudios merged 1 commit into
mainfrom
feature/24-shell-icons
Sep 27, 2026
Merged

nextestudios merged 1 commit into
mainfrom
feature/24-shell-icons

Conversation

@nextestudios

Copy link
Copy Markdown
Owner

Summary

  • Core: IIconProvider + IconRequest.For(entry, specialFolders). Common files and every archive entry are keyed by extension (never touch the disk); folders share one generic key; drives, known folders (also when browsed as normal directories) and .exe/.ico files are keyed by path. LruCache<TKey,TValue> for a bounded cache. Core stays free of Windows deps.
  • Infrastructure.Windows: ShellIconProvider uses SHGetFileInfo (SHGFI_USEFILEATTRIBUTES for extension/folder requests) and SHGetImageList (IImageList::GetIcon via the vtable, no COM interop types), converts the HICON to premultiplied BGRA, and runs on a dedicated STA thread; the UI thread never waits. Chooses the 16/32/48/256 list by pixel size and falls back to 48 px when a jumbo icon has no large art. Requests cancelled before their turn are skipped.
  • App: IconLoader shows a Segoe Fluent/MDL2 glyph immediately and swaps in the shell icon when it arrives; identical in-flight requests are shared; recycled containers cancel their request; LRU cache (512 entries) keyed by type + pixel size, cleared when XamlRoot.RasterizationScale changes (rows are rebuilt at the new size). Used by Home, Browser, Picker and archive views (same list). The lock emoji became text; no emoji remain in list rows.
  • Recycle Bin icon: there is no Recycle Bin location in the UI yet (feat: add the Recycle Bin as a browsable location #26); it can use the same provider when it lands.

Testing

  • CI unit tests: IconRequestTests (extension vs. path keys, archive entries never hit the disk, blocked rows get no icon; LRU eviction).
  • CI Windows integration: ShellIconIntegrationTests checks a .txt, a folder and the system drive return a non-empty image at 32 and 64 px.
  • Manual (added to docs/TESTING.md): known-folder/drive-type icons, per-type icons, archive view, 10,000-item folder scrolling, 1080p/4K/handheld scaling and moving between monitors, focus/marking legibility over icons.

Closes #24

🤖 Generated with Claude Code

@nextestudios
nextestudios force-pushed the feature/24-shell-icons branch 4 times, most recently from 0810ee2 to db68f04 Compare September 27, 2026 03:00
- IIconProvider contract and IconRequest in Core: common types are keyed by
  extension (no disk access, archive entries included); drives, known
  folders and .exe/.ico are keyed by path.
- ShellIconProvider (Infrastructure.Windows) uses SHGetFileInfo and the
  system image lists on a dedicated STA thread; picks the image list for the
  requested pixel size and falls back to 48 px when a jumbo icon has no
  large art. Cancelled requests are skipped.
- IconLoader (App) shows a Segoe Fluent/MDL2 glyph at once, swaps in the
  shell icon when ready, dedupes identical requests, cancels on container
  recycle and keeps a bounded LRU cache keyed by type and pixel size that is
  cleared when the display scale changes.
- No emoji left in the list rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nextestudios
nextestudios merged commit c15ba39 into main Sep 27, 2026
1 check passed
@nextestudios
nextestudios deleted the feature/24-shell-icons branch September 27, 2026 03:04
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.

feat: integrate native Windows file and folder icons

1 participant