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
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ScreenSize struct {
|
||||||
|
WidthCells, HeightCells, WidthPx, HeightPx, CellWidth, CellHeight uint
|
||||||
|
updated bool
|
||||||
|
}
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
controlling_term *tty.Term
|
controlling_term *tty.Term
|
||||||
terminal_options TerminalStateOptions
|
terminal_options TerminalStateOptions
|
||||||
|
screen_size ScreenSize
|
||||||
escape_code_parser utils.EscapeCodeParser
|
escape_code_parser utils.EscapeCodeParser
|
||||||
keep_going bool
|
keep_going bool
|
||||||
flush_write_buf 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
|
// 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
|
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 {
|
func (self *Loop) handle_csi(raw []byte) error {
|
||||||
@ -125,6 +151,19 @@ func (self *Loop) on_SIGINT() error {
|
|||||||
return nil
|
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 {
|
func (self *Loop) on_SIGTERM() error {
|
||||||
self.death_signal = SIGTERM
|
self.death_signal = SIGTERM
|
||||||
self.keep_going = false
|
self.keep_going = false
|
||||||
@ -170,6 +209,14 @@ func (self *Loop) DeathSignalName() string {
|
|||||||
return ""
|
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() {
|
func (self *Loop) KillIfSignalled() {
|
||||||
switch self.death_signal {
|
switch self.death_signal {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
@ -198,7 +245,7 @@ func (self *Loop) Run() (err error) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
sigchnl := make(chan os.Signal, 256)
|
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()
|
defer reset_signals()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@ -20,6 +20,7 @@ const (
|
|||||||
SIGUSR1 Signal = 7
|
SIGUSR1 Signal = 7
|
||||||
SIGUSR2 Signal = 8
|
SIGUSR2 Signal = 8
|
||||||
SIGALRM Signal = 9
|
SIGALRM Signal = 9
|
||||||
|
SIGWINCH Signal = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self *Signal) String() string {
|
func (self *Signal) String() string {
|
||||||
@ -44,6 +45,8 @@ func (self *Signal) String() string {
|
|||||||
return "SIGUSR2"
|
return "SIGUSR2"
|
||||||
case SIGALRM:
|
case SIGALRM:
|
||||||
return "SIGALRM"
|
return "SIGALRM"
|
||||||
|
case SIGWINCH:
|
||||||
|
return "SIGWINCH"
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("SIG#%d", *self)
|
return fmt.Sprintf("SIG#%d", *self)
|
||||||
}
|
}
|
||||||
@ -69,6 +72,8 @@ func as_signal(which os.Signal) Signal {
|
|||||||
return SIGUSR2
|
return SIGUSR2
|
||||||
case syscall.SIGALRM:
|
case syscall.SIGALRM:
|
||||||
return SIGALRM
|
return SIGALRM
|
||||||
|
case syscall.SIGWINCH:
|
||||||
|
return SIGWINCH
|
||||||
default:
|
default:
|
||||||
return SIGNULL
|
return SIGNULL
|
||||||
}
|
}
|
||||||
@ -96,6 +101,8 @@ func as_go_signal(which Signal) os.Signal {
|
|||||||
return syscall.SIGUSR2
|
return syscall.SIGUSR2
|
||||||
case SIGALRM:
|
case SIGALRM:
|
||||||
return syscall.SIGALRM
|
return syscall.SIGALRM
|
||||||
|
case SIGWINCH:
|
||||||
|
return syscall.SIGWINCH
|
||||||
default:
|
default:
|
||||||
return zero_go_signal
|
return zero_go_signal
|
||||||
}
|
}
|
||||||
@ -146,6 +153,11 @@ func (self *Loop) read_signals(f *os.File, buf []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case SIGWINCH:
|
||||||
|
err := self.on_SIGWINCH()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
case SIGTSTP:
|
case SIGTSTP:
|
||||||
err := self.on_SIGTSTP()
|
err := self.on_SIGTSTP()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user