feat(tui): prompt to power-cycle, show read/write progress, and fix the port box - #2
Merged
Merged
Conversation
…he port box
Three things from the bench, plus what the typing lag turned out to be.
**The power-cycle instruction is a prompt now.** It was a line in the log, which
is the wrong place for the one thing the operator has to go and do to the
hardware. A read or a write puts it on the screen, and takes it down again by
itself the moment the radio answers - the normal case needs no keystroke at all.
Cancel, or Esc, abandons the operation instead of sitting through the remaining
90-second wait. Anything that dismisses the box counts as cancelling, so Esc
cannot leave a read running invisibly.
**Read and write show progress**, from the library rather than guessed at:
TaitProgrammer now raises a ProgrammerProgress with a phase, a count and a total
- sections for a read, records for a write - and takes a CancellationToken.
Cancelling a write is only honoured up to the point where the write block opens.
Past that the radio's codeplug is being modified and stopping half way would
leave the block open and the codeplug partly applied, which is worse than
finishing, so a started write always runs to its commit. Two tests hold both
halves of that.
Progress redraws are throttled: a write is over a thousand records, and with
Terminal.Gui repainting the whole screen for any change (see below), an
unthrottled bar would push a thousand full repaints down an SSH link and become
the slowest thing in the write.
**The port box would not accept typing.** DropDownList defaults to ReadOnly,
which makes it a picker rather than the combo box it looks like, so on a machine
where the radio's port does not enumerate there was no way to name one and the
interactive mode could not be used at all. The README has claimed since 0.6.0
that a port which did not enumerate can be typed in; now it can.
**On the typing lag itself**: it is Terminal.Gui, and it is not something this
app can fix. Every character typed into a text box repaints the entire screen,
measured at ~7-8 bytes per cell:
80x24 ( 1920 cells) 13,428 bytes per typed character
100x30 ( 3000 cells) 21,826
120x40 ( 4800 cells) 36,885
200x50 (10000 cells) 81,658
A minimal Terminal.Gui app - one window, one text field, nothing else - does the
same, so it is not this UI; 2.4.18-develop.31 does the same, so it is not a
version bump away. On a maximised terminal over SSH, 82 KB a character is the
second or two per keystroke that typing a frequency felt like. Caret moves and
backspace are ~135 bytes, which is why only insertion feels slow.
Tried and rejected: disabling the dialog's shadow, the superview line canvas,
the field's autocomplete and its suggestion generator; an in-window overlay
instead of a modal; a hand-written single-line field that only marks itself
dirty (any redraw at all costs a full frame, so it bought nothing and lost
selection and clipboard). The DOTNET driver is cheaper than the ANSI one (15 KB
against 22 KB) but still a whole-screen repaint.
Documented in the README with the three things that do help: a smaller terminal
while editing, `patch <port> ch0.rxfreq <MHz>` instead of the editor, or running
the tool on the machine the radio is plugged into.
Verified end to end against a fake TM8100 on a pty: the prompt appears, dismisses
itself when the radio answers, and Cancel and Esc both abandon the read cleanly;
a 265-record read and a 168-record write both complete with the bar moving and
clearing afterwards.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkDFej82QnbjMJYFcwYyAZ
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.
The three things from the bench, plus a diagnosis of the typing lag and a bug found on the way.
The power-cycle instruction is a prompt, not a log line
It was a line in the log, which is the wrong place for the one thing you have to go and do to the hardware. A read or a write now puts it on screen:
It dismisses itself when the radio answers, so the normal case needs no keystroke. Cancel or Esc abandons the operation rather than sitting through the rest of the 90-second wait. Anything that dismisses the box counts as cancelling, so Esc cannot leave a read running invisibly behind a closed prompt (it could, in the first cut of this).
Read and write show progress
writing 52% (88/168)next to the buttons, with a bar. The numbers come from the library rather than being guessed at:TaitProgrammerraises aProgrammerProgress(phase, done, total) and takes aCancellationToken.Cancelling a write is honoured only up to the point where the write block opens. Past that the radio's codeplug is being modified, and stopping half way would leave the block open and the codeplug partly applied, which is worse than finishing - so a started write always runs to its commit. Both halves of that are tested.
The bar is throttled to a few redraws a second. That matters more than it sounds: a write is over a thousand records, and for the reason below, an unthrottled bar would push a thousand full-screen repaints down an SSH link and become the slowest thing in the write.
The port box would not accept typing
DropDownListdefaults toReadOnly, which makes it a picker rather than the combo box it looks like. On a machine where the radio's port does not enumerate - which a plain USB-serial cable often does not - there was no way to name one, so interactive mode could not be used at all. The README has claimed since 0.6.0 that a port which did not enumerate can still be typed in. Now it can.The typing lag: it is Terminal.Gui, and this app cannot fix it
Every character typed into a text box repaints the entire screen. Measured, median of three, on the real binary behind a pty that answers the driver's queries:
That is ~7-8 bytes per cell on screen, per keystroke, and it scales linearly with the window. On a maximised terminal over SSH, 82 KB a character is a second or two per keystroke. Caret moves and backspace in the same field cost ~135 bytes, which is why only insertion feels slow.
It is not this UI: a minimal Terminal.Gui app (one window, one text field, nothing else) does exactly the same. It is not a version away: 2.4.18-develop.31 behaves identically. Tried and rejected on the way to being sure:
The README now says so, with the three things that do help: a smaller terminal window while editing (80x24 costs a sixth of 200x50),
tait-codeplug patch <port> ch0.rxfreq 144.812500instead of the editor, or running the tool on the machine the radio is plugged into.Testing
77 tests, up from 66. New: progress and cancellation against the scripted-radio double (including that a cancelled write never opens the block, and that a started one always commits), and the redraw throttle.
Verified end to end against a fake TM8100 served on a pty: the prompt appears and dismisses itself when the radio answers; Cancel and Esc both abandon cleanly and leave the app usable; a 265-record read and a 168-record write both complete with the bar moving and clearing afterwards.
Merging this wants a
v0.7.0tag; the CHANGELOG section is written.🤖 Generated with Claude Code
https://claude.ai/code/session_01FkDFej82QnbjMJYFcwYyAZ