Fix: Blank screen after Resume() — tcell cell cache not invalidated - lazydocker warp | kitty terminals related#101
Open
AbrhamSayd wants to merge 2 commits intojesseduffield:masterfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
This is a proposed fix for a blank screen issue reported in
jesseduffield/lazydocker(#611) where pressingctrl+eto exec into a container shell and then exiting causes lazydocker to show a blank, unresponsive screen. The issue has been reproduced on Warp and Kitty terminals.The root cause appears to be in how
Resume()re-engages the terminal after a subprocess exits.Suspected Root Cause
Resume()delegates tog.screen.Resume(), which calls tcell'sengage(). Insideengage(), the physical screen is cleared:tcell tracks what it last wrote to the terminal in an internal cell cache.
engage()clears the physical screen but never invalidates that cache. When gocui'sflush()runsScreen.Show(), tcell diffs the draw buffer against the stale cache, finds nothing dirty, and writes nothing — the screen stays blank.flush()has one invalidation path, but it only fires on a terminal resize:If the terminal size didn't change during the subprocess (the common case), no invalidation happens and the stale cache persists.
Proposed Fix
Call
g.screen.Sync()afterg.screen.Resume().Sync()invalidates the entire cache and forces a full redraw:Diff:
func (g *Gui) Resume() error { - return g.screen.Resume() + if err := g.screen.Resume(); err != nil { + return err + } + // engage() clears the physical screen but leaves tcell's "last drawn" + // cache stale. Sync() invalidates it so the next Show() does a full redraw. + g.screen.Sync() + return nil }This change was tested locally against the lazydocker reproduction case and resolved the blank screen. Testing was done on Warp (macOS), Warp (Windows), and WSL2 under Debian. Broader testing across other terminals and platforms is welcome.