fix(tui): fill the frame background so the terminal backdrop can't bleed through
The main render path never applied the Screen backdrop, so any sub-view that left a line short or a row empty showed the transparent terminal background. Pad every frame to full width×height with the theme backdrop before display; content stays top-left anchored so caret coords are unaffected.
This commit is contained in:
@@ -41,14 +41,38 @@ const cursorMarker = ""
|
|||||||
// bubbletea v2 the View carries terminal state, so renderRaw() builds the string
|
// bubbletea v2 the View carries terminal state, so renderRaw() builds the string
|
||||||
// and View() resolves the caret to a real blinking cursor + sets the window title.
|
// and View() resolves the caret to a real blinking cursor + sets the window title.
|
||||||
func (m Model) View() tea.View {
|
func (m Model) View() tea.View {
|
||||||
content, cur := splitCursor(m.renderRaw(), " ")
|
content, cur := splitCursor(m.fillFrame(m.renderRaw()), " ")
|
||||||
return tea.View{Content: content, AltScreen: true, Cursor: cur, WindowTitle: m.windowTitle()}
|
return tea.View{Content: content, AltScreen: true, Cursor: cur, WindowTitle: m.windowTitle()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fillFrame guarantees every cell of the width×height frame carries the theme backdrop, so a
|
||||||
|
// sub-view that leaves a line short or a row empty shows the theme background rather than the
|
||||||
|
// terminal-transparent backdrop bleeding through. Pads each line to full width and appends any
|
||||||
|
// missing bottom rows; content stays anchored top-left so caret coordinates are unaffected.
|
||||||
|
func (m Model) fillFrame(s string) string {
|
||||||
|
if m.width <= 0 || m.height <= 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
pad := m.theme.Screen
|
||||||
|
lines := strings.Split(s, "\n")
|
||||||
|
out := make([]string, 0, m.height)
|
||||||
|
for i := 0; i < m.height; i++ {
|
||||||
|
ln := ""
|
||||||
|
if i < len(lines) {
|
||||||
|
ln = lines[i]
|
||||||
|
}
|
||||||
|
if gap := m.width - ansi.StringWidth(ln); gap > 0 {
|
||||||
|
ln += pad.Render(strings.Repeat(" ", gap))
|
||||||
|
}
|
||||||
|
out = append(out, ln)
|
||||||
|
}
|
||||||
|
return strings.Join(out, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
// render returns the frame as a plain string with the caret drawn as the static
|
// render returns the frame as a plain string with the caret drawn as the static
|
||||||
// "▏" glyph — for the preview tool and golden tests, which have no live cursor.
|
// "▏" glyph — for the preview tool and golden tests, which have no live cursor.
|
||||||
func (m Model) render() string {
|
func (m Model) render() string {
|
||||||
content, _ := splitCursor(m.renderRaw(), "▏")
|
content, _ := splitCursor(m.fillFrame(m.renderRaw()), "▏")
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user