[BUG] Android soft-keyboard show/hide corrupts TUI frames — 100% reproducible, Ctrl+L recovers (2.1.267)
Description
Claude Code's TUI misrenders on Android every time the soft keyboard is dismissed and then reopened. This is 100% reproducible — not an occasional glitch, it happens on every keyboard toggle.
Previously rendered frames are re-emitted on top of the current frame. Observed effects:
- Text from earlier output reappears inside the input region, mixed character-by-character with what is being typed
- Box borders are duplicated or drawn at the wrong rows
- List menus become unusable: the
AskUserQuestionoption list renders offset, and the highlight marking the selected row is not visible, so the user cannot tell what is selected or confirm a choice
Ctrl+L recovers the display immediately and completely. The corruption returns on the next keyboard toggle.
Environment
- Claude Code 2.1.267 (native glibc binary, aarch64)
- Host: Android 13 (Xiaomi M2012K11AC, aarch64)
- Claude Code runs as a native glibc binary inside a Debian trixie chroot, launched from Termux. Termux itself cannot host it (bionic vs glibc — see #50270).
- Terminal emulator: Termux's built-in terminal, using the Android on-screen (soft) keyboard
TERM=xterm-256color,COLORTERM=truecolor; tmux is not used- Config:
tuileft atdefault(not fullscreen), customstatusLinecommand
Steps to reproduce
- Start
claudein the Termux terminal (inside the Debian chroot). - Tap the prompt to raise the soft keyboard, then dismiss it.
- Tap again to reopen the keyboard.
- The frame is corrupted. Reproduces 100% of the time, first toggle.
Expected
Reopening the keyboard reflows and repaints the current frame; content that has scrolled off remains in scrollback.
Actual
Stale frames accumulate over the current one in the visible region. It does not self-correct: Esc, arrow keys and further typing do not clear it. Only a forced full repaint does — Ctrl+L works, and it works every time.
How this differs from #29937
#29937 reports overlapping text that Ctrl+L and tmux redraw cannot fix, and explicitly states that resizing is not the trigger. Here the trigger is deterministic (soft keyboard show/hide, 100%) and Ctrl+L does recover it. That points at a stale frame buffer / diffed repaint rather than a permanently desynchronised virtual buffer, which is a meaningfully different failure mode.
Suspected cause
Soft-keyboard show/hide changes the terminal's row count and emits SIGWINCH on every toggle. The incremental repaint pipeline renders a diff against the frame it believes is on screen, but the terminal has reflowed underneath it, so the diff is applied at the wrong rows. Ctrl+L forces a full repaint, which is consistent with it recovering reliably.
Related issues
- #29937 — tmux overlap corruption: same symptom class, different trigger, not
Ctrl+L-fixable - #46834 — SIGWINCH relayout spills the transcript into scrollback as duplicates (macOS)
- #42010 — Ink frame-buffer contamination during streaming; resize is the documented workaround there
- #86775 — background sessions never receive SIGWINCH
Notes
Android/Termux is not an officially supported platform, so I understand if this is deprioritised. Filing it because the resize-triggered corruption class keeps surfacing in the tracker, and this instance has an unusually clean reproduction (a deterministic trigger plus a working workaround) that might help localise it.
No screenshot or recording attached — happy to provide one, or a minimal repro, if useful.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗