1//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || aix || zos
2// +build darwin dragonfly freebsd linux netbsd openbsd solaris aix zos
3
4package uv
5
6import (
7 "context"
8 "os"
9 "os/signal"
10 "sync"
11 "syscall"
12
13 "github.com/charmbracelet/x/term"
14 "github.com/charmbracelet/x/termios"
15)
16
17func (l *WinChReceiver) receiveEvents(ctx context.Context, f term.File, evch chan<- Event) error {
18 sig := make(chan os.Signal, 1)
19 signal.Notify(sig, syscall.SIGWINCH)
20
21 sendWinSize := func(w, h int) {
22 select {
23 case <-ctx.Done():
24 case evch <- WindowSizeEvent{w, h}:
25 }
26 }
27
28 sendPixelSize := func(w, h int) {
29 select {
30 case <-ctx.Done():
31 case evch <- WindowPixelSizeEvent{w, h}:
32 }
33 }
34
35 defer signal.Stop(sig)
36
37 // Send the initial window size.
38 winsize, err := termios.GetWinsize(int(f.Fd()))
39 if err != nil {
40 return err
41 }
42
43 var wg sync.WaitGroup
44 wg.Add(1)
45 go func() {
46 defer wg.Done()
47 sendWinSize(int(winsize.Col), int(winsize.Row))
48 }()
49
50 wg.Add(1)
51 go func() {
52 defer wg.Done()
53 sendPixelSize(int(winsize.Xpixel), int(winsize.Ypixel))
54 }()
55
56 // Wait for all goroutines to finish before continuing.
57 wg.Wait()
58
59 // Listen for window size changes.
60 for {
61 select {
62 case <-ctx.Done():
63 return nil
64 case <-sig:
65 winsize, err := termios.GetWinsize(int(f.Fd()))
66 if err != nil {
67 return err
68 }
69
70 wg.Add(1)
71 go func() {
72 defer wg.Done()
73 sendWinSize(int(winsize.Col), int(winsize.Row))
74 }()
75
76 wg.Add(1)
77 go func() {
78 defer wg.Done()
79 sendPixelSize(int(winsize.Xpixel), int(winsize.Ypixel))
80 }()
81
82 // Wait for all goroutines to finish before continuing.
83 wg.Wait()
84 }
85 }
86}