feat(app): first-launch prompt to set Open CAD Studio as default for .dwg/.dxf

On the first launch that hasn't answered it yet, the app shows a small
dialog offering to become the default handler for .dwg and .dxf files.
The choice is persisted (default_assoc_prompted) so the prompt never
reappears.

The platform plumbing lives in io/file_association.rs:
  * Windows — opens the OS's own per-app default-programs dialog via
    IApplicationAssociationRegistrationUI::LaunchAdvancedAssociationUI,
    passing the "Open CAD Studio" RegisteredApplications name the MSI
    registers. Modern Windows guards the actual default behind a
    UserChoice hash, so this is the supported consent path.
  * Linux — xdg-mime default against the installed .desktop file, whose
    MimeType entries already cover image/vnd.dwg and image/vnd.dxf.
  * macOS — LSSetDefaultRoleHandlerForContentType binds the DWG/DXF UTIs
    declared in Info.plist to the app bundle id.

The work runs on a dedicated thread (the Windows dialog is modal) with
the result delivered back through a oneshot channel and surfaced in the
command line.

https://claude.ai/code/session_01DFVSKgViFaxEjZD2KsTdtt
This commit is contained in:
Claude 2026-06-12 07:50:41 +00:00
commit a7d85fe148
No known key found for this signature in database
7 changed files with 457 additions and 3 deletions

View file

@ -33,7 +33,10 @@ truck-shapeops = "0.4"
rustc-hash = "2"
[target.'cfg(target_os = "windows")'.dependencies]
windows-sys = { version = "0.61", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
# Win32_System_Com is needed for the COM calls behind "Set as default app"
# (CoCreateInstance → IApplicationAssociationRegistrationUI), which opens
# Windows' own per-app default-programs dialog.
windows-sys = { version = "0.61", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging", "Win32_System_Com"] }
[patch.crates-io]
# Tracks HakanSeven12/acadrust main, which carries the hatch