fix: prevent cursor jumps during synchronized redraws - #4310
ogulcancelik wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthrough
Suggested reviewers: Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to The change prevents synchronized redraw positions from being adopted as cursor settle candidates while retaining final cursor state handling. No concrete merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
✅ Action performedReview finished.
|
|
|
@JJLiebig could you test this one? |
|
@ogulcancelik Tested it from this branch, has not solved the issue (at least for me) can try to figure out a way to solve it and post it here / in the issue if it is a small edit. Screen recording Inspelning.2026-09-17.223743.mp4 |
|
@axelalbertkarlsson not saying we shouldn't fix this but the astra "dots" will be removed in the next codex-cli update, it's already removed in alpha cause it created a ton of issues. openai/codex#45137 & gets replaced with openai/codex#46096 |
@JJLiebig Totally fair! With the Astra dots removed the cursor moving is a lot less annoying, but the cursor still moves. Understand if this is not a priority atm |
|
@axelalbertkarlsson no absolutely, I think this is great actually as we can fix the cursor-move-issue and test it with the astra dots - so excellent time to fix it I suppose haha I must say I have the same core issue but because my personal config has the flat | cursor and not the unix-style block one, I never noticed I think. @ogulcancelik can confirm @axelalbertkarlsson's findings, still jumping around. Getting some logging on ConPTY bytes now. |
|
@JJLiebig Ahh nice! Don't know the root cause of this issue but I'll try to see if i can find it, the issue has not been unique to Herdr, have noticed in alot of different repos. |
|
Some extra capture evidence on native Windows 11, Windows Terminal: Environment
Result: the drawn cursor still flashes/jumps while typing in the composer, so the current guard alone is not enough. I captured the raw writes reaching What the capture shows Every synchronized frame arrives as two writes:
One ~30s typing capture:
Representative lines ( The first is Why the new tests pass They split Possible direction Gate on whether the write participated in a synchronized frame at any point, rather than on the mode at the end of the write — e.g. only observe when the write both starts and ends outside synchronized output (or when it contains no Happy to re-run this capture against a new revision. |
|
@JJLiebig & @ogulcancelik This fixed it! https://github.com/axelalbertkarlsson/herdr/tree/fix/codex-cursor-settle Have not tested it on another computer but I guess you could take some inspo from there Fixherdr.1.mp4 |
|
@axelalbertkarlsson tried your commit: It sometimes flickers, sometimes it's fine. Even right now, with a master built exe on laptop, no flicker, but on my desktop it does. Odd. Edit, some notes on Axel's build: Tested From an instrumented build (log-only, reverted after):
Why it still leaks: Also worth noting: the cursor-rendering files are byte-identical between the current release ( Possible direction: treat the frame close as never authoritative on its own — hold the previous settled cursor across |
|
@JJLiebig fuck that's confusing! Classic works on my machine issue then. But I'll try figure out the root cause, and then test on both work/personal laptops |
0882b9d to
bebe833
Compare
bebe833 to
cbb3a40
Compare
|
i reviewed the docstring-coverage warning. these are internal cursor helpers and descriptive regression tests; the non-obvious timing rule already has a comment. i am keeping the code consistent with the repo guidance against redundant comments rather than adding docstrings solely for the coverage percentage. |
|
@axelalbertkarlsson @JJLiebig my gpt is pretty confident on latest patch, tested on a windows wm. could you give it a shot? |
|
lgtm @ogulcancelik 4310.mp4@axelalbertkarlsson can you check the head as well rq? Oh one thing I realized, this was still 0.154, gonna briefly check 0.155 as well Edit: Yep still jumpy, a lot better, but not entirely fixed. 0155_boot.mp4 |
|
@JJLiebig & @ogulcancelik Looks alot better!! The recording did not catch is entirely but when holding down backspace did trigger the flickering a tiny bit but this looks good to me. Inspelning.2026-09-18.172848.mp4 |
|
@JJLiebig I gotta go now, so if you’ve got other higher-priority PRs to get to, I can help you test this more tomorrow. |
|
@axelalbertkarlsson thanks for all the help, got a script to properly tackle this locally and I think there's a few things we could do. |
|
Follow-up for anyone cherry-picking: I pulled the settle logic apart from a raw capture and put a candidate fix on a side branch. Branch: What the capture showed: during Codex start/exit the terminal parks the cursor at column 0 on a row above the composer (clear-and-rehome, The branch holds a candidate that jumps (different row, or >2 column move) for the max window (100 ms) instead of the settle window (20 ms). Ordinary same-row caret steps still settle in 20 ms, so typing is unaffected. It also restarts the churn window after a quiet gap so a finished burst can't adopt a lone sample. Cursor tests pass unchanged, plus a regression test from the trace; Caveat: the repaint is rare and my detector wasn't precise enough for a clean A/B (an early version counted the shell's own prompt cursor; the Codex-gated version skips the transition frames where it actually happens). Treat this as the captured mechanism plus a targeted mitigation, not proof of elimination. Next thing to try: today |
|
Closed in favour of #4389 |

summary
refs #4303
remaining failure reproduced
The initial fix was insufficient. With Windows system ConPTY, a synchronized frame can close at Codex's repair cell, with the real input caret restored in a separate write about 8–11 ms later. Ignoring only positions inside synchronized output does not cover that ordering.
The old settling timer also survived idle gaps. On the next redraw it could immediately publish the temporary repair position instead of preserving the previous quiet candidate. This followup corrects that timing without adding a cursor-intent escape-sequence parser.
live Windows verification
Tested in native Windows Terminal on Windows 11 10.0.26200.9457 using the reporter's exact
JJLiebig/codex0.154.0-fork.5, Astra low, and Herdr's drawn cursor. Each completed recording typed 150 characters over a 25-second recording; no model prompt was submitted.Recordings and raw trace are retained locally. The corrected recordings still show the moving input caret, not a permanently hidden cursor. These are bounded VM observations, not verification on every reporter's machine.
automated validation
just checkpassed after rebasing onto current master: 3,629 tests plus formatting, clippy, Windows cross-target lint, and maintenance/integration/docs checksThe live VM runs preceded the rebase; both cursor/terminal files are byte-for-byte unchanged by the rebase. Native macOS was not tested. The behavior remains Windows-gated. Temporary named sessions/tasks were removed and the VM checkout restored clean.