Skip to content

fix(tui): enhance flicker prevention for Windows terminals with DECSET 2026#1477

Closed
wplll wants to merge 2 commits into
Hmbown:mainfrom
wplll:fix/windows-flicker-prevention
Closed

fix(tui): enhance flicker prevention for Windows terminals with DECSET 2026#1477
wplll wants to merge 2 commits into
Hmbown:mainfrom
wplll:fix/windows-flicker-prevention

Conversation

@wplll
Copy link
Copy Markdown

@wplll wplll commented May 11, 2026

Summary


This PR addresses flickering issues reported on Windows terminals (ConHost, VSCode integrated terminal) by enhancing the flicker prevention system with terminal capability detection and synchronized
rendering updates.


Problem


Users on Windows terminals experience visible flicker during:

  • Window resize operations
  • Focus switches (Alt+Tab)
  • Streaming output from the model
  • Viewport resets
    
    The root cause is that ratatui's terminal.draw() internally emits \x1b[2J (screen clear) which creates a visible blank frame on terminals with slower rendering pipelines.
    

Solution



1. Terminal Capability Detection (terminal_caps.rs)

  • Auto-detect Windows Terminal, VSCode, and ConPTY environments
  • Determine DECSET 2026 (Synchronized Output) support
  • Provide platform-specific rendering recommendations
    

2. Enhanced Synchronized Updates

  • draw_app_frame(): Wrapped in DECSET 2026 markers (BeginSynchronizedUpdate / EndSynchronizedUpdate) to buffer frames atomically
  • reset_terminal_viewport(): Added synchronized updates to prevent flicker during viewport resets
  • Added error handling and debug logging for terminals that don't support DECSET 2026
    

3. Diagnostic Command

  • New /flicker command shows:
  • Terminal type detection results
  • DECSET 2026 support status
  • Frame rate configuration
  • Active anti-flicker measures
  • Platform-specific recommendations
    

4. Debug Logging

  • Added RUST_LOG=render tracing for rendering operations
  • Log resize events with dimensions
  • Help diagnose flicker issues in the field
    
    Terminal Support:
Terminal DECSET 2026 Support
Windows Terminal ✅ Full support
ConPTY (Win10 1809+) ✅ VT passthrough
VSCode Terminal ✅ xterm.js based

Testing

  1. Test Scenarios:
  • Rapid window resize (drag window edges)
  • Focus switches (Alt+Tab)
  • Wait for streaming output
  • Toggle between fullscreen/windowed
  1. Automated Tests:
  • All existing tests pass (2673 passed, 2 pre-existing failures)
  • New terminal capability detection module includes unit tests
    
    Related Issues
    
  • Fixes flicker reported on Windows ConHost
  • Addresses VSCode terminal rendering issues
  • Improves Ghostty compatibility
    
    Checklist
    
  • Code compiles without warnings
  • All existing tests pass
  • New /flicker command works correctly
  • Debug logging is properly gated behind RUST_LOG
  • No breaking changes to existing functionality
    

wplll and others added 2 commits May 12, 2026 04:02
Add comprehensive flicker prevention measures for Windows terminals:

- Add terminal capability detection module (terminal_caps.rs)
  - Auto-detect Windows Terminal, VSCode, ConPTY support
  - Detect DECSET 2026 synchronized output support

- Enhance draw_app_frame() with synchronized updates
  - Wrap terminal.draw() in DECSET 2026 markers
  - Add error handling and debug logging

- Add synchronized updates to reset_terminal_viewport()
  - Prevent flicker during viewport resets
  - Use swap_buffers() instead of clear()

- Add /flicker diagnostic command
  - Show terminal capabilities and detection results
  - Display DECSET 2026 support status
  - Provide platform-specific recommendations

- Add rendering debug logs
  - Trace draw operations
  - Log resize events with dimensions
  - Help diagnose flicker issues

Fixes flicker issues reported on Windows ConHost and VSCode terminals.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request focuses on improving prefix cache stability and reducing terminal flicker. Key changes include implementing deterministic sorting for tools, MCP resources, diagnostics, and project context packs to ensure stable prompt hashes. It introduces a CacheWarmupKey to track the validity of provider-side caches and enhances the /cache inspect command with verbose diffing and JSON output. To address flicker, the TUI now detects terminal capabilities and utilizes synchronized updates (DECSET 2026) and buffer swapping. Feedback highlights that the recommended frame interval is not yet applied to the rate limiter, the threshold for skipping tool result deduplication may be too high, and there is a contradiction regarding tool inclusion in cache warmup requests.

Comment thread crates/tui/src/tui/ui.rs
Comment on lines 640 to +644
// codex's frame coalescing that maps cleanly onto our poll-based loop.
let mut frame_rate_limiter = crate::tui::frame_rate_limiter::FrameRateLimiter::default();

// Detect terminal capabilities for flicker-free rendering
let terminal_caps = crate::tui::terminal_caps::TerminalCapabilities::detect();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The detected terminal_caps.recommended_frame_interval_ms() is logged but doesn't appear to be used to configure the frame_rate_limiter. For terminals like VSCode (xterm.js) where a lower frame rate (60 FPS / 16ms) is recommended to reduce flicker, the application will still default to its standard rate (likely 120 FPS / 8ms). Consider passing the recommended interval to the limiter initialization.

Comment on lines +1016 to +1024
if original_chars <= TOOL_RESULT_SENT_CHAR_BUDGET {
return WireToolResult {
content: content.to_string(),
original_chars,
sent_chars: original_chars,
truncated: false,
deduplicated: false,
};
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Skipping deduplication for all tool results under 12,000 characters is a significant regression in token efficiency. While it avoids hashing overhead for small strings, 12,000 characters (~3,000 tokens) is quite large. If a medium-sized tool result (e.g., 10k chars) appears multiple times in the conversation history, it will now be sent in full every time, consuming significant context window space. Consider using a much lower threshold for skipping deduplication (e.g., 500-1000 characters) while still allowing truncation to happen at the 12k limit.

Comment on lines +683 to +684
// Note: stable_prefix_parts intentionally excludes tool schema —
// the warmup request does not include tools.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This comment stating that "the warmup request does not include tools" contradicts the implementation of run_cache_warmup in crates/tui/src/tui/ui.rs (line 3077), which explicitly includes the tool catalog. To ensure the PromptInspection and CacheWarmupKey accurately reflect the stable prefix that is actually warmed, the tool schema should be considered part of the stable prefix if it is included in the warmup request.

@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 13, 2026

Thanks for the contribution. I’m keeping the v0.8.33 branch focused on final release polish and not pulling this PR into that branch right now. Leaving it open for review in the next cycle.

@Hmbown
Copy link
Copy Markdown
Owner

Hmbown commented May 23, 2026

This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current main and reopen. 鲸鱼兄弟们等你 🐋

@Hmbown Hmbown closed this May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants