← Commit history

1.0.14: NATIVE (Rust) build. 1.0.14: an editor window the bridge OPENS is put back on the monitor the user keeps that editor on, not just after a restart (wiki #48, the opens-or-restarts half of the complaint).

John Lauer ·08eaa0a2d2 ·1mo ago ·parent 4a6d9d7
3 files changed +53−28
rust/Cargo.lock+3−3
@@ -244,7 +244,7 @@ dependencies = [  [[package]] name = "kicad-bridge"-version = "1.0.13"+version = "1.0.14" dependencies = [  "kicad-core",  "kicad-platform",@@ -255,7 +255,7 @@ dependencies = [  [[package]] name = "kicad-core"-version = "1.0.13"+version = "1.0.14" dependencies = [  "kicad-ipc-rs",  "kicad-platform",@@ -281,7 +281,7 @@ dependencies = [  [[package]] name = "kicad-platform"-version = "1.0.13"+version = "1.0.14" dependencies = [  "serde",  "serde_json",
rust/Cargo.toml+1−1
@@ -3,7 +3,7 @@ resolver = "2" members = ["crates/*"]  [workspace.package]-version = "1.0.13"+version = "1.0.14" edition = "2021" license = "MIT" publish = false
rust/crates/kicad-bridge/src/verbs_windows.rs+49−24
@@ -651,30 +651,34 @@ pub(crate) fn restore_placement() -> Vec<Value> {     if mem.is_empty() {         return Vec::new();     }-    let mut out = Vec::new();-    for w in kicad_windows() {-        let kind = w.kind();-        let Some(remembered) = mem.get(kind.as_str()) else { continue };-        let r = &remembered.place;-        let current = match native().placement(w.hwnd) {-            Ok(p) => p,-            Err(e) => {-                out.push(json!({"window": kind.as_str(), "hwnd": w.hwnd, "moved": false, "error": e}));-                continue;-            }-        };-        let on_monitor = native().on_a_monitor((r.x, r.y, r.width, r.height)).unwrap_or(false);-        match window_memory::decide(r, &current, on_monitor) {-            Restore::Skip(why) => out.push(json!({"window": kind.as_str(), "hwnd": w.hwnd, "moved": false, "why": why})),-            Restore::Move(p) => match native().set_placement(w.hwnd, &p) {-                Ok(()) => out.push(json!({"window": kind.as_str(), "hwnd": w.hwnd, "moved": true,-                    "to": {"x": p.x, "y": p.y, "width": p.width, "height": p.height, "maximized": p.maximized},-                    "rememberedAt": remembered.at})),-                Err(e) => out.push(json!({"window": kind.as_str(), "hwnd": w.hwnd, "moved": false, "error": e})),-            },-        }-    }-    out+    kicad_windows().iter().filter_map(|w| restore_one(&mem, w.kind(), w.hwnd)).collect()+}++/// Wiki #48: one freshly opened window put back on the monitor the user keeps that kind of+/// window on. Called when a verb OPENS an editor, not only when it restarts KiCad, because+/// "the bridge opens or restarts KiCad and it comes back on the laptop screen" is one+/// complaint with two halves. Returns None when nothing is remembered for that kind.+pub(crate) fn restore_placement_one(kind: WindowKind, hwnd: u64) -> Option<Value> {+    restore_one(&window_memory::load(), kind, hwnd)+}++fn restore_one(mem: &window_memory::Memory, kind: WindowKind, hwnd: u64) -> Option<Value> {+    let remembered = mem.get(kind.as_str())?;+    let r = &remembered.place;+    let current = match native().placement(hwnd) {+        Ok(p) => p,+        Err(e) => return Some(json!({"window": kind.as_str(), "hwnd": hwnd, "moved": false, "error": e})),+    };+    let on_monitor = native().on_a_monitor((r.x, r.y, r.width, r.height)).unwrap_or(false);+    Some(match window_memory::decide(r, &current, on_monitor) {+        Restore::Skip(why) => json!({"window": kind.as_str(), "hwnd": hwnd, "moved": false, "why": why}),+        Restore::Move(p) => match native().set_placement(hwnd, &p) {+            Ok(()) => json!({"window": kind.as_str(), "hwnd": hwnd, "moved": true,+                "to": {"x": p.x, "y": p.y, "width": p.width, "height": p.height, "maximized": p.maximized},+                "rememberedAt": remembered.at}),+            Err(e) => json!({"window": kind.as_str(), "hwnd": hwnd, "moved": false, "error": e}),+        },+    }) }  fn find_project_manager() -> Option<u64> {@@ -1333,6 +1337,22 @@ fn ensure_project_manager(info: &KicadInfo, pathways: &mut Vec<String>) -> Resul /// Open an editor frame: an existing one wins; else the native menu walk on each host /// frame (WM_COMMAND, repost once at 10 s); else UIA Invoke. Returns (hwnd, mechanism). fn open_editor_frame(info: &KicadInfo, spec: &OpenSpec, budget: &Budget, pathways: &mut Vec<String>) -> Result<(u64, &'static str), Value> {+    let out = open_editor_frame_inner(info, spec, budget, pathways);+    // Wiki #48: a frame the bridge just opened is placed by Windows defaults, which means the+    // primary display. An existing window is the user's own and is never moved.+    if let Ok((hwnd, mechanism)) = &out {+        if *mechanism != "existing" {+            if let Some(row) = restore_placement_one(spec.kind, *hwnd) {+                if row["moved"] == json!(true) {+                    pathways.push(format!("placement-restored:{}", spec.kind.as_str()));+                }+            }+        }+    }+    out+}++fn open_editor_frame_inner(info: &KicadInfo, spec: &OpenSpec, budget: &Budget, pathways: &mut Vec<String>) -> Result<(u64, &'static str), Value> {     invalidate();     if let Some(h) = first_of_kind(spec.kind) {         return Ok((h, "existing"));@@ -1583,6 +1603,11 @@ pub(crate) fn open_file(state: &mut State, args: &Value, kind: WindowKind) -> Va             out["hwnd"] = json!(w.hwnd);             out["title"] = json!(w.title);             out["windowAppeared"] = json!(true);+            // Wiki #48: this window was spawned by us, so Windows placed it on the primary+            // display; put it back on the monitor the user keeps this editor on.+            if let Some(row) = restore_placement_one(kind, w.hwnd) {+                out["placementRestored"] = row;+            }         }         None => {             let alive = native().process_alive(pid);