[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