fix: reduce paste_suppress_until window from 2s to 200ms (closes #237)#238
Conversation
The 2s window silently drops every typed character on Windows for 2 seconds whenever any of five paste-detection code paths fires. Fast typing fills paste_pend faster than the 300ms stage2 quiet period, so normal typing bursts get misclassified as paste and the next 2s of input is dropped. User observation: type → nothing appears → wait a couple of seconds → typing resumes. ConPTY's async clipboard-inject race (the original reason for the suppression) resolves in under 50ms. A 200ms window keeps a 4x margin over the race it guards while being well below human-perceptible typing latency. No behavior change for paste: tested single-line, multi-line, and rapid sequential Ctrl+V — all deliver once, no duplication. Closes #237
|
Thank you @tarikguney for this excellent fix and your thorough analysis in #237. Your bisect to We ran independent E2E validation to prove both the bug and the fix: Bug ConfirmedTwo test suites proved the 2s suppression window was silently dropping legitimate keystrokes:
Fix ValidatedAfter applying your change, we verified:
The 200ms window still provides a 4x safety margin over ConPTY's async inject race (resolves in under 50ms) while eliminating the human-perceptible typing freeze. Test files for reproduction:
Thanks for the quality contribution. Merged with Co-authored-by credit. |
- typing_bench.cs: cursor-position-based render latency monitor (500Hz) - burst_bench2.cs: full screen buffer char-count monitor - injector_batch.cs: batch keystroke injector - timed_injector.cs: timestamped keystroke injector - typing_benchmark.cs, burst_benchmark.cs: earlier benchmark tools - cursor_bench.cs: cursor tracking prototype - test_realistic_typing.ps1: multi-speed typing benchmark (8/12/20ms) - test_burst_typing_benchmark.ps1: burst speed comparison - test_long_paragraph_benchmark.ps1: long text render test - test_typing_render_latency.ps1: capture-pane render latency - test_typing_benchmark.ps1: basic typing speed test - test_sustained_fast_typing.ps1: sustained typing stress test - test_issue237_final_proof.ps1: issue #237 freeze reproduction - test_issue237_typing_freeze.ps1: issue #237 debug validation - test_issue237_typing_freeze_perf.ps1: issue #237 perf variant - test_issue197_paste_validation.ps1: issue #197 paste validation These tests proved: - Issue #237 typing freeze (2s suppress window, fixed in PR #238) - Issue #197 paste behavior validated (6 test scenarios) - 15ms P50 overhead at fast typing speeds vs direct PowerShell - Root cause: 20ms paste_pend buffer delays every keystroke
Modified typing test suites to include proper test result markers: - test_realistic_typing.ps1: Validates zero-latency optimization - test_burst_typing_benchmark.ps1: Validates PR #238 fix - test_typing_render_latency.ps1: Detects typing freezes - test_typing_benchmark.ps1: Compares vs direct PowerShell latency - test_long_paragraph_benchmark.ps1: Validates smooth rendering - test_sustained_fast_typing.ps1: Tests multiple speed tiers All tests now output [PASS]/[FAIL] markers compatible with the run_all_tests.ps1 test runner, allowing typing tests to be included in automated full test suite runs with proper result aggregation.
Summary
paste_suppress_untilwindow insrc/client.rsfrom 2 seconds to 200 milliseconds across all 6 call sites.3bf380d).Why
paste_suppress_untilblocksKeyCode::Char(c)events while the window is in the future (pre-existing check atsrc/client.rs:2079–2107). Commit3bf380d(#197) added five new call sites that set this window tonow + 2s, includingSTAGE2_TIMEOUT— which fires whenpaste_pendaccumulates typed chars without a Ctrl+V within 300ms. That is the exact pattern of normal fast typing, so fast typing trips the stage2 heuristic, sets a 2-second suppression window, and silently drops every subsequent keystroke for 2 seconds. See #237 for the full bisect and root-cause analysis.The 2-second window is far longer than the race it guards. Original motivation (#197): ConPTY may inject clipboard characters asynchronously after a Ctrl+V Release event arrives, so a subsequent
Event::Paste/ stage2 burst could cause a double-send. This async inject completes in well under 50ms on tested Windows 11 systems. 200ms is a comfortable margin while staying below human-perceptible typing latency.Test plan
Tested on Windows 11 / pwsh 7 / Windows Terminal 1.23 / PSReadLine 2.4.5:
hello worldarrives exactly once.Risk / rollout
KeyCode::Charsuppression check entirely and rely onpaste_pendtiming plus bracketed-pasteEvent::Pastefor dedup. Happy to switch to that approach.Closes #237