← 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).

John Lauer ·c9c9e6e844 ·1mo ago ·parent a641c89
2 files changed +15
rust/crates/kicad-platform/src/lib.rs+7
@@ -230,6 +230,13 @@ pub trait Platform: Sync + Send {     /// off (setting `backgroundGuard`). Off means KiCad windows are never moved or pushed by the     /// bridge at all; events are still logged so the two modes can be compared.     fn etiquette_set_enabled(&self, _on: bool) {}+    /// Whether the background guard is on (setting `backgroundGuard`).+    fn etiquette_enabled(&self) -> bool { true }+    /// A Windows shell window (taskbar, Start, desktop, anything explorer.exe owns). The bridge+    /// never forces one of these to the foreground: doing so crashed Explorer (Taskbar.View.dll).+    fn is_shell_window(&self, _h: u64) -> bool { false }+    /// Ask (never force) for `h` to become the foreground window. True when Windows agreed.+    fn request_foreground(&self, _h: u64) -> bool { false }     /// Cancel Windows' taskbar attention flash on bridge-owned KiCad windows (setting     /// `activityIndicator`: progress and none suppress it, flash and both leave it).     fn etiquette_set_flash_suppressed(&self, _on: bool) {}
rust/crates/kicad-platform/src/win/etiquette.rs+8
@@ -1182,6 +1182,14 @@ pub fn set_flash_suppressed(on: bool) { /// The user's A/B switch (setting `backgroundGuard`, the dashboard's "Keep KiCad in the background"). static GUARD_ENABLED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(true); +pub fn enabled() -> bool {+    GUARD_ENABLED.load(std::sync::atomic::Ordering::Relaxed)+}++pub fn is_shell_hwnd(h: u64) -> bool {+    is_shell_window(h, &mut ExeCache::default())+}+ pub fn set_enabled(on: bool) {     let was = GUARD_ENABLED.swap(on, std::sync::atomic::Ordering::Relaxed);     if was != on {