mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-14 15:16:40 +00:00
fix(companion): prefs schema corruption, broken multi-scope, stale relay filter, cursor row
Follow-up review of f589b9b2 -- five defects in that commit's own changes.
- repeat_scope_only + repeat_extra_scopes were read/written in the MIDDLE of
the prefs stream, beside their repeat_* siblings. loadPrefsInt()'s rd() is a
plain sequential reader gated only on file.available(), with no per-field
versioning, so on any pre-existing file those 25 bytes were taken from the
fields that follow, shifting EVERY later field: repeater profile (incl. a
float freq), track_shared_loc, all of loc_share_*, trail, bot, GPIO modes.
Moved to the struct/file tail, sentinel bumped to 0xC0DE0027 with 0xC0DE0026
marked burned. sizeof stays 2752 (confirmed by build); the tripwire procedure
now spells out the append-only rule that "in struct order" left implicit.
- rebuildRepeatScopes() called getAutoKeyFor() with id 0 for every entry, but
that cache is keyed on the id alone and ignores the name on a hit -- so every
extra scope after the first silently got the first one's key, making the
comma-separated list do nothing. Distinct id per scope now.
- interference_threshold had no load clamp, so an upgrader read 0x23 (35) out
of the old file's sentinel tail instead of 0.
- CMD_SET_DEFAULT_FLOOD_SCOPE wrote default_scope_key without rebuilding the
relay filter, so setting or clearing the scope from the app left the repeater
filtering on the previous key until reboot. The on-device path already did.
- The keyboard preview derived the cursor's row a second time from byte
offsets, disagreeing with the cursor_line the scroll window already computes:
it pinned the cursor to the end of a full line (drawing '_' one character
past the display width) at every wrap boundary. Use cursor_line directly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -577,18 +577,18 @@ struct KeyboardWidget {
|
||||
// ...and the byte offset that line starts at.
|
||||
int ps = 0;
|
||||
for (int n = first_line * cpl; n > 0 && ps < len; n--) ps += kbUtf8CharBytesAt(buf, ps, len);
|
||||
bool cursor_drawn = false; // draw it on exactly one line, even once the text itself runs out
|
||||
for (int pl = 0; pl < prev_lines; pl++) {
|
||||
int pe = ps; // byte offset cpl codepoints further along (or end of text)
|
||||
for (int k = 0; k < cpl && pe < len; k++) pe += kbUtf8CharBytesAt(buf, pe, len);
|
||||
// cursor_pos == len == pe is the common "typing at the end" case: that's
|
||||
// this line's cursor only if THIS is where the text actually ends (pe ==
|
||||
// len), not just whichever line happens to be the bottom of the preview
|
||||
// area -- short text (fitting in fewer than prev_lines rows) would
|
||||
// otherwise always show the cursor stranded on the last blank row
|
||||
// instead of right after what was just typed.
|
||||
bool cursor_here = !cursor_drawn && ps <= cursor_pos && (cursor_pos < pe || pe == len);
|
||||
if (cursor_here) cursor_drawn = true;
|
||||
// Which row the cursor is on is already decided above, by the same
|
||||
// cursor_chars / cpl the scroll window uses -- just ask it. Deriving it a
|
||||
// second time from byte offsets here is what put the cursor in the wrong
|
||||
// place: "cursor_pos >= ps and this is the bottom row" stranded it on the
|
||||
// last blank row whenever the text was shorter than the preview area,
|
||||
// and "text ends here" instead pinned it to the end of a full line
|
||||
// (drawing the '_' one character past the display width) at every
|
||||
// wrap boundary, where cursor_line has already moved to the next row.
|
||||
bool cursor_here = (first_line + pl == cursor_line);
|
||||
int line_end = (len < pe) ? len : pe;
|
||||
char linebuf[KB_PREVIEW_BYTES + 2]; // cpl codepoints + cursor '_' + NUL
|
||||
if (cursor_here) {
|
||||
|
||||
Reference in New Issue
Block a user