@@ -30,6 +30,28 @@ private struct EnvironmentSnapshot: Equatable {
3030 }
3131}
3232
33+ /// ANSI background codes for each render surface in a frame.
34+ ///
35+ /// Keeping these grouped avoids accidentally rendering every surface
36+ /// with `palette.background` and ignoring palette-specific tokens like
37+ /// `statusBarBackground`.
38+ internal struct RenderBackgroundCodes : Equatable {
39+ /// Main content area background code.
40+ let content : String
41+
42+ /// App header background code.
43+ let appHeader : String
44+
45+ /// Status bar background code.
46+ let statusBar : String
47+
48+ init ( palette: any Palette ) {
49+ self . content = ANSIRenderer . backgroundCode ( for: palette. background)
50+ self . appHeader = ANSIRenderer . backgroundCode ( for: palette. appHeaderBackground)
51+ self . statusBar = ANSIRenderer . backgroundCode ( for: palette. statusBarBackground)
52+ }
53+ }
54+
3355// MARK: - Render Loop
3456
3557/// Manages the full rendering pipeline for each frame.
@@ -178,9 +200,13 @@ extension RenderLoop {
178200 var environment = buildEnvironment ( )
179201 environment. pulsePhase = pulsePhase
180202 environment. cursorTimer = cursorTimer
181- invalidateCacheIfEnvironmentChanged ( environment: environment)
182203
183204 let scene = evaluateAppBody ( environment: environment)
205+ if let paletteOverrideScene = scene as? any RootPaletteOverrideProvidingScene ,
206+ let paletteOverride = paletteOverrideScene. rootPaletteOverride ( ) {
207+ environment. palette = paletteOverride
208+ }
209+ invalidateCacheIfEnvironmentChanged ( environment: environment)
184210
185211 // Determine header height. On the first frame, we perform a measurement
186212 // pass to discover the actual header height before outputting anything.
@@ -329,15 +355,15 @@ private extension RenderLoop {
329355 statusBarHeight: Int ,
330356 headerHeight: Int
331357 ) {
332- let bgCode = ANSIRenderer . backgroundCode ( for : environment. palette. background )
358+ let backgroundCodes = RenderBackgroundCodes ( palette : environment. palette)
333359 let reset = ANSIRenderer . reset
334360 let contentHeight = terminalHeight - statusBarHeight - headerHeight
335361
336362 let outputLines = diffWriter. buildOutputLines (
337363 buffer: buffer,
338364 terminalWidth: terminalWidth,
339365 terminalHeight: contentHeight,
340- bgCode: bgCode ,
366+ bgCode: backgroundCodes . content ,
341367 reset: reset
342368 )
343369
@@ -347,7 +373,8 @@ private extension RenderLoop {
347373 renderAppHeader (
348374 atRow: 1 ,
349375 terminalWidth: terminalWidth,
350- bgCode: bgCode,
376+ environment: environment,
377+ bgCode: backgroundCodes. appHeader,
351378 reset: reset
352379 )
353380 }
@@ -362,7 +389,8 @@ private extension RenderLoop {
362389 renderStatusBar (
363390 atRow: terminalHeight - statusBarHeight + 1 ,
364391 terminalWidth: terminalWidth,
365- bgCode: bgCode,
392+ environment: environment,
393+ bgCode: backgroundCodes. statusBar,
366394 reset: reset
367395 )
368396 }
@@ -406,10 +434,15 @@ private extension RenderLoop {
406434 }
407435
408436 /// Renders the app header at the specified terminal row.
409- func renderAppHeader( atRow row: Int , terminalWidth: Int , bgCode: String , reset: String ) {
437+ func renderAppHeader(
438+ atRow row: Int ,
439+ terminalWidth: Int ,
440+ environment: EnvironmentValues ,
441+ bgCode: String ,
442+ reset: String
443+ ) {
410444 guard let contentBuffer = appHeader. contentBuffer else { return }
411445
412- let environment = buildEnvironment ( )
413446 let headerView = AppHeader ( contentBuffer: contentBuffer)
414447
415448 let context = RenderContext (
@@ -431,8 +464,13 @@ private extension RenderLoop {
431464 }
432465
433466 /// Renders the status bar at the specified terminal row.
434- func renderStatusBar( atRow row: Int , terminalWidth: Int , bgCode: String , reset: String ) {
435- let environment = buildEnvironment ( )
467+ func renderStatusBar(
468+ atRow row: Int ,
469+ terminalWidth: Int ,
470+ environment: EnvironmentValues ,
471+ bgCode: String ,
472+ reset: String
473+ ) {
436474 let palette = environment. palette
437475
438476 let highlightColor =
0 commit comments