fix(tui): enhance flicker prevention for Windows terminals with DECSET 2026#1477
fix(tui): enhance flicker prevention for Windows terminals with DECSET 2026#1477wplll wants to merge 2 commits into
Conversation
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>
There was a problem hiding this comment.
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.
| // 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(); |
There was a problem hiding this comment.
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.
| if original_chars <= TOOL_RESULT_SENT_CHAR_BUDGET { | ||
| return WireToolResult { | ||
| content: content.to_string(), | ||
| original_chars, | ||
| sent_chars: original_chars, | ||
| truncated: false, | ||
| deduplicated: false, | ||
| }; | ||
| } |
There was a problem hiding this comment.
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.
| // Note: stable_prefix_parts intentionally excludes tool schema — | ||
| // the warmup request does not include tools. |
There was a problem hiding this comment.
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.
|
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. |
|
This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current |
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:
The root cause is that
ratatui'sterminal.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)
2. Enhanced Synchronized Updates
draw_app_frame(): Wrapped in DECSET 2026 markers (BeginSynchronizedUpdate/EndSynchronizedUpdate) to buffer frames atomicallyreset_terminal_viewport(): Added synchronized updates to prevent flicker during viewport resets
3. Diagnostic Command
/flickercommand shows:
4. Debug Logging
RUST_LOG=rendertracing for rendering operations
Terminal Support:
Testing
Related Issues
Checklist