fix: disable high-performance pager rendering by default

HighPerformancePager defaulted to true, wiring bubbles' viewport.HighPerformanceRendering
on by default. That mode is deprecated upstream in Bubble Tea and bypasses the normal
renderer with raw ANSI scroll-region escapes, which several terminals (e.g. kitty) don't
render correctly, causing shuffled/duplicated lines during scroll.

Default it off; GLOW_HIGH_PERFORMANCE_PAGER=true still opts back in.

Fixes #554
This commit is contained in:
Som Samantray 2026-07-30 22:15:38 +05:30
commit e993c35d0e
3 changed files with 87 additions and 1 deletions

View file

@ -15,6 +15,11 @@ type Config struct {
Path string
// For debugging the UI
HighPerformancePager bool `env:"GLOW_HIGH_PERFORMANCE_PAGER" envDefault:"true"`
//
// Defaults to false: bubbletea's high-performance/scroll-region
// rendering is deprecated upstream and known to corrupt output on
// several terminals (e.g. kitty) during scroll. See #554. Users can
// still opt in via GLOW_HIGH_PERFORMANCE_PAGER=true.
HighPerformancePager bool `env:"GLOW_HIGH_PERFORMANCE_PAGER" envDefault:"false"`
GlamourEnabled bool `env:"GLOW_ENABLE_GLAMOUR" envDefault:"true"`
}

46
ui/config_test.go Normal file
View file

@ -0,0 +1,46 @@
package ui
import (
"testing"
"github.com/caarlos0/env/v11"
)
func TestConfig_HighPerformancePagerDefault(t *testing.T) {
t.Setenv("GLOW_HIGH_PERFORMANCE_PAGER", "")
cfg, err := env.ParseAs[Config]()
if err != nil {
t.Fatalf("env.ParseAs[Config]() error = %v", err)
}
if cfg.HighPerformancePager {
t.Errorf("HighPerformancePager default = true, want false (see #554: high-performance rendering is deprecated upstream and corrupts scroll on some terminals)")
}
}
func TestConfig_HighPerformancePagerOptIn(t *testing.T) {
t.Setenv("GLOW_HIGH_PERFORMANCE_PAGER", "true")
cfg, err := env.ParseAs[Config]()
if err != nil {
t.Fatalf("env.ParseAs[Config]() error = %v", err)
}
if !cfg.HighPerformancePager {
t.Error("HighPerformancePager with GLOW_HIGH_PERFORMANCE_PAGER=true = false, want true (opt-in must still work)")
}
}
func TestConfig_HighPerformancePagerExplicitOff(t *testing.T) {
t.Setenv("GLOW_HIGH_PERFORMANCE_PAGER", "false")
cfg, err := env.ParseAs[Config]()
if err != nil {
t.Fatalf("env.ParseAs[Config]() error = %v", err)
}
if cfg.HighPerformancePager {
t.Error("HighPerformancePager with GLOW_HIGH_PERFORMANCE_PAGER=false = true, want false")
}
}

35
ui/pager_test.go Normal file
View file

@ -0,0 +1,35 @@
package ui
import "testing"
// newPagerModel wires viewport.HighPerformanceRendering from the
// package-level config var (set via NewProgram in normal operation).
// These tests set it directly to exercise that wiring in isolation.
func TestNewPagerModel_HighPerformanceRenderingOff(t *testing.T) {
old := config
defer func() { config = old }()
config = Config{HighPerformancePager: false}
common := &commonModel{cfg: config}
m := newPagerModel(common)
if m.viewport.HighPerformanceRendering {
t.Error("viewport.HighPerformanceRendering = true, want false when config.HighPerformancePager is false (see #554)")
}
}
func TestNewPagerModel_HighPerformanceRenderingOptIn(t *testing.T) {
old := config
defer func() { config = old }()
config = Config{HighPerformancePager: true}
common := &commonModel{cfg: config}
m := newPagerModel(common)
if !m.viewport.HighPerformanceRendering {
t.Error("viewport.HighPerformanceRendering = false, want true when config.HighPerformancePager is explicitly true (opt-in must still work)")
}
}