fix(cli): remove theme background fills from input box and user messages#5772
Conversation
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Thanks for the PR, @chiga0! 👋
The PR body doesn't follow the pull request template. A few required sections are missing:
## What this PR doesand## Why it's needed— your## Summaryand## Whycover the content, but please use the exact template headings so reviewers can scan quickly.## Reviewer Test Plan— this is the big one. It needs### How to verify(steps a reviewer can follow),### Evidence (Before & After)(screenshots or tmux output showing the color block before and after the fix), and### Tested on(OS matrix). Since this is a visual/TUI change, before-and-after evidence is essential for reviewers to confirm the fix without running it themselves.## Risk & Scope— main risk, what's out of scope, any breaking changes.## Linked Issues— you mention "Fixes #5771" in the body (which is great), but please put it in the dedicated section.
Could you update the PR description to match the template? The content is already there — it mostly just needs reorganizing under the right headings, plus the test plan and evidence sections. Happy to take another look once that's done. 🙏
中文说明
感谢 PR,@chiga0!👋
PR 描述没有按照 pull request 模板 来写,缺少几个必填部分:
## What this PR does和## Why it's needed— 你的## Summary和## Why内容都有了,但请使用模板中的确切标题,方便审查者快速浏览。## Reviewer Test Plan— 这是最重要的部分。需要包含### How to verify(审查者可以跟随的步骤)、### Evidence (Before & After)(截图或 tmux 输出,展示修复前后的色块对比)和### Tested on(操作系统矩阵)。因为这是视觉/TUI 变更,前后对比证据对审查者确认修复效果至关重要。## Risk & Scope— 主要风险、不在范围内的内容、是否有破坏性变更。## Linked Issues— 你在正文提到了 "Fixes #5771"(很好),但请放在专门的章节里。
能否按照模板更新一下 PR 描述?内容基本都有了,主要是重新组织到正确的标题下,再加上测试计划和证据部分。更新后我会再看一次。🙏
— Qwen Code · qwen3.7-max
bd4d387 to
18e368a
Compare
chiga0
left a comment
There was a problem hiding this comment.
Overview
Final Verdict: LGTM — Clean, focused bug fix. The approach is correct: since the TUI never paints its own background, the two flood-fills (input box and user-message band) were inherently inconsistent across terminals and themes. Removing them and letting everything render on the terminal's own background is the right fix.
Cross-Validation
| # | Finding | Reviewer | My Assessment |
|---|---|---|---|
| C1 | PR template format (missing ## What this PR does / ## Why it's needed sections) |
qwen-code-ci-bot | Format issue, not code — the PR body has equivalent content under different headings (## Summary, ## What was wrong). Non-blocking for code quality. |
No unique Critical, Major, or Minor findings from my independent review.
Additional Audit Coverage
Areas I independently verified beyond existing findings:
- Cursor visibility:
getEffectiveTerminalBackground()returns#000000(dark) or#ffffff(light) based solely on terminal type. Software cursor derives contrast from this — light cursor on dark terminal, dark cursor on light terminal. Correct regardless of active theme. - UserMessage width prop: The simplified component no longer destructures
width. Callers passingwidthare unaffected (extra props are ignored). The fallbackmarginTop={1}provides consistent visual separation without background dependency. <Static>commit issue: The PR description correctly identifies that<Static>commits rows and never repaints, making the band inconsistent across theme switches. This is a fundamental limitation that cannot be worked around — removing the band is the only correct fix.- Custom/ANSI themes:
getTerminalBackgroundType()returns'dark'by default for unclassified themes.getEffectiveTerminalBackground()returns#000000in this case — cursor gets light contrast. Safe default. - Test coverage: 3 tests for
getEffectiveTerminalBackground(light terminal, dark terminal, theme-independent). 3 tests for software cursor contrast (dark terminal, light terminal, theme-agnostic). Comprehensive for the scope. - Net deletion (+53/-216): Confirms this is a simplification, not a replacement. No hidden behavior changes.
This review was generated by QoderWork AI
The TUI paints no background of its own and relies on the terminal's own background. Two elements broke that and rendered as off-colour blocks that could not be made consistent across terminals and themes: - The input box (QwenLM#5568) flood-filled theme.background.primary. Even when the theme's light/dark bucket matched the terminal (the QwenLM#5746 gate), the exact colour usually differed from the terminal's real background, so the prompt rendered as a distinct block — worst over SSH/remote where brightness detection is unreliable and defaults to dark. - The user-message half-line band (QwenLM#4595) painted a subtleBandColor band behind each user message, gated on the same theme/terminal match. Because history is rendered through Ink <Static> (committed rows are never repainted) and the gate only fires when the active theme matches the terminal, the band showed on some messages but not others across a theme switch — it cannot be made consistent. Stop painting both so the input area and user messages blend into the terminal background everywhere. User messages fall back to marginTop=1 for separation. The software cursor now derives its contrast from the terminal's detected brightness (getEffectiveTerminalBackground) so it stays visible with no fill painted. Also remove the band's now-unused helpers — subtleBandColor and supportsTrueColor (added by QwenLM#4595) and the dead UserMessageProps.width prop. Fixes QwenLM#5771. Generated with AI Co-authored-by: Qwen-Coder <[email protected]>
18e368a to
edc70f6
Compare
chiga0
left a comment
There was a problem hiding this comment.
No review findings. Downgraded from Approve to Comment: self-PR; CI still running. Clean removal — all dead code (width prop, subtleBandColor, supportsTrueColor) properly cleaned up, tests pass, cross-file references fully updated.
— qwen3.7-max via Qwen Code /review
| @@ -205,70 +199,19 @@ const ContinuationMarkdownMessage: React.FC< | |||
| ); | |||
There was a problem hiding this comment.
[Suggestion] The simplified UserMessage only destructures { text }, but UserMessageProps (line 32) still declares width?: number and HistoryItemDisplay.tsx:237 still passes width={contentWidth} — the prop is silently ignored. Consider removing width from the interface and updating the caller so TypeScript enforces a clean contract.
— qwen3.7-max via Qwen Code /review
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
No new review findings. Clean, focused simplification — removes two background fills that could never match the terminal consistently, consolidates the helper into a single terminal-derived function, and tests are updated accordingly. All 23 relevant tests pass. Downgraded from Approve to Comment: CI still running.
— qwen3.7-max via Qwen Code /review
yiliang114
left a comment
There was a problem hiding this comment.
LGTM. The removal is the right fix — the two flood-fills were never going to be consistent across terminals/themes, and deriving cursor contrast from the terminal type instead of the never-painted theme background is correct.
Verified on the PR branch:
- All five removed symbols (
getInputBackgroundFill,themeBackgroundMatchesTerminal,getEffectiveInputBackground,subtleBandColor,supportsTrueColor) have no remaining references anywhere in the repo, and no orphaned imports (Lint is green). - The only Ink
UserMessagecall site (HistoryItemDisplay) dropswidthtoo; the other<UserMessage>/<UserMessageBubble>matches are unrelated components in other packages. - Ran the affected suites locally — 76 passing (
theme-background,software-cursor,color-utils,ConversationMessages,BaseTextInput,HistoryItemDisplay).
Two non-blocking notes:
interpolateColorno longer has any non-test caller now thatsubtleBandColoris gone — kept as a generic primitive, which is fine, just flagging it's currently dead outside its own test.- +1 on the bot's ask for Before/After evidence. For a visual change like this, a quick before/after (the off-colour block vs. clean background) is what lets reviewers confirm without running it.
|
Thanks for the PR, @chiga0! Template: the CI bot already flagged the missing headings — I won't duplicate that. The substance is all here. On direction: solid. This fixes a real visual bug — the input box and user-message band render as off-colour blocks that can never be made consistent across terminals and themes. Removing the fills and letting everything render on the terminal's own background is exactly the right approach. It aligns with the TUI's core design principle of not painting its own background. Claude Code's CHANGELOG shows similar theme/rendering fixes have been a recurring pain point there too. On approach: focused and minimal — net -238 lines across 9 files. Every change traces directly to the stated goal: remove the two fills, clean up the now-dead utilities ( Moving on to code review. 🔍 中文说明感谢贡献! 模板:CI bot 已经指出缺少的标题,不重复了。内容都在。 方向:正确。修复了一个真实的视觉 bug —— 输入框和用户消息背景色块在不同终端/主题下无法一致。移除填充色、让内容直接渲染在终端背景上,完全符合 TUI 不绘制自身背景的核心设计原则。Claude Code 的 CHANGELOG 中也有类似的主题/渲染修复记录。 方案:精简且聚焦 —— 净减少 238 行,9 个文件。所有改动都直接服务于目标:移除两处填充、清理已废弃的工具函数、更新软件光标对比度来源。无范围蔓延,无顺手重构。放弃紧凑间距换取跨终端一致性的取舍合理。 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewClean subtraction. I read the diff against my independent proposal (which was: remove the two No correctness issues. The cascading clean-up is thorough: One observation worth noting (not a blocker): TestingUnit tests: all 36 tests pass across the three changed test files ( Interactive TUI — Before (installed build, v0.19.1): The Interactive TUI — After (PR code): could not run interactively. The build fails on both main and the PR branch with a pre-existing The code change is straightforward enough that the visual outcome is predictable: removing — Qwen Code · qwen3.7-max |
|
This is a clean, well-scoped bug fix. The motivation is real — I confirmed the off-colour band rendering in the installed build's interactive TUI. The approach is the simplest possible fix: remove the two problematic fills entirely and let the terminal's own background do the work. Net -238 lines, no new abstractions, no scope creep. The code reads like it was written by someone who understood the full blast radius of the removal. Every dead code path — The trade-off (losing the tighter band spacing) is intentional and well-documented. Consistency across terminals beats aesthetic tightness that only works some of the time. I couldn't run the PR code interactively due to a pre-existing build environment issue ( The template format issue flagged by the CI bot is minor — the substance is all there. Once the author addresses the heading format, this is ready. LGTM ✅ 中文说明这是一个干净、范围合理的 bug 修复。动机真实 —— 我在已安装版本的交互 TUI 中确认了偏色背景带的渲染问题。方案是最简路径:完全移除两处有问题的填充色,让终端自身背景承担渲染。净减少 238 行,无新抽象,无范围蔓延。 代码清理彻底:所有废弃代码路径( 放弃紧凑间距换取跨终端一致性是有意为之且有文档记录的权衡。 由于构建环境的已有问题( CI bot 指出的模板格式问题是小问题 —— 实质内容都在。作者修正标题格式后即可合并。 可以合并 ✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
Summary
The TUI paints no background of its own and relies on the terminal's own background. Two elements broke that and rendered as off-colour blocks that cannot be made consistent across terminals and themes, so this PR removes both.
Fixes #5771.
The two offenders
Input box (
BaseTextInput, since fix(cli): fill content area background on wrapped input lines #5568) flood-filledtheme.background.primary. Even when the theme's light/dark bucket matched the terminal (the fix(cli): only paint theme background when it matches the terminal #5746 gate), the exact colour usually differed from the terminal's real background, so the prompt rendered as a distinct off-colour block — worst over SSH/remote where brightness detection is unreliable and defaults to dark.User-message half-line band (
UserMessage, since fix(tui): Tighten message and tool spacing #4595) painted asubtleBandColorband behind each user message, gated on the same theme/terminal match. Because history is rendered through Ink<Static>(committed rows are never repainted) and the gate only fires when the active theme matches the terminal, the band appeared on some messages but not others across a theme switch — see below.Why the band can't be consistent
themeBackgroundMatchesTerminal()only paints the band when the active theme's brightness matches the terminal. On a dark terminal: qwen-dark messages get the band, qwen-light messages don't. And<Static>means a theme switch never repaints already-committed messages, so a single screen can show banded and un-banded user messages side by side.What changed
BaseTextInput.tsx: drop thebackgroundColorfill on the input content area.ConversationMessages.tsx:UserMessageno longer paints a band; it renders directly on the terminal background and falls back tomarginTop={1}for separation (consistent across all themes).theme-background.ts: remove the now-unusedgetInputBackgroundFill/themeBackgroundMatchesTerminal; replacegetEffectiveInputBackgroundwithgetEffectiveTerminalBackground, which derives a brightness-representative colour purely from the terminal's detected dark/light type.software-cursor.ts: the software cursor derives its contrast fromgetEffectiveTerminalBackground()so it stays visible now that no fill is painted.color-utils.ts: remove the band's now-unusedsubtleBandColor/supportsTrueColorhelpers (added by fix(tui): Tighten message and tool spacing #4595), plus the deadUserMessageProps.widthprop and its call site inHistoryItemDisplay. The genericinterpolateColorprimitive is kept.Tests
theme-background.test.tsforgetEffectiveTerminalBackground(terminal-derived, theme-independent).software-cursor.test.tsdefault-contrast cases to assert terminal-derived cursor contrast.BaseTextInput/ConversationMessages/HistoryItemDisplaysuites pass (they assert text content, not fills).Trade-off
This removes the user-message half-line band introduced in #4595 along with its tighter spacing; user messages revert to a single
marginTopline for separation. That is intentional: consistent, background-free rendering across all terminals/themes was preferred over a band that only renders in matching theme/terminal combinations.