From 6e65d867dc8e835aa24c76dfe59bbe9c30e1f051 Mon Sep 17 00:00:00 2001 From: Cyrus Date: Sun, 19 Jul 2026 23:53:02 +0800 Subject: [PATCH] Detect terminal resize on Windows (fix #4790) Windows has no SIGWINCH and notifyOnResize was an empty TODO, so fzf running in --height mode never noticed console size changes. Poll the console screen buffer dimensions every 100ms and push a signal through the same channel SIGWINCH uses on Unix. Full-screen mode is unaffected as it goes through tcell which emits its own resize events. --- src/terminal_windows.go | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/terminal_windows.go b/src/terminal_windows.go index 9b200aaa..1325a49f 100644 --- a/src/terminal_windows.go +++ b/src/terminal_windows.go @@ -4,10 +4,48 @@ package fzf import ( "os" + "syscall" + "time" + + "golang.org/x/sys/windows" ) +const resizePollInterval = 100 * time.Millisecond + +type resizeSignal struct{} + +func (resizeSignal) String() string { return "resize" } +func (resizeSignal) Signal() {} + +// Windows has no SIGWINCH, so poll the console screen buffer for window +// size changes instead. func notifyOnResize(resizeChan chan<- os.Signal) { - // TODO + consoleOut, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0) + if err != nil { + return + } + var info windows.ConsoleScreenBufferInfo + if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil { + return + } + last := info.Window + go func() { + for { + time.Sleep(resizePollInterval) + if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil { + continue + } + current := info.Window + if current.Right-current.Left != last.Right-last.Left || + current.Bottom-current.Top != last.Bottom-last.Top { + last = current + select { + case resizeChan <- resizeSignal{}: + default: + } + } + } + }() } func notifyStop(p *os.Process) {