feat(stage5): System-Wide Installation of Generated ICC/ICM Profiles #223

Open
opened 2026-09-07 07:13:55 +01:00 by gronod · 0 comments
Owner

Feature Summary & Background

ICCery’s Stage 5 (Verification, Drift Analytics & 3D Gamut) currently produces a high-quality ICC/ICM printer profile via colprof and validates it with profcheck. After successful generation and verification the profile remains only in the working directory / project artefacts folder.

Professional colour-management workflows require the profile to be registered with the host operating system’s colour management subsystem so that:

  • Print dialogs, RIP software, Adobe applications, Affinity, Capture One, GIMP, and other colour-managed applications can discover and select it.
  • The profile appears in the OS colour-management UI (Windows Color Management, macOS ColorSync Utility, Linux colord / GNOME Color).
  • Subsequent verification runs and drift tracking can reference a system-registered profile.

This feature adds an explicit, optional “Install to System” action in Stage 5 that copies (and, where required, registers) the generated profile into the correct platform-specific location with appropriate privilege handling and user feedback.


Proposed Feature Requirements

1. UI Placement & Controls (Stage 5)

After a successful colprof / profcheck run (profile artefact present and verification exit code 0):

  • Add a primary action button in the Stage 5 action row (aligned with existing .btn-md / .btn-lg hierarchy):

    Install Profile to System

  • Button states:

    • Enabled only when a valid .icc / .icm artefact exists on disk and verification has completed successfully.
    • Disabled (with tooltip) when the profile has already been installed in the current session or the artefact is missing.
    • Show a transient “Installing…” spinner / progress state while the copy/registration is in progress.
    • On success: change label temporarily to “Installed ✓” and display a non-blocking success toast containing the final system path.
    • On failure: show a clear error toast with the underlying reason (permissions, path not writable, etc.).
  • Optional secondary control (collapsible Advanced section or Settings preference):

    • “Also open system Colour Management panel after install” (platform-specific deep-link where available).
  • Contextual tooltip:

    Copies the generated ICC/ICM profile into the operating system’s standard colour-profile directory so that print dialogs and colour-managed applications can discover it. Requires elevated privileges on some platforms.

2. Platform-Specific Installation Targets & Behaviour

Windows

  • Target directory: %WINDIR%\System32\spool\drivers\color
    (resolved via GetSystemDirectory / SHGetKnownFolderPathFOLDERID_System + \spool\drivers\color).
  • File extension: .icm (ICCery already produces the correct platform convention).
  • Registration:
    • Prefer the Windows Color Management API (InstallColorProfile / WcsInstallColorProfile) when available so the profile is immediately visible to ICM/WCS.
    • Fallback: simple file copy into the directory (sufficient for most applications).
  • Privilege handling:
    • Attempt the copy/registration with the current user token.
    • If ERROR_ACCESS_DENIED occurs, request elevation via Tauri’s tauri-plugin-shell / Windows UAC prompt (or surface a clear “Run as Administrator required” message with a “Retry with Elevation” button).
  • Collision policy:
    • If a profile of the same filename already exists, offer “Overwrite”, “Rename (append timestamp)”, or “Cancel”.

macOS

  • Preferred user-level location (no elevation required):
    \~/Library/ColorSync/Profiles/
  • Optional system-wide location (requires admin):
    /Library/ColorSync/Profiles/
  • Registration:
    • Use ColorSync framework APIs (ColorSyncProfileCreateWithURL, ColorSyncProfileInstall) where possible so the profile is immediately recognised by ColorSync Utility and applications.
    • Fallback: simple file copy.
  • File extension: .icc.
  • After successful install, optionally launch ColorSync Utility focused on the Profiles list (open -a "ColorSync Utility").

Linux

  • Preferred user-level location (no elevation):
    \~/.local/share/icc/ or \~/.color/icc/ (both are recognised by colord and most desktop environments).
  • System-wide locations (require root / polkit):
    /usr/share/color/icc/ or /usr/local/share/color/icc/.
  • Registration with colord (recommended):
    • Prefer colormgr import-profile <path> (or the D-Bus interface org.freedesktop.ColorManager) so the profile is immediately available to GNOME Color, KDE, and applications using colord.
    • Fallback: simple file copy into one of the recognised directories.
  • File extension: .icc.
  • Detect whether colord / colormgr is present; if absent, fall back to pure filesystem copy and inform the user.

3. Backend Implementation (Rust / Tauri)

  • New Tauri command: install_profile_to_system(profile_path: String, options: InstallOptions) -> Result<InstallResult, String>
    • InstallOptions may contain:
      • force_overwrite: bool
      • prefer_system_wide: bool (macOS/Linux)
      • register_with_os: bool (default true)
    • InstallResult returns the final absolute path and a human-readable status message.
  • Cross-platform path resolution utilities (reuse existing platform abstraction patterns used by the raw-print subsystem).
  • Atomic copy where possible (std::fs::copy + rename, or platform equivalents) to avoid partial writes.
  • Thorough error mapping:
    • Permission denied → actionable elevation guidance.
    • Disk full / path too long → clear message.
    • Profile already registered → informative status.
  • Unit tests covering path construction for each OS and mock registration success/failure paths.
  • Integration with the existing artefact-gating system: the command must re-verify that the source profile still exists and matches the expected hash / size before installation.

4. UX & Safety Considerations

  • Never silently overwrite an existing system profile without explicit user confirmation.
  • Always surface the final installed path in the success toast and in the Stage 5 log panel.
  • Preserve the original working-directory copy; the system install is a copy, not a move.
  • Log the installation event (timestamp, source path, destination path, success/failure) for diagnostic purposes (can be stored alongside verification history if desired).
  • Respect the existing “Clean AGPL Boundary” principle: the installation logic lives entirely in the proprietary Rust host, never inside an ArgyllCMS process.

5. Settings & Persistence

  • Add a user preference (Settings → Advanced):
    • “Default install location” (User / System) – remembered across sessions.
    • “Ask before overwriting existing profiles” (default: true).
  • Optionally record the last-installed system path in the project’s metadata so Stage 5 can show “Already installed to …” on subsequent visits.

Acceptance Criteria

  1. After a successful Stage 5 verification the “Install Profile to System” button is enabled and functional on Windows, macOS, and Linux.
  2. On Windows the profile is placed in %WINDIR%\System32\spool\drivers\color (or registered via the Color Management API) and becomes visible in the Windows Color Management control panel.
  3. On macOS the profile appears under \~/Library/ColorSync/Profiles/ (or /Library/ColorSync/Profiles/ when elevated) and is listed in ColorSync Utility.
  4. On Linux the profile is installed to a colord-recognised location and, when colormgr is available, is imported via colord.
  5. Permission / elevation failures produce clear, actionable error messages rather than silent failures.
  6. Filename collisions are handled with an explicit user choice (Overwrite / Rename / Cancel).
  7. The original profile artefact in the working directory remains untouched.
  8. Unit tests cover path resolution and the install command’s success and error paths for all three platforms.
  9. Documentation (README / AGENTS.md) updated with the new Stage 5 capability and platform-specific notes.

Technical Notes & References

  • Windows Color Management API: InstallColorProfile, WcsInstallColorProfile (wingdi / mscms).
  • macOS: ColorSync framework (ColorSyncProfileInstall).
  • Linux: colormgr import-profile / org.freedesktop.ColorManager D-Bus interface; FreeDesktop colour-directory conventions (\~/.local/share/icc, /usr/share/color/icc).
  • Existing ICCery patterns to reuse: platform-aware path handling, artefact verification, Tauri command error mapping, and the standardised button hierarchy introduced in #177.

Out of Scope (for this ticket)

  • Automatic association of the profile with a specific printer device (that can be a follow-up).
  • Batch installation of multiple historical profiles.
  • Uninstall / remove-from-system functionality (can be added later if demand exists).

## Feature Summary & Background ICCery’s Stage 5 (Verification, Drift Analytics & 3D Gamut) currently produces a high-quality ICC/ICM printer profile via `colprof` and validates it with `profcheck`. After successful generation and verification the profile remains only in the working directory / project artefacts folder. Professional colour-management workflows require the profile to be registered with the host operating system’s colour management subsystem so that: * Print dialogs, RIP software, Adobe applications, Affinity, Capture One, GIMP, and other colour-managed applications can discover and select it. * The profile appears in the OS colour-management UI (Windows Color Management, macOS ColorSync Utility, Linux colord / GNOME Color). * Subsequent verification runs and drift tracking can reference a system-registered profile. This feature adds an explicit, optional “Install to System” action in Stage 5 that copies (and, where required, registers) the generated profile into the correct platform-specific location with appropriate privilege handling and user feedback. --- ## Proposed Feature Requirements ### 1. UI Placement & Controls (Stage 5) After a successful `colprof` / `profcheck` run (profile artefact present and verification exit code 0): * Add a primary action button in the Stage 5 action row (aligned with existing `.btn-md` / `.btn-lg` hierarchy): **Install Profile to System** * Button states: * Enabled only when a valid `.icc` / `.icm` artefact exists on disk and verification has completed successfully. * Disabled (with tooltip) when the profile has already been installed in the current session or the artefact is missing. * Show a transient “Installing…” spinner / progress state while the copy/registration is in progress. * On success: change label temporarily to “Installed ✓” and display a non-blocking success toast containing the final system path. * On failure: show a clear error toast with the underlying reason (permissions, path not writable, etc.). * Optional secondary control (collapsible Advanced section or Settings preference): * “Also open system Colour Management panel after install” (platform-specific deep-link where available). * Contextual tooltip: > Copies the generated ICC/ICM profile into the operating system’s standard colour-profile directory so that print dialogs and colour-managed applications can discover it. Requires elevated privileges on some platforms. ### 2. Platform-Specific Installation Targets & Behaviour #### Windows * Target directory: `%WINDIR%\System32\spool\drivers\color` (resolved via `GetSystemDirectory` / `SHGetKnownFolderPath` → `FOLDERID_System` + `\spool\drivers\color`). * File extension: `.icm` (ICCery already produces the correct platform convention). * Registration: * Prefer the Windows Color Management API (`InstallColorProfile` / `WcsInstallColorProfile`) when available so the profile is immediately visible to ICM/WCS. * Fallback: simple file copy into the directory (sufficient for most applications). * Privilege handling: * Attempt the copy/registration with the current user token. * If `ERROR_ACCESS_DENIED` occurs, request elevation via Tauri’s `tauri-plugin-shell` / Windows UAC prompt (or surface a clear “Run as Administrator required” message with a “Retry with Elevation” button). * Collision policy: * If a profile of the same filename already exists, offer “Overwrite”, “Rename (append timestamp)”, or “Cancel”. #### macOS * Preferred user-level location (no elevation required): `\~/Library/ColorSync/Profiles/` * Optional system-wide location (requires admin): `/Library/ColorSync/Profiles/` * Registration: * Use ColorSync framework APIs (`ColorSyncProfileCreateWithURL`, `ColorSyncProfileInstall`) where possible so the profile is immediately recognised by ColorSync Utility and applications. * Fallback: simple file copy. * File extension: `.icc`. * After successful install, optionally launch ColorSync Utility focused on the Profiles list (`open -a "ColorSync Utility"`). #### Linux * Preferred user-level location (no elevation): `\~/.local/share/icc/` or `\~/.color/icc/` (both are recognised by colord and most desktop environments). * System-wide locations (require root / polkit): `/usr/share/color/icc/` or `/usr/local/share/color/icc/`. * Registration with colord (recommended): * Prefer `colormgr import-profile <path>` (or the D-Bus interface `org.freedesktop.ColorManager`) so the profile is immediately available to GNOME Color, KDE, and applications using colord. * Fallback: simple file copy into one of the recognised directories. * File extension: `.icc`. * Detect whether `colord` / `colormgr` is present; if absent, fall back to pure filesystem copy and inform the user. ### 3. Backend Implementation (Rust / Tauri) * New Tauri command: `install_profile_to_system(profile_path: String, options: InstallOptions) -> Result<InstallResult, String>` * `InstallOptions` may contain: * `force_overwrite: bool` * `prefer_system_wide: bool` (macOS/Linux) * `register_with_os: bool` (default true) * `InstallResult` returns the final absolute path and a human-readable status message. * Cross-platform path resolution utilities (reuse existing platform abstraction patterns used by the raw-print subsystem). * Atomic copy where possible (`std::fs::copy` + rename, or platform equivalents) to avoid partial writes. * Thorough error mapping: * Permission denied → actionable elevation guidance. * Disk full / path too long → clear message. * Profile already registered → informative status. * Unit tests covering path construction for each OS and mock registration success/failure paths. * Integration with the existing artefact-gating system: the command must re-verify that the source profile still exists and matches the expected hash / size before installation. ### 4. UX & Safety Considerations * Never silently overwrite an existing system profile without explicit user confirmation. * Always surface the final installed path in the success toast and in the Stage 5 log panel. * Preserve the original working-directory copy; the system install is a copy, not a move. * Log the installation event (timestamp, source path, destination path, success/failure) for diagnostic purposes (can be stored alongside verification history if desired). * Respect the existing “Clean AGPL Boundary” principle: the installation logic lives entirely in the proprietary Rust host, never inside an ArgyllCMS process. ### 5. Settings & Persistence * Add a user preference (Settings → Advanced): * “Default install location” (User / System) – remembered across sessions. * “Ask before overwriting existing profiles” (default: true). * Optionally record the last-installed system path in the project’s metadata so Stage 5 can show “Already installed to …” on subsequent visits. --- ## Acceptance Criteria 1. After a successful Stage 5 verification the “Install Profile to System” button is enabled and functional on Windows, macOS, and Linux. 2. On Windows the profile is placed in `%WINDIR%\System32\spool\drivers\color` (or registered via the Color Management API) and becomes visible in the Windows Color Management control panel. 3. On macOS the profile appears under `\~/Library/ColorSync/Profiles/` (or `/Library/ColorSync/Profiles/` when elevated) and is listed in ColorSync Utility. 4. On Linux the profile is installed to a colord-recognised location and, when `colormgr` is available, is imported via colord. 5. Permission / elevation failures produce clear, actionable error messages rather than silent failures. 6. Filename collisions are handled with an explicit user choice (Overwrite / Rename / Cancel). 7. The original profile artefact in the working directory remains untouched. 8. Unit tests cover path resolution and the install command’s success and error paths for all three platforms. 9. Documentation (README / AGENTS.md) updated with the new Stage 5 capability and platform-specific notes. --- ## Technical Notes & References * Windows Color Management API: `InstallColorProfile`, `WcsInstallColorProfile` (wingdi / mscms). * macOS: ColorSync framework (`ColorSyncProfileInstall`). * Linux: `colormgr import-profile` / `org.freedesktop.ColorManager` D-Bus interface; FreeDesktop colour-directory conventions (`\~/.local/share/icc`, `/usr/share/color/icc`). * Existing ICCery patterns to reuse: platform-aware path handling, artefact verification, Tauri command error mapping, and the standardised button hierarchy introduced in #177. --- ## Out of Scope (for this ticket) * Automatic association of the profile with a specific printer device (that can be a follow-up). * Batch installation of multiple historical profiles. * Uninstall / remove-from-system functionality (can be added later if demand exists). ---
gronod added the Kind/Feature
Reviewed
Confirmed
1
Priority
High
2
labels 2026-09-07 07:13:55 +01:00
Sign in to join this conversation.