Terminate resize notification when Loop exits

- Pass Loop context to notifyOnResize
- Windows: stop polling goroutine, close CONOUT$ handle on ctx.Done
- Unix: unregister SIGWINCH handler on ctx.Done
This commit is contained in:
Junegunn Choi
2026-07-20 13:09:06 +09:00
parent 6e65d867dc
commit dc384afb70
3 changed files with 18 additions and 4 deletions
+1 -1
View File
@@ -6199,7 +6199,7 @@ func (t *Terminal) Loop() error {
if !t.tui.ShouldEmitResizeEvent() { if !t.tui.ShouldEmitResizeEvent() {
resizeChan := make(chan os.Signal, 1) resizeChan := make(chan os.Signal, 1)
notifyOnResize(resizeChan) // Non-portable notifyOnResize(ctx, resizeChan) // Non-portable
go func() { go func() {
for { for {
select { select {
+6 -1
View File
@@ -3,6 +3,7 @@
package fzf package fzf
import ( import (
"context"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
@@ -10,8 +11,12 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
func notifyOnResize(resizeChan chan<- os.Signal) { func notifyOnResize(ctx context.Context, resizeChan chan<- os.Signal) {
signal.Notify(resizeChan, syscall.SIGWINCH) signal.Notify(resizeChan, syscall.SIGWINCH)
go func() {
<-ctx.Done()
signal.Stop(resizeChan)
}()
} }
func notifyStop(p *os.Process) { func notifyStop(p *os.Process) {
+11 -2
View File
@@ -3,6 +3,7 @@
package fzf package fzf
import ( import (
"context"
"os" "os"
"syscall" "syscall"
"time" "time"
@@ -19,19 +20,27 @@ func (resizeSignal) Signal() {}
// Windows has no SIGWINCH, so poll the console screen buffer for window // Windows has no SIGWINCH, so poll the console screen buffer for window
// size changes instead. // size changes instead.
func notifyOnResize(resizeChan chan<- os.Signal) { func notifyOnResize(ctx context.Context, resizeChan chan<- os.Signal) {
consoleOut, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0) consoleOut, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
if err != nil { if err != nil {
return return
} }
var info windows.ConsoleScreenBufferInfo var info windows.ConsoleScreenBufferInfo
if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil { if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil {
syscall.Close(consoleOut)
return return
} }
last := info.Window last := info.Window
go func() { go func() {
defer syscall.Close(consoleOut)
ticker := time.NewTicker(resizePollInterval)
defer ticker.Stop()
for { for {
time.Sleep(resizePollInterval) select {
case <-ctx.Done():
return
case <-ticker.C:
}
if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil { if windows.GetConsoleScreenBufferInfo(windows.Handle(consoleOut), &info) != nil {
continue continue
} }