Add callback for screen resize handling
This commit is contained in:
parent
c2ef6c986b
commit
e68b5fa504
@ -35,9 +35,15 @@ func write_ignoring_temporary_errors(fd int, buf []byte) (int, error) {
|
||||
return n, err
|
||||
}
|
||||
|
||||
type ScreenSize struct {
|
||||
WidthCells, HeightCells, WidthPx, HeightPx, CellWidth, CellHeight uint
|
||||
updated bool
|
||||
}
|
||||
|
||||
type Loop struct {
|
||||
controlling_term *tty.Term
|
||||
terminal_options TerminalStateOptions
|
||||
screen_size ScreenSize
|
||||
escape_code_parser utils.EscapeCodeParser
|
||||
keep_going bool
|
||||
flush_write_buf bool
|
||||
@ -56,6 +62,26 @@ type Loop struct {
|
||||
|
||||
// Called when text is received either from a key event or directly from the terminal
|
||||
OnText func(loop *Loop, text string, from_key_event bool, in_bracketed_paste bool) error
|
||||
|
||||
// Called when the terminal is resize
|
||||
OnResize func(loop *Loop, old_size ScreenSize, new_size ScreenSize) error
|
||||
}
|
||||
|
||||
func (self *Loop) update_screen_size() error {
|
||||
if self.controlling_term != nil {
|
||||
return fmt.Errorf("No controlling terminal cannot update screen size")
|
||||
}
|
||||
ws, err := self.controlling_term.GetSize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := &self.screen_size
|
||||
s.updated = true
|
||||
s.HeightCells, s.WidthCells = uint(ws.Row), uint(ws.Col)
|
||||
s.HeightPx, s.WidthPx = uint(ws.Ypixel), uint(ws.Xpixel)
|
||||
s.CellWidth = s.WidthPx / s.WidthCells
|
||||
s.CellHeight = s.HeightPx / s.HeightCells
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Loop) handle_csi(raw []byte) error {
|
||||
@ -125,6 +151,19 @@ func (self *Loop) on_SIGINT() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Loop) on_SIGWINCH() error {
|
||||
self.screen_size.updated = false
|
||||
if self.OnResize != nil {
|
||||
old_size := self.screen_size
|
||||
err := self.update_screen_size()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return self.OnResize(self, old_size, self.screen_size)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Loop) on_SIGTERM() error {
|
||||
self.death_signal = SIGTERM
|
||||
self.keep_going = false
|
||||
@ -170,6 +209,14 @@ func (self *Loop) DeathSignalName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *Loop) ScreenSize() (ScreenSize, error) {
|
||||
if self.screen_size.updated {
|
||||
return self.screen_size, nil
|
||||
}
|
||||
err := self.update_screen_size()
|
||||
return self.screen_size, err
|
||||
}
|
||||
|
||||
func (self *Loop) KillIfSignalled() {
|
||||
switch self.death_signal {
|
||||
case SIGINT:
|
||||
@ -198,7 +245,7 @@ func (self *Loop) Run() (err error) {
|
||||
}()
|
||||
|
||||
sigchnl := make(chan os.Signal, 256)
|
||||
reset_signals := notify_signals(sigchnl, SIGINT, SIGTERM, SIGTSTP, SIGHUP)
|
||||
reset_signals := notify_signals(sigchnl, SIGINT, SIGTERM, SIGTSTP, SIGHUP, SIGWINCH)
|
||||
defer reset_signals()
|
||||
|
||||
go func() {
|
||||
|
||||
@ -20,6 +20,7 @@ const (
|
||||
SIGUSR1 Signal = 7
|
||||
SIGUSR2 Signal = 8
|
||||
SIGALRM Signal = 9
|
||||
SIGWINCH Signal = 10
|
||||
)
|
||||
|
||||
func (self *Signal) String() string {
|
||||
@ -44,6 +45,8 @@ func (self *Signal) String() string {
|
||||
return "SIGUSR2"
|
||||
case SIGALRM:
|
||||
return "SIGALRM"
|
||||
case SIGWINCH:
|
||||
return "SIGWINCH"
|
||||
default:
|
||||
return fmt.Sprintf("SIG#%d", *self)
|
||||
}
|
||||
@ -69,6 +72,8 @@ func as_signal(which os.Signal) Signal {
|
||||
return SIGUSR2
|
||||
case syscall.SIGALRM:
|
||||
return SIGALRM
|
||||
case syscall.SIGWINCH:
|
||||
return SIGWINCH
|
||||
default:
|
||||
return SIGNULL
|
||||
}
|
||||
@ -96,6 +101,8 @@ func as_go_signal(which Signal) os.Signal {
|
||||
return syscall.SIGUSR2
|
||||
case SIGALRM:
|
||||
return syscall.SIGALRM
|
||||
case SIGWINCH:
|
||||
return syscall.SIGWINCH
|
||||
default:
|
||||
return zero_go_signal
|
||||
}
|
||||
@ -146,6 +153,11 @@ func (self *Loop) read_signals(f *os.File, buf []byte) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case SIGWINCH:
|
||||
err := self.on_SIGWINCH()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case SIGTSTP:
|
||||
err := self.on_SIGTSTP()
|
||||
if err != nil {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user