From e993c35d0e99e3cd385a738f407a97588381baa5 Mon Sep 17 00:00:00 2001 From: Som Samantray Date: Thu, 30 Jul 2026 22:15:38 +0530 Subject: [PATCH] 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 --- ui/config.go | 7 ++++++- ui/config_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ ui/pager_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 ui/config_test.go create mode 100644 ui/pager_test.go diff --git a/ui/config.go b/ui/config.go index 001d5b8..890b63b 100644 --- a/ui/config.go +++ b/ui/config.go @@ -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"` } diff --git a/ui/config_test.go b/ui/config_test.go new file mode 100644 index 0000000..575c0a3 --- /dev/null +++ b/ui/config_test.go @@ -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") + } +} diff --git a/ui/pager_test.go b/ui/pager_test.go new file mode 100644 index 0000000..737cd5d --- /dev/null +++ b/ui/pager_test.go @@ -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)") + } +}