← Commit history

1.0.30: NATIVE (Rust) build. 1.0.30: kicad_taskbar_repair fixes the white taskbar icon on standalone KiCad editors by writing KiCad's own AUMID onto its standalone Start Menu shortcuts, once at every bridge start and on demand; no Adom identity; a stubborn button needs a logon or explorer restart.

John Lauer ·d9b65accd7 ·1mo ago ·parent 7e18d90
4 files changed +53−4
rust/Cargo.lock+3−3
@@ -244,7 +244,7 @@ dependencies = [  [[package]] name = "kicad-bridge"-version = "1.0.29"+version = "1.0.30" dependencies = [  "kicad-core",  "kicad-platform",@@ -255,7 +255,7 @@ dependencies = [  [[package]] name = "kicad-core"-version = "1.0.29"+version = "1.0.30" dependencies = [  "kicad-ipc-rs",  "kicad-platform",@@ -281,7 +281,7 @@ dependencies = [  [[package]] name = "kicad-platform"-version = "1.0.29"+version = "1.0.30" dependencies = [  "serde",  "serde_json",
rust/Cargo.toml+1−1
@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"]  [workspace.package]-version = "1.0.29"+version = "1.0.30" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-bridge/src/main.rs+9
@@ -107,6 +107,15 @@ fn main() {      kicad_platform::native().init_process();     kicad_platform::native().etiquette_start();+    // The white taskbar icon (kicad_taskbar_repair): KiCad's own AUMID onto its standalone+    // shortcuts, once per boot, off the request path. Idempotent and never fatal.+    std::thread::spawn(|| {+        let version = util::State::new().kicad_info().version;+        let r = verbs_maint::taskbar_repair(&version);+        if r["written"].as_u64().unwrap_or(0) > 0 || r["errors"].as_u64().unwrap_or(0) > 0 {+            eprintln!("[kicad-bridge] taskbar repair: {}", r["output"].as_str().unwrap_or(""));+        }+    });     let server = Arc::new(server);     let mut handles = Vec::new();     for _ in 0..WORKERS {
rust/crates/kicad-bridge/src/verbs_maint.rs+40
@@ -11,8 +11,19 @@ use crate::catalog::{Mechanism, Verb}; use crate::util::State; use kicad_core::model_check::{self, Ctx}; use kicad_core::{install_kicad, pcm, updates};+use kicad_platform::native;  pub static VERBS: &[Verb] = &[+    Verb {+        name: "kicad_taskbar_repair",+        summary: "Fix the white taskbar icon on standalone KiCad editors by writing KiCad's own AUMID onto its Start Menu shortcuts.",+        mechanism: Mechanism::File, risk: "write", timeout_sec: 30,+        input: "{}",+        example: "kicad_taskbar_repair {}",+        hint: "KiCad's installer leaves the AppUserModelID blank on the standalone PCB Editor, Schematic Editor and Gerber Viewer shortcuts, so a pcbnew.exe the bridge launches (and its 3D viewer, same process) can show the generic white page on the taskbar. This writes KiCad's OWN AUMID (Kicad.Kicad.pcbnew.<ver>) onto KiCad's OWN user-level shortcuts, nothing of Adom's, and runs by itself at every bridge start. Idempotent. The shell reads the mapping when it next rebuilds its Start Menu index: a newly opened editor usually picks it up; a button that stays white needs a logon or an explorer restart, which the bridge never does for you.",+        related: &["kicad_readiness", "kicad_open_board", "kicad_launch"],+        pitfalls: &["Never stamp Adom identity on KiCad windows: Windows caches the taskbar icon per AUMID string and a bad stamp is permanent (skills/kicad-bridge-dev, THE WHITE-ICON MECHANISM).", "Needs a detected KiCad (the shortcuts are named by major.minor)."],+    },     Verb {         name: "kicad_model_check",         summary: "Read-only 3D model diagnostics for a footprint or a whole board: which (model ...) references exist, where KiCad looks, whether each file exists and holds geometry.",@@ -117,6 +128,7 @@ pub static VERBS: &[Verb] = &[  pub fn dispatch(state: &mut State, command: &str, args: &Value) -> Option<Value> {     let out = match command {+        "kicad_taskbar_repair" => taskbar_repair(&state.kicad_info().version),         "kicad_model_check" => {             let ctx = Ctx::from_info(&state.kicad_info());             model_check::handle(&ctx, args)@@ -154,3 +166,31 @@ pub fn dispatch(state: &mut State, command: &str, args: &Value) -> Option<Value>     };     Some(out) }+++/// Wiki: the white taskbar icon. Also run once at boot from main.rs.+pub fn taskbar_repair(version: &str) -> Value {+    let mm: String = version.split('.').take(2).collect::<Vec<_>>().join(".");+    if mm.is_empty() || !mm.contains('.') {+        return json!({"success": false, "errorCode": "not_installed", "error": "No KiCad version detected, so the shortcut names are unknown.", "_hint": "kicad_readiness reports install state; run again once KiCad is installed."});+    }+    match native().repair_taskbar_shortcuts(&mm) {+        Ok(rows) => {+            let count = |k: &str| rows.as_array().map(|a| a.iter().filter(|r| r["outcome"] == k).count()).unwrap_or(0);+            let (written, already, missing, errors) = (count("written"), count("already"), count("missing"), count("error"));+            json!({+                "success": errors == 0, "version": mm, "shortcuts": rows,+                "written": written, "already": already, "missing": missing, "errors": errors,+                "output": format!("KiCad {mm} standalone shortcuts: {written} written, {already} already carried an AUMID, {missing} missing, {errors} error(s)."),+                "_hint": if written > 0 {+                    "KiCad's own AUMID is now on its standalone shortcuts. A newly opened editor usually gets its real icon; a button that stays white needs a logon or an explorer restart (never done for you)."+                } else if already > 0 {+                    "Nothing to do: the standalone shortcuts already carry an AUMID. A button that is still white needs a logon or an explorer restart, or the icon was cached under a foreign AUMID before this fix (see the bridge-dev skill)."+                } else {+                    "No standalone shortcuts found under this user's Start Menu for that KiCad version, so there was nothing to repair."+                },+            })+        }+        Err(e) => json!({"success": false, "errorCode": if e.contains("not supported") { "not_supported_on_platform" } else { "platform_error" }, "error": e}),+    }+}