From f0b1a448d485d48645454a410ef47ffc38488143 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sat, 31 Oct 2026 10:10:16 -0700 Subject: [PATCH] refactor(mac): register every Window in ax_registry and forget the dead Step 11(ii), second part. BEHAVIOUR (memory and bookkeeping only; no AX call is added anywhere, and no existing call reads the table yet except the still-unused MacosBackend). Window::new registers the window under its id. Entries end where the daemon learns of a death: Window::drop when the window is no longer alive (next to the InvalidWindow notification it already sends), reap_window in the reaper, and WindowManagerEvent::Destroy for NSWorkspaceDidTerminateApplication (forget_pid, next to enhanced_ui::forget: a new process may reuse the pid). A live window that is never managed stays registered until it dies or its application quits; the table holds retained references that the Window clones held anyway. The native tab case (id and element changed in place) follows in its own revision. Verified: macOS fake-CC type-check (tools/fast-check) PASS. Not verified: cannot run on Linux. Gate needed: the Mac hand check, see docs/dev/macos-handcheck.md (open and close many windows and quit apps; the daemon's memory must not grow; nothing else should look different). --- komorebi-for-mac/komorebi/src/process_event.rs | 1 + komorebi-for-mac/komorebi/src/reaper.rs | 3 +++ komorebi-for-mac/komorebi/src/window.rs | 12 ++++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/komorebi-for-mac/komorebi/src/process_event.rs b/komorebi-for-mac/komorebi/src/process_event.rs index 7c72b2f0..5467f52f 100644 --- a/komorebi-for-mac/komorebi/src/process_event.rs +++ b/komorebi-for-mac/komorebi/src/process_event.rs @@ -745,6 +745,7 @@ impl WindowManager { ) ) { enhanced_ui::forget(process_id); + crate::ax_registry::forget_pid(process_id); } // some apps like Discord in all of their relentless Electron slop stupidity diff --git a/komorebi-for-mac/komorebi/src/reaper.rs b/komorebi-for-mac/komorebi/src/reaper.rs index 9f06b359..362c95b1 100644 --- a/komorebi-for-mac/komorebi/src/reaper.rs +++ b/komorebi-for-mac/komorebi/src/reaper.rs @@ -111,6 +111,9 @@ fn invalid_window_ids( } fn reap_window(wm: &mut WindowManager, window_id: u32) -> color_eyre::Result<()> { + // whatever else happens to the window, the id no longer names anything + crate::ax_registry::forget(window_id); + let mut should_update = false; for monitor in wm.monitors_mut() { for workspace in monitor.workspaces_mut() { diff --git a/komorebi-for-mac/komorebi/src/window.rs b/komorebi-for-mac/komorebi/src/window.rs index 8dc9420e..247b887e 100644 --- a/komorebi-for-mac/komorebi/src/window.rs +++ b/komorebi-for-mac/komorebi/src/window.rs @@ -476,6 +476,9 @@ impl Drop for Window { // for now - hopefully it doesn't break anything else reaper::send_notification(ReaperNotification::InvalidWindow(self.id)); + // and the id no longer names anything + crate::ax_registry::forget(self.id); + // make sure the observer gets removed from any run loops AccessibilityApi::invalidate_observer(&self.observer); } @@ -560,13 +563,18 @@ impl Window { Some(window_observer_callback), )?; - Ok(Self { + let window = Self { id: AccessibilityApi::window_id(&element)?, element: AccessibilityUiElement(element), application, observer: AccessibilityObserver(Some(observer)), details: None, - }) + }; + + // so that the window can be found again from its id alone + crate::ax_registry::register(&window); + + Ok(window) } /// The handles that act on this window, as the registry keeps them