window_manager.rs: three WindowsApi::center_cursor_in_rect calls become backend().center_cursor_in(..) and WindowsApi::disable_focus_follows_mouse becomes backend().set_focus_follows_mouse(false); workspace.rs: the WindowsApi::restore_window that unmaximizes a window becomes backend().unminimize(..) (the same ShowWindow call, after an IsWindow check). backend-switch.md now lists every WindowsApi call left in window_manager, workspace and monitor and why each cannot be switched without changing an error, a default or a flag (foreground_window, cursor_pos, focus on the desktop window, position_window flags, start-up enumeration, monitor fields). BEHAVIOUR: a dead window is skipped by the unminimize. e2e gate needed: commands, focus_follows_mouse, maximizing, workspaces. Verified: Windows clippy -D warnings via tools/fast-check PASS; e2e not run.
5.7 KiB
Windows: which call sites go through backend()
Step 8 of the unified-binaries plan. komorebi::windows_backend::backend() returns the shared
komorebi_backend::Backend (a stateless WindowsBackend over WindowsApi and Window). The daemon
is switched one cluster at a time; each switch is its own revision marked BEHAVIOUR.
What every switched call changes in the Windows daemon: WindowsBackend first asks IsWindow and
fails with Error::WindowGone for a dead window (hide, restore, minimize, maximize and the other ()
returning operations are then skipped: before, Window::hide of a dead window still ran
ShowWindow on it, a no-op, and recorded its handle in HIDDEN_HWNDS), and a failure of a window
that died meanwhile is reported as WindowGone (the error text changes from the Win32 one). Call sites
use ? or ignore the result; none inspects the error. frame is the exception: it does not ask
IsWindow first, so the Win32 error is what callers get.
Switched
| Cluster | Operation | Sites | Notes | e2e needed |
|---|---|---|---|---|
| focus | focus(id, mouse_follows) |
40 (process_event, process_command, workspace, window_manager, focus_manager, stackbar) | animation/transition.rs calls Window::focus from the slide-in code Window::focus defers to: left |
commands, focus, focus_follows_mouse, stacking, workspaces, lifecycle |
| frame write | set_rect(id, rect) |
2 (workspace layout update, stackbar tab click) | top = false only |
commands, resize, layouts, stacking, scrolling, workspaces |
| frame read | frame(id) |
about 55, one revision per file: stackbar_manager (2 files), animation (snapshot, ghost_dispatcher, ghost test), live_resize, pan, scrolling, process_command, process_event, window_manager, border_manager (2 files) | frame is a provided method added to the trait for this (WindowsBackend: Window::window_rect, one DWM call; error kept). Window::window_rect/WindowsApi::window_rect remain only inside window.rs (the implementation, and Window::set_position/move_to_area/center/focus internals) |
resize, layouts, stacking, scrolling, borders, animation, commands, lifecycle |
| hide / show | hide, restore (plain forms) |
23 | commands, workspaces, stacking, lifecycle_hidden | |
| hide / show | minimize, close, raise |
1 + 1 + 4 (process_command), 4 minimize (monitor_reconciliator) | commands, monitor reconciliation, lifecycle | |
| maximize | maximize(id, bool) |
5 (workspace.rs) | capability query already in the trait (supports(Capability::Maximize), true here) |
maximizing, commands, workspaces |
Left on purpose (platform-owned subsystems, seam.md rule 5)
set_position(.., true)(window.rsmove_to_area,center, workspace maximize area): the raise-to-front flag is a Windows detail of the layout/animation code, the sharedset_recthas none.hide_with_border,restore_with_border: borders are a platform subsystem (own windows and threads).animation/transition.rs,animation/ghost*.rs(except the frame reads above): the DWM ghost and slide-in machinery.set_opacity: the adapter writes the plain alpha,Window::transparent/opaquetake the alpha from the transparency manager and animate.
Not switched, and what the trait would need (for step 9)
| Operation | Why it stays on the platform API | What the trait would need |
|---|---|---|
foreground_window |
WindowsApi::foreground_window() -> Result<isize>: a null handle is an Err whose message callers pass on; the trait has Option<WindowId> |
a Result variant (Error::Platform for "no foreground window"), or accept losing the message |
cursor_pos |
Result<POINT> vs Option<(i32, i32)>; callers ? it |
same: a Result return |
monitors / window |
monitors() rebuilds MonitorInfo and drops the Monitor fields the daemon needs (device id, serial, device, work-area offsets); window() asks title, class, exe, path |
the daemon-side Monitor fields in MonitorInfo (or a platform extension), and for step 9 the monitor model moving to the core |
monitor_from_point |
never None on Windows (MONITOR_DEFAULTTONEAREST), None outside every monitor on KDE and macOS |
an explicit "nearest" flag or two methods |
What is left in window_manager.rs, workspace.rs, monitor.rs (checked call by call)
Switched in the last batch: center_cursor_in_rect (3, window_manager), disable_focus_follows_mouse (1),
restore_window as unminimize (1, workspace). The rest names WindowsApi for a reason the trait does not
cover yet:
| Call (sites) | Why it stays |
|---|---|
foreground_window (10 in window_manager, 3 workspace, 1 monitor) |
Result<isize>, a null handle is an Err the callers ? on; trait has Option<WindowId> |
cursor_pos, window_at_cursor_pos, monitor_from_window, monitor_from_point |
Result/never-None semantics, see the table above; window_at_cursor_pos and monitor_from_window have no trait equivalent |
raise_and_focus_window(desktop_window) (4) |
Backend::focus is Window::focus, which skips when the window is already foreground and defers while it slides in; the direct call always raises and focuses |
position_window(hwnd, rect, false, true) (2) |
a different flag combination than set_rect (top = false, the second flag is the layered/shadow handling), not expressible |
load_monitor_information, load_workspace_information |
start-up enumeration into a WindowManager; seam.md 9: windows() cannot match the core's filter |
monitor(hmonitor), monitor_rects, monitors_have_same_dpi |
the Monitor fields (device id, DPI) the trait's MonitorInfo drops |
set_wallpaper |
wallpaper stays KDE-only in the trait (D36) |
focus_follows_mouse (query) |
the trait has the setter only |