Repository navigation
R-INPUT S2a: the input router reduces each window's focus as the app's focus handle does (WindowFocus), Rust only - #34929
Conversation
…focus handle does (R-INPUT S2a), red Stage S2 makes the router own every window's focus, so the app's per-window focus handle can become the router's. Today the two reduce differently: - the router reduces a topology report again (reducer::reduce), while the app's handle takes reducer::set_topology's fast path (an equal topology, re-reported after every daemon delta, changes nothing); - the router has no address bar memory (Chrome's per-tab omnibox focus), which the app's handle keeps beside the state. This commit adds: - cmux_focus_core::window::WindowFocus: one window's focus (the state, the address bar memory, the Close Tab aim) with the operations the app's handle performs. The FFI handle (cmux-layout-reducer-ffi focus.rs) now wraps it and delegates, with no ABI or reply change. - InputEffect::FocusReduced: after a focus event's effects, whether the reducer ran and what the address bar memory asks for (the app's reply carries this). - key_router::window_focus: the same focus events through the router and a WindowFocus; effects, reductions and state must be equal. The red: the router still reduces as today (it reports ran from reducer::reduce and no address bar memory), so the test fails here.
…uces focus events as the app's focus handle does (R-INPUT S2a) The router's per-window entry holds a cmux_focus_core::window::WindowFocus (the state, the address bar memory, the Close Tab aim) instead of a bare FocusState, and a focus event goes through WindowFocus::send: - a topology report takes reducer::set_topology's fast path (an equal topology changes nothing), as in the app's handle; - the address bar memory notes every reduction, and the router reports what it asks for in InputEffect::FocusReduced. The reference model holds a WindowFocus per window too, so the fuzz compares routing over the same focus semantics. No caller yet: stage S2b gives the app one cmux_input_* handle over the router, with the focus handle's replies.
|
Review (independent subagent, correctness first): SHIP at d5cb5d4 Reviewed at d5cb5d4: FindingsNone that block. 1.
|
|
REWRITE R-INPUT: the non-green check on head d5cb5d4 is a base finding. This PR changes only
Independent review: SHIP at d5cb5d4 (#34929 (comment)). Sequencing: I add |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
R-INPUT stage S2a (DESIGN.md, stage S2). Stage S2 makes the input router (
cmux-focus-coreinput::InputRouter, #34052) own every window's focus, so that the app's per-window focus handle can become the router's in S2b and S2c. Today the router and the app's handle reduce the same focus event in different ways:reducer::reduceagain. The app's handle takesreducer::set_topology's fast path: an equal topology changes nothing. The daemon sends the topology again after every delta, so the router reportedranfor events that the app's handle drops.This PR makes the router reduce focus as the app's handle does. It changes no caller and no app behavior:
cmux_focus_core::window::WindowFocus: one window's focus (the state, the address bar memory, the Close Tab aim), with the operations that the app's focus handle performs (send,set_topology,pane_moved,frame_presented,pane_emptied,aims_at_emptied_pane,set_close_focus,import,rederive).cmux-layout-reducer-ffisrc/focus.rs) now holds aWindowFocusand delegates to it. The C ABI and the reply bytes do not change.WindowFocusfor each window, and a focus event goes throughWindowFocus::send. After the focus effects, the router emits the newInputEffect::FocusReduced { window, reduction }: whether the reducer ran and what the address bar memory asks for. The app's reply carries the same data.WindowFocusfor each window, so the fuzz compares the routing over the same focus rules.This is step A of the FFI two-step rule (STATUS 5388):
cmux-focus-coreandcmux-layout-reducer-ffiare app FFI inputs. After this lands, the bot publishes the FFI release and opens the re-pin. There is no Swift half: the ABI does not change.Test (
cmux-tui/crates/cmux-focus-core/tests/input_router/key_router/window_focus.rs):key_router::window_focus::the_router_reduces_focus_events_as_the_apps_focus_handle_does: the same focus events go through the router and through aWindowFocus(the app handle's type). The events are a topology, the equal topology again, a mouse focus on a page pane, the address bar by keyboard, a mouse focus on the terminal pane, a keyboard focus back to the page pane, and the return event. The router's focus effects, itsFocusReducedreduction and the window's state must be equal to the handle's after each event.Red/green, the same filter
key_router::(scripts/ci/cmux-tui-rust-check.sh --os linux):WindowFocus, with the router as on feat), modetest: step 3d17eb26c48f34c41d3ce7b1. 72 tests ran and 1 failed:key_router::window_focus::the_router_reduces_focus_events_as_the_apps_focus_handle_does, on its assertion at window_focus.rs:68, on the equal topology report (leftSome(Reduction { ran: true, .. }), rightSome(Reduction { ran: false, .. })). It failed again when it ran alone. The first red step (bf51f012572b93d9e4bd7045) also ended in failure, but its log is lost: GitHub answers BlobNotFound and the controller has no full log. So I ran it again.all: step 28af93a87fd6752c31c2dbd8. fmt passed. Clippy (--workspace --all-targets -D warnings) passed. 72 of 72key_router::tests passed: the new test, the router fuzz (20,000 cases against the reference model),key_router::mutants::every_mutant_is_caughtandkey_router::allocations::a_key_its_release_and_a_bound_chord_allocate_nothing(a key still allocates nothing).cmux-layout-reducer-ffiis its own Cargo workspace, so the fleet's Rust check does not build it. The never-merge reffix/r-input-s2a-ffi-proof-never-merge(439a4c8, listed in stopped.txt) adds the crate to the cmux-tui workspace and runs every workspace test, including the FFI crate's Swift-recorded focus corpus (the_rust_focus_rules_reproduce_every_recorded_swift_step) and the handle tests inclose_focus_rules.rs. Step 6203ede8b4514ffe3266189d (modetest, no filter):cmux-layout-reducer-ffi74 of 74 passed,cmux-focus-core133 of 133 passed. The step as a whole failed on 10 tests in crates that this PR does not touch (acpmux3,cmux-agent-pane-policy2,cmux-tui4 and their reruns; for exampleacpmux::hermetic_daemon_guard every_test_binary_runs_in_the_hermetic_environment, which the proof ref's extra workspace member can cause, andcmux-agent-pane-policy::typescript the_page_sends_only_allowed_acpmux_meta). The GitHub checkcmux-tui/crates/cmux-layout-reducer-ffiof this PR also builds the FFI crate in its own workspace, runs clippy-D warningson all targets and runs every FFI test: it passed.Independent review: SHIP at d5cb5d4 (#34929 (comment)). Its three small points go to a follow-up (S2b touches the same files): an FFI handle test of the reply to an equal topology; a reference model that keeps
reducer::reducefor topology events, so that the fuzz also proves the fast path changes no routing; and a doc line that the FFI sends a topology only throughset_topology.Observed / Not run
Changelog
none
No capture: Rust-only library code; the app's behavior does not change.