[PATCH 0/4] Fix out-of-order keystrokes
Takashi Yano
takashi.yano@nifty.ne.jp
Wed Mar 18 07:35:26 GMT 2026
Hi Johannes,
On Fri, 6 Mar 2026 08:46:40 +0100 (CET)
Johannes Schindelin wrote:
>
> Hi Takashi,
>
> On Tue, 3 Mar 2026, Takashi Yano wrote:
>
> > On Mon, 02 Mar 2026 14:24:36 +0000
> > "Johannes Schindelin wrote:
> > > A Git for Windows user reported that typing in a Bash session while a native
> > > Windows program is running (or has just exited) can produce scrambled input
> > > -- e.g. typing "git log" yields "igt olg":
> > > https://github.com/git-for-windows/git/issues/5632
> > >
> > > I have been experiencing what I suspect is the same bug for a long time in
> > > my tmux sessions: after quitting a pager and immediately pressing cursor-up
> > > to recall the previous command, often followed by Escape+Backspace, the Bash
> > > session simply hangs. I suspect that the escape sequence bytes arrive out of
> > > order, and hence the sequence does not parse, and the terminal hangs. Quite
> > > frustrating, and it happens often enough to be a real productivity drain.
> > >
> > > This bug report was therefore always on my mind, and gaining some good
> > > experience with AI-assisted coding at work finally gave me the push to
> > > investigate properly. I started by writing an AutoHotKey-based UI test (Git
> > > for Windows has a small suite of those; they are not included in this series
> > > because they are specific to our fork). Getting a reliable reproducer
> > > required quite a bit of back-and-forth as the bug is timing-sensitive and
> > > only manifests when pseudo console transitions happen while keystrokes are
> > > in flight.
> > >
> > > The investigation itself was substantial. The total session spread over a
> > > week. To be transparent about the methodology: I used AI (Claude Opus) as an
> > > investigative tool throughout this process. I dictated context and direction
> > > via speech recognition, the AI searched the code, instrumented the code
> > > liberally, and dug into the PTY internals. Every decision about what to
> > > investigate, what to fix and how was mine, the AI merely executed my plans.
> > > I typed very little (leaving typing to Parakeet's speech recognition and to
> > > Claude Opus); the keystrokes are not mine, but the ideas are. For that
> > > reason I use "Assisted-by" rather than "Co-authored-by" trailers in the
> > > commits.
> > >
> > > The root cause is what Opus labeled "pseudo console oscillation" (I called
> > > it "flickering" but agree that "oscillation" is a better term): each time a
> > > native program starts or exits, pcon_activated and pty_input_state change
> > > rapidly, and several code paths in master::write() react by calling
> > > transfer_input() to move data between the cyg and nat pipes. During
> > > oscillation, these transfers steal readline's buffered data from the cyg
> > > pipe, causing characters to arrive out of order.
> > >
> > > My suspicion is that the originally reported bug is fixed entirely by the
> > > first patch (1/4). The remaining three address edge cases that the
> > > reproducer exposed through its more aggressive oscillation pattern. You
> > > might say that I over-deliver a bit, but that seems like a good thing in
> > > this instance.
> > >
> > > I tested both with and without MSYS=disable_pcon to verify that the
> > > scenarios the removed code was originally intended to handle are still
> > > covered by setpgid_aux(). This is even automated in Git for Windows' fork
> > > via the AutoHotKey-based tests; for full details see
> > > https://github.com/git-for-windows/msys2-runtime/pull/124.
> >
> > [...]
> >
> > I tried to reproduce the issue, however I could not yet.
> >
> > Is the issue reproducible in pcon_activated case?
> > Or disable_pcon case?
> >
> > If you can reproduce the issue in cygwin, could you kindly please
> > let me know how to reproduce it?
>
> It is admittedly difficult to reproduce. It took me a good 4 days to get
> to a reliable reproducer. And I failed to do this in manual mode, I had to
> employ the help of AutoHotKey to do it. The result can be seen here:
> https://github.com/dscho/msys2-runtime/blob/fix-jumbled-character-order/ui-tests/keystroke-order.ahk
>
> Unfortunately, it is not quite stand-alone, it requires `powershell.exe`
> in the `PATH`, and
> https://github.com/dscho/msys2-runtime/blob/fix-jumbled-character-order/ui-tests/ui-test-library.ahk
> and
> https://github.com/dscho/msys2-runtime/blob/fix-jumbled-character-order/ui-tests/cpu-stress.ps1
> in the same directory. I just verified that it reproduces even with vanilla
> Cygwin, using the latest AutoHotKey version from
> https://github.com/AutoHotkey/AutoHotkey/releases/tag/v2.0.21. I ensured
> that Cygwin's `bin` directory is first in the `PATH` and then ran, from a
> PowerShell session:
>
> & "<path-to>\AutoHotkey64.exe" /force keystroke-order.ahk "$PWD\log.txt"
>
> What this test does: It runs a small PowerShell script designed to add a
> bit of CPU load and then spawns a Cygwin process (`sleep 1`). While these
> are running, it then types _very_ rapidly four characters, then two
> backspaces, then repeats that quite a few times ("ABXY" then deleting
> "XY", then "CDXY", deleting "XY", etc). The number of characters was
> chosen high enough that this reproducer basically reproduces the issue on
> the first try. The "log.txt" file contains a detailed log including the
> verdict. In my latest test, for example, it shows:
>
> Iteration 1 of 20
> MISMATCH in iteration 1!
> Expected: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
> Got: ABCDEFGHIJKLMNOPQRXSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
>
> You will spot the "X" between "R" and "S", meaning that the backspace was
> not able to remove the "X" because it was routed to the wrong pipe, or
> after the "X" was already consumed.
>
> > In addition, after applying these four patches, non-cygwin apps
> > lose its input. Please try cmd.exe in pcon_activated mode.
>
> When I tried this with the MSYS2 runtime, it simply worked. But when I
> tried it in Cygwin, it reproduced! To be clear, this is the meaning I
> extracted from the quoted text:
>
> Patch 2/4 "Cygwin: pty: Remove pcon_start readahead flush that
> displaces readline data" is too broad, it breaks the scenario when
> in an interactive Bash session in a MinTTY window (without
> `disable_pcon`), `cmd.exe` is launched interactively: You will see
> the typed characters, but `cmd.exe` won't receive them.
>
> And this indeed reproduced here, but only with Cygwin. In MSYS2, it still
> worked with the patches as-are. I will keep investigating, but in the
> meantime I'd like to propose this fixup:
>
> -- snip --
> Subject: [PATCH] fixup! Cygwin: pty: Remove pcon_start readahead flush that
> displaces readline data
>
> ---
> winsup/cygwin/fhandler/pty.cc | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/winsup/cygwin/fhandler/pty.cc b/winsup/cygwin/fhandler/pty.cc
> index 693e1a8062..1a3c50721b 100644
> --- a/winsup/cygwin/fhandler/pty.cc
> +++ b/winsup/cygwin/fhandler/pty.cc
> @@ -2216,6 +2216,11 @@ fhandler_pty_master::write (const void *ptr, size_t len)
> if (!get_ttyp ()->pcon_start)
> { /* Pseudo console initialization has been done in above code. */
> pinfo pp (get_ttyp ()->pcon_start_pid);
> + if (get_ttyp ()->switch_to_nat_pipe
> + && get_ttyp ()->pty_input_state_eq (tty::to_cyg))
> + {
> + get_ttyp ()->pty_input_state = tty::to_nat;
> + }
> get_ttyp ()->pcon_start_pid = 0;
> }
>
> -- snap --
>
> What do you think?
Do you mean removing transfer_input (tty::to_nat, ...) and
just changing pty_input_state to tty::to_nat?
I guess this break your AutoHotKey() test with cmd.exe.
The input before pseudo console setup will be lost.
--
Takashi Yano <takashi.yano@nifty.ne.jp>
More information about the Cygwin-patches
mailing list