Note
🤖 Claude Opus 5.5 responding on behalf of samanyudas
Triage result: the engine already has both snapping modes, so this issue is mostly a Settings control, docs, and checks.
I added needs-info, because criterion 4 has no measurable limit and three product choices are open.
No code changed.
Why the strip scrolls continuously today
The pinned engine (a20f56e, on main at ffefedfa) has two step modes, and both are off by default:
[swipe.gesture] paging = trueturns a strip swipe into focus steps, one adjacent window perpage_distance_cmof finger travel (default 2 cm). Seepaging_gestureandGestureOptions.[swipe.scroll] window_step = trueturns each modifier-scroll wheel input into one focus step. Seehandle_scroll_wheel.
Upstream Paneru added these modes in d7080ec on 16 October 2026.
Miri's Settings writes fingers_count, direction, and vertical in [swipe.gesture], but never paging or window_step (Settings.swift).
So the engine defaults apply, and the strip scrolls freely, then settles.
What each criterion needs
Evidence types differ below.
"CI" means the engine unit tests passed in the Engine tests on macOS 27 job of CI run 42179065759 on ffefedfa.
"Code" means I read the code and did not run it.
Nothing below was checked in the running app.
| Criterion | State in the engine | Work left |
|---|---|---|
| 1. Settings shows both modes | Not built. | A Settings control that writes both keys, plus rows in decisions/configuration.md. |
| 2. Discrete steps | Built. Each step is the keyboard focus command, so the strip moves only as far as needed to show the column. CI: paging_waits_for_distance_then_focuses_without_free_scrolling. | Live check. |
| 3. Trackpad and wheel | Built as two separate keys. CI: 14 paging tests and 5 wheel tests passed. | One Miri setting must write both keys. |
| 4. Momentum | Wheel: momentum events never step, and same-direction repeats within 180 ms are dropped. CI: wheel_momentum_does_not_select_a_window_or_delay_the_next_input. Trackpad: steps come from finger travel only, so momentum cannot add steps. But a long swipe earns one step per 2 cm, and those steps still play out after the fingers lift. CI: paging_fast_swipe_keeps_each_step_and_signed_remainder. | A measurable limit. See question 1. |
| 5. Strip ends | Built. Focus stops at the end column. CI: paging_respects_reversed_direction_and_strip_edges, wheel_steps_focus_adjacent_windows_and_stop_at_strip_edges. | Live check with an overflowing strip. |
| 6. Mixed widths and stacks | Code: steps call the same focus command as the keyboard, with focus history, so a stack follows the keyboard focus rule. | Live check. AXFixture is fixed at 380 pt, so mixed widths need another window or a --width option, as noted in #305. |
| 7. Per display and Space | Code: steps move focus, so each strip keeps its own offset. A step acts on the focused window's strip, the same as a swipe today. #212 covers the strip under the pointer. | Live check on two displays. |
| 8. Switching back | Code: a config change resets the paging state. | Live check. |
| 9. Survives restart | The setting lives in the config file. | Swift test plus a relaunch check. |
Agents cannot send real trackpad gestures, so the trackpad parts of criteria 2 to 8 and the "feels predictable" check are hand checks for Sam. The wheel parts can run with synthetic modifier-scroll events.
Open questions for Sam
- Long swipes. Today a 10 cm swipe moves 5 windows. Should snapping keep one step per 2 cm of travel, or allow exactly one step per gesture? My recommendation is one step per 2 cm, because it matches the engine and lets a long swipe travel far. Criterion 4 would then read: "A trackpad step needs 2 cm of finger travel, and travel after the fingers lift adds no step. Wheel momentum never adds a step."
- Haptics. The engine pulses the trackpad on each step by default (
haptics). Should Miri keep that on with no setting, turn it off, or add a setting? My recommendation is on, with no setting. - Step distance. Should
page_distance_cmstay fixed at 2 cm, or be a setting? My recommendation is fixed at 2 cm for now.
Release: the work left is small, but Sam set v2, and decisions/release-scope.md says settling has no setting in v1.
I did not change the scope.