app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
← Commit history
1.0.48: 1.0.48: the backgroundGuard switch now switches off ALL of the bridge's window moving. A second mechanism, the per-verb focus check that runs after every window verb, ignored the switch: it pushed a KiCad window back and forced the user's previous window to the front after each verb, so with the guard off KiCad still never ended up in front and the A/B comparison showed nothing. It now obeys the switch, never targets a shell window, and asks for the user's window back with one plain SetForegroundWindow instead of the forcing call (thread-input attach, the same call that crashed Explorer when aimed at the taskbar).
3 files changed
+14−7
rust/Cargo.lock+3−3@@ -244,7 +244,7 @@ dependencies = [ [[package]] name = "kicad-bridge"-version = "1.0.47"+version = "1.0.48" dependencies = [ "kicad-core", "kicad-platform",@@ -255,7 +255,7 @@ dependencies = [ [[package]] name = "kicad-core"-version = "1.0.47"+version = "1.0.48" dependencies = [ "kicad-ipc-rs", "kicad-platform",@@ -281,7 +281,7 @@ dependencies = [ [[package]] name = "kicad-platform"-version = "1.0.47"+version = "1.0.48" dependencies = [ "serde", "serde_json",
rust/Cargo.toml+1−1@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"] [workspace.package]-version = "1.0.47"+version = "1.0.48" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-bridge/src/verbs_windows.rs+10−3@@ -802,8 +802,14 @@ fn is_kicad_hwnd(hwnd: u64) -> bool { /// and the user had a non-KiCad window before, push KiCad back once (never activate the /// user's window: Windows re-activates it naturally) and report the event. fn one_shot_focus_check(fg_before: Option<u64>) -> Option<Value> {+ // Part of the background guard: with the guard OFF the bridge moves no KiCad window at all.+ // Before 1.0.48 this per-verb check ignored the switch, so "guard off" still pushed KiCad back+ // after every verb and the A/B comparison showed nothing (AdomLapper, 2026-09-21).+ if !native().etiquette_enabled() {+ return None;+ } let before = fg_before?;- if is_kicad_hwnd(before) {+ if is_kicad_hwnd(before) || native().is_shell_window(before) { return None; } // What covers the user's window is the top of the Z order, not only the activated@@ -824,8 +830,9 @@ fn one_shot_focus_check(fg_before: Option<u64>) -> Option<Value> { // A Z-order push alone does not hold: the editor still owns the activation and raises // itself again on its next paint. Give the user's window its activation back (this // restores what the user had before the verb; it is not a foreground of ours).- let restored = ab::desktop_restore_user_window(before, "restore the user's window after a KiCad window raised itself").is_ok()- || matches!(native().bring_to_front(before), Ok(true));+ // ASK for the user's window back, never force it (no thread-input attach): the forcing+ // bring_to_front here was the same call that crashed Explorer when aimed at the taskbar.+ let restored = native().request_foreground(before); let action = match (pushed, restored) { (true, true) => "pushed-to-background, user window restored", (true, false) => "pushed-to-background",