Read command-history recalls in Wine edit fields

MUSHclient consumes queued Up/Down keys in PreTranslateMessage before the
Edit control receives WM_KEYDOWN. It recalls commands with SetWindowText
followed by SetSel at the end of the replacement. The editor subclass only
refreshed its snapshot for WM_SETTEXT, so the recalled command was silent
or followed by a stray character or blank from the caret update. Recalling
equal-length commands also leaves the final caret position unchanged.

Observe Up/Down for the focused standard Edit control in WH_GETMESSAGE,
excluding Ctrl-modified navigation. Associate the next successful
WM_SETTEXT with that retrieved key and announce the bounded recalled text
as an existing ordered text-read action. Report empty input as blank.
Consume the pending recall after the replacement and suppress the ensuing
EM_SETSEL feedback so each recalled command is announced once.

Reset recall tracking on subsequent retrieved messages, actual focus and
ordinary dispatched navigation. Preserve snapshot refreshes and normal
Left/Right reading after recalls. Keep password and foreground/focus
exclusion in place, leave unrelated programmatic text updates silent, and
check the control class before accessing the shared attachment property
so Scintilla's different state structure is untouched. Both native hook
architectures receive the fix through the existing build.

Extend the Edit fixture with application-side pretranslation of queued
history arrows. Assert the exact ordered feedback for Up/Down, equal-length
entries, rapid recalls, empty input and horizontal navigation afterward.
Require silence for unchanged history boundaries, unrelated programmatic
updates, protected fields and independently unprotected background fields.
Document history behavior and live MUSHclient acceptance steps.

Validation used a private Xorg dummy display, disposable Wine prefixes and
recording D-Bus services, with GUI checks run sequentially:

- cmake --build build --parallel
- ctest --test-dir build --output-on-failure: all four checks passed
- python3 tests/menu_integration.py --build-dir build --fixture edit
- The Edit check with --32-bit, --32-bit --late-helper, and
  --32-bit --restart-helper
- python3 tests/menu_integration.py --build-dir build --fixture winforms
  --32-bit
- python3 tests/menu_integration.py --build-dir build --fixture notepad
- python3 tests/menu_integration.py --build-dir build --fixture menu
  --32-bit
- git diff --check

The new 32-bit history regression failed against the original hook,
recording only blank actions, and passed with the fix. Final 32-bit,
64-bit and Windows Forms editor checks passed, including existing typing,
selection, deletion, Unicode, password and read-only assertions.

Built and installed the helper into the existing user-local installation,
backed up the previous five files and verified the installed artifacts.
The user subsequently confirmed that the installed fix works in MUSHclient.
Physical braille acceptance was not separately established.
This commit is contained in:
deedra committed 2026-10-14 15:46:26 -07:00
1 parent 7d3ac09ea1
commit b808c6686a
5 files changed
+112 -12

No files matched your search

+7
View File
@@ -307,6 +307,13 @@ with tempfile.TemporaryDirectory(prefix="wine-access-menus-") as temporary:
typed = [e[2] for e in text_events if e[1] == "text" and "kind=8" in e[5]]
assert typed == ["z", "z", "space", "\u00e9", "\U0001f600", "new line", "tab", "q", "L", "\U0001f600"], f"typing echo missing or incorrect: {typed!r}"
assert not any(e[1] == "text" and e[2] in ("!", "@", "~", "%") for e in events), "rejected, password or background typing leaked"
history_focus = next(e[0] for e in text_events
if e[1] == "focus" and e[4] == "blank")
history_actions = [e[2] for e in text_events
if e[0] == history_focus and e[1] == "text"]
assert history_actions == ["history north", "history south", "history north", "blank",
"history north", "history south", "history north", "h", "blank", "blank"], \
f"command history missing, reordered, duplicated or leaked: {history_actions!r}"
if args.fixture == "winforms":
assert any(e[2] == "Email" and e[3] == "edit" and e[4] == "alpha beta"
for e in text_events), "managed email label/focus missing"