diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6265c7fb8..34a36c5b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -75,6 +75,18 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable + - name: Convert SVG icon to ICO + shell: pwsh + run: | + # ImageMagick is pre-installed on windows-latest. The + # auto-resize generates every size Explorer / Add-Remove + # Programs / the Start Menu shortcut may request from a + # single source SVG. Must run BEFORE the build so build.rs + # can embed the icon into the .exe (issue #107). + magick assets/logo.svg ` + -define icon:auto-resize=16,24,32,48,64,128,256 ` + packaging/windows/AppIcon.ico + - name: Build run: cargo build --release @@ -96,17 +108,6 @@ jobs: timestamp-rfc3161: http://timestamp.acs.microsoft.com timestamp-digest: SHA256 - - name: Convert SVG icon to ICO - shell: pwsh - run: | - # ImageMagick is pre-installed on windows-latest. The - # auto-resize generates every size Explorer / Add-Remove - # Programs / the Start Menu shortcut may request from a - # single source SVG. - magick assets/logo.svg ` - -define icon:auto-resize=16,24,32,48,64,128,256 ` - packaging/windows/AppIcon.ico - - name: Build MSI installer shell: pwsh run: | diff --git a/Cargo.lock b/Cargo.lock index 86132e6fd..81ee7aaf8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,6 +36,7 @@ dependencies = [ "truck-shapeops", "ureq", "windows-sys 0.61.2", + "winresource", ] [[package]] @@ -3137,7 +3138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b577e2d69827c4740cba2b52efaad1c4cc7c73042860b199710b3575c68438d" dependencies = [ "bytecount", - "memchr 1.0.2", + "memchr 2.8.1", "nom 8.0.0", ] @@ -4829,6 +4830,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + [[package]] name = "servo_arc" version = "0.1.1" @@ -5446,6 +5456,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -5493,6 +5518,12 @@ dependencies = [ "winnow 1.0.3", ] +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + [[package]] name = "tracing" version = "0.1.44" @@ -6776,6 +6807,16 @@ dependencies = [ "memchr 2.8.1", ] +[[package]] +name = "winresource" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087" +dependencies = [ + "toml", + "version_check", +] + [[package]] name = "wit-bindgen" version = "0.51.0" diff --git a/Cargo.toml b/Cargo.toml index 456cc1a27..ce154a069 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,11 @@ build = "build.rs" [workspace] members = ["crates/ocs_plugin_api"] +# Embed the application icon into the Windows .exe so Explorer, the taskbar, +# the Start-menu tile and file-association entries show it (issue #107). +[target.'cfg(windows)'.build-dependencies] +winresource = "0.1" + [dependencies] # Stable, dependency-free add-on contract (manifest + ribbon/CadModule types). # Plugin authors target this crate's semver, not OpenCADStudio internals. diff --git a/build.rs b/build.rs index baa65b3c4..582907c38 100644 --- a/build.rs +++ b/build.rs @@ -26,6 +26,22 @@ use std::path::Path; const PRIORITY: &[&str] = &["home", "model", "insert", "annotate", "view", "manage"]; fn main() { + // Windows: embed AppIcon.ico into the .exe so the executable carries its + // own icon (Explorer, taskbar, Start-menu tile, file associations). The + // .ico is produced from assets/logo.svg by the release workflow before the + // build; when it is absent (local/dev builds) this is skipped. See #107. + #[cfg(windows)] + { + println!("cargo:rerun-if-changed=packaging/windows/AppIcon.ico"); + if Path::new("packaging/windows/AppIcon.ico").exists() { + let mut res = winresource::WindowsResource::new(); + res.set_icon("packaging/windows/AppIcon.ico"); + if let Err(e) = res.compile() { + println!("cargo:warning=failed to embed Windows icon: {e}"); + } + } + } + let mods_dir = Path::new("src/modules"); println!("cargo:rerun-if-changed=src/modules");