mirror of
https://github.com/amnezia-vpn/amneziawg-windows-client.git
synced 2026-10-13 21:34:51 +00:00
[GH-ISSUE #119] ui/syntax/syntaxedit.go: characters/lines don't render while editing (typing, delete-selection) until manual redraw trigger #79
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amnezia-vpn/amneziawg-windows-client#79
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @fr-nt on GitHub (Aug 12, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-windows-client/issues/119
In the tunnel edit dialog, the raw config text editor (
ui/syntax/syntaxedit.go)has a rendering bug where the RichEdit control doesn't visually update after
certain text edits, even though the underlying text buffer is correct.
Reproduced symptoms:
elsewhere in the field or scroll.
line) can leave the deleted line(s) visually on screen until the field is
interacted with again.
correctly, which was the key clue for the root cause below.
This reproduces on both AmneziaWG configs (many
[Interface]/[Peer]parameters, e.g. Jc/Jmin/Jmax/S1-S4/H1-H4/I1-I5) and appears to be present in
upstream
wireguard-windows' identical code as well (unchanged there since~2019-2021), though it's more noticeable here likely because AmneziaWG configs
produce more highlighter spans per
highlightText()pass.Root cause
highlightText()inui/syntax/syntaxedit.gore-colors the entire documenton every
EN_CHANGE, wrapped inWM_SETREDRAW FALSE/TRUEto avoidflicker while it walks every highlight span and calls
EM_SETCHARFORMAT.After re-enabling redraw and issuing a plain
RedrawWindow(...), RichEditsometimes leaves stale glyph state for the region that was actually just
edited — a plain repaint invalidates the painted area but doesn't force
RichEdit to recompute its internal line/wrap layout. Manually resizing the
window works because a resize forces that internal layout recalculation,
which a repaint alone does not trigger.
Fix
Force that same internal layout recalculation programmatically (without an
actual visual resize) by re-sending the control its own current client rect
via
EM_SETRECTright after re-enabling redraw, before restoringscroll/selection. Also restore scroll via
EM_SETSCROLLPOSas before (neededto cancel scroll drift accumulated while the formatting loop moves the
selection across the whole document), followed by an
EM_SCROLLCARETnudgein case the edit itself moved the caret out of view.
Diff (against the current
ui/syntax/syntaxedit.go), applied at the end ofhighlightText():```diff
win.SendMessage(hWnd, win.EM_EXSETSEL, 0, uintptr(unsafe.Pointer(&origSelection)))
win.SendMessage(hWnd, win.EM_HIDESELECTION, win.FALSE, 0)
win.SendMessage(hWnd, win.WM_SETREDRAW, win.TRUE, 0)
win.RedrawWindow(hWnd, nil, 0, win.RDW_ERASE|win.RDW_FRAME|win.RDW_INVALIDATE|win.RDW_ALLCHILDREN)
win.SendMessage(hWnd, win.EM_SETEVENTMASK, 0, win.ENM_CHANGE)
se.idoc.Undo(win.TomResume, nil)
```