Conversation
The desk holds Tab while sweeping the pointer across the order lines it wants cancelled. Between two lines nothing is hovered, and every auto- repeat fell through the app-level keystroke interceptor to MoonUI Root's `tab` -> `focus_next` -> `Window::refresh`: focus walked every control of the terminal and the window redrew once per repeat (measured with the render counters: shell_render 1/s -> 23/s under a 3 s hold, one full draw per repeat — the "fps drops to 5-10" report). The interceptor now reads `KeystrokeEvent::is_held` (MoonUI ef48635) and stops a bare Tab or Shift+Tab REPEAT while a chart is hovered: there Tab is the cancel key, not navigation. A fresh press with nothing under the pointer still navigates, and away from a chart a held Tab keeps its ordinary auto-repeat walk. Measured after: shell_render 1-3/s under the same hold. The same flag stops the cancel spam the repeat produced: the cancelled line stays on the chart until the core echoes, so every repeat sent the same cancel again. `ChartPanel::cancel_hovered_order` takes the repeat flag and does not resend for the order it already addressed during the current hover; `dispatch_hotkey`/`dispatch_hotkey_at` carry the flag so the Delete route gets it too, while modifier hotkeys and mouse action clicks pass `false`. Contract test `a_held_tab_is_spent_before_focus_navigation` holds the rule. Not verified live on a real core.
The Tab fix reads `KeystrokeEvent::is_held`, which MoonUI grew in ef48635. build.yml refreshes MoonUI at run time, but release.yml builds `--locked` on the committed pin and a local `main` resolves the lock as committed — both would stop compiling at the old revision. Moved with `cargo update -p moon-gpui -p moon-gpui-platform -p moon-ui`; `assert-only-moonui-moved.sh` confirms nothing else moved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Report from the desk: holding Tab while sweeping the pointer across order lines to cancel them makes focus "switch through every window of the terminal" and drops the chart to 5–10 fps.
Mechanism (read in the fork, then measured): the app-level keystroke interceptor cancels the hovered order on Tab and lets the key through otherwise. A held key auto-repeats, and every repeat with nothing under the pointer reached MoonUI Root's
tab->focus_next->Window::refresh— a full window draw per repeat, walking focus through everyMoonButton(all tab stops by default). Render counters under a 3 s hold on--fixture:shell_render1/s -> 22–23/s,frame_drawsthe same, ~137 ms of draw per second on the light fixture layout.Fix: the interceptor reads
KeystrokeEvent::is_held(MoonUIef48635, companion change) and stops a bare Tab or Shift+Tab repeat while a chart is hovered — there Tab is the cancel key. A fresh press with nothing under the pointer still navigates; away from a chart a held Tab keeps its ordinary auto-repeat walk. Measured after:shell_render3/s in the first second (the one press), 1/s for the rest of the hold.The same flag stops a second effect of the repeat: the cancelled line stays on the chart until the core echoes, so every repeat sent the same cancel again (~30/s).
ChartPanel::cancel_hovered_ordertakes the repeat flag and does not resend for the order it already addressed during the current hover;dispatch_hotkey/dispatch_hotkey_atcarry the flag so the Delete route gets it too, while modifier hotkeys and mouse action clicks passfalse.This has been the behaviour since Tab-cancel landed on 2026-07-15 (
a350b065); the focus walk itself comes from MoonUI Root and predates it — not a regression of the last release.Notable decisions
(core, uid)— cleared when the hover changes order or leaves the slot, kept across the line/start-cross halves of one order. A workspace refusal counts as "addressed": a repeat need not ask again.KeystrokeEvent.is_heldis the platform's flag; Windows, macOS and Wayland report repeats, the X11 backend does not (alwaysfalse) — noted on the field, out of scope here.Known limitations
--lockedand a localmainresolves the committed pin, and both would stop compiling at the old revision.assert-only-moonui-moved.shpasses on the diff.Issues
none of the 16 open issues is touched by this change (#493 is Ctrl+Shift+wheel, unrelated)
How to verify
fmt
--checkexit 0 В· build all targets green В· clippy-D warningsstops on the pre-existingbuild.rsdebt before this crate; run without-D, every finding in the touched files sits outside this diff's hunks (none inboot.rs) В· moon-core 1947 + contract targets green, moon-ui-gpui 1799 + theme_contract 331 green (incl. the newa_held_tab_is_spent_before_focus_navigation) В· FireTest not run.Manual:
MOON_RENDER_DIAG=1,--fixture, hold Tab over the chart for 3 s, readlogs/render_diag.login the fixture temp root —shell_renderstays at 1–3/s (was 22–23/s).