From d30a3eb6868188cb38b4fa23d0d24b61e2663f64 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sat, 31 Oct 2026 10:01:05 -0700 Subject: [PATCH] refactor(mac): MacosBackend reaches a window only through Window methods Step 11(i). The compile-only adapter still read the Accessibility element for two things: the minimized flag (copy_attribute_value of kAXMinimized) and close (AdhocWindow::close on the element). Window::minimized is added (the same query, on self.element) and the adapter now calls it and Window::close; with set_rect, focus, raise, hide, restore, minimize, unminimize, alive and frame (earlier revisions) every operation of the adapter is a Window method and the file imports no AccessibilityApi. The adapter is still not used by the daemon, so nothing changes at runtime. Steps 11(ii) (id registry) and (iii) are not started. Verified: macOS fake-CC type-check (tools/fast-check) PASS. Not verified: cannot run or unit-test on Linux. --- .../komorebi/src/macos_backend.rs | 19 +++++-------------- komorebi-for-mac/komorebi/src/window.rs | 6 ++++++ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/komorebi-for-mac/komorebi/src/macos_backend.rs b/komorebi-for-mac/komorebi/src/macos_backend.rs index b1b32f0f..aa12546e 100644 --- a/komorebi-for-mac/komorebi/src/macos_backend.rs +++ b/komorebi-for-mac/komorebi/src/macos_backend.rs @@ -1,5 +1,6 @@ -//! `MacosBackend`: the shared [`komorebi_backend::Backend`] over the existing [`MacosApi`], -//! [`Window`] and [`AdhocWindow`] functions. +//! `MacosBackend`: the shared [`komorebi_backend::Backend`] over the existing [`MacosApi`] and +//! [`Window`] methods (set_rect, focus, raise, hide, restore, minimize, unminimize, close, alive, +//! frame and minimized): it holds no Accessibility call of its own. //! //! **Nothing uses it yet.** The daemon still holds `Window` values (element, application and //! observer) and calls them directly; this adapter exists so that the trait is known to be @@ -19,13 +20,10 @@ //! callback refreshes on main with [`MacosBackend::refresh_monitors`]. use crate::LibraryError; -use crate::accessibility::AccessibilityApi; -use crate::accessibility::attribute_constants::kAXMinimizedAttribute; use crate::core::Rect; use crate::core::WindowHidingPosition; use crate::macos_api::MacosApi; use crate::skylight::BatchedUpdates; -use crate::window::AdhocWindow; use crate::window::Window; use komorebi_backend::Backend; use komorebi_backend::Error; @@ -35,7 +33,6 @@ use komorebi_backend::Result; use komorebi_backend::WindowId; use komorebi_backend::WindowInfo; use objc2::MainThreadMarker; -use objc2_core_foundation::CFBoolean; use parking_lot::Mutex; use std::collections::HashMap; @@ -130,12 +127,6 @@ impl MacosBackend { return None; } - let minimized = AccessibilityApi::copy_attribute_value::( - &window.element, - kAXMinimizedAttribute, - ) - .is_some_and(|b| b.as_bool()); - Some(WindowInfo { id: WindowId::from_u32(window.id), pid: window.application.process_id, @@ -143,7 +134,7 @@ impl MacosBackend { rect: window.frame() .map(Rect::from) .unwrap_or_default(), - minimized, + minimized: window.minimized(), alive: true, title: window.title(), // macOS has no window class: a bundle identifier, role and subrole instead @@ -243,7 +234,7 @@ impl Backend for MacosBackend { fn close(&self, id: WindowId) -> Result<()> { // presses the close button; `Ok` when the window has none let window = self.lookup(id)?; - AdhocWindow::close(&window.element.0).map_err(|e| Self::failed(id, &window, e)) + window.close().map_err(|e| Self::failed(id, &window, e)) } fn center_cursor_in(&self, rect: &Rect) -> Result<()> { diff --git a/komorebi-for-mac/komorebi/src/window.rs b/komorebi-for-mac/komorebi/src/window.rs index 3ea82eab..2f1ad9a6 100644 --- a/komorebi-for-mac/komorebi/src/window.rs +++ b/komorebi-for-mac/komorebi/src/window.rs @@ -802,6 +802,12 @@ impl Window { Ok(()) } + /// Whether the window is minimized (the `WindowInfo::minimized` field of the shared `Backend`). + pub fn minimized(&self) -> bool { + AccessibilityApi::copy_attribute_value::(&self.element, kAXMinimizedAttribute) + .is_some_and(|b| b.as_bool()) + } + pub fn minimize(&mut self) -> Result<(), AccessibilityError> { let cf_boolean = CFBoolean::new(true); let value = &**cf_boolean;