Use inband resize events in kittens

This commit is contained in:
Kovid Goyal
2024-07-18 21:57:53 +05:30
parent a4cdc1cdf3
commit 10bd0f71d8
3 changed files with 68 additions and 31 deletions

View File

@@ -41,6 +41,7 @@ type Loop struct {
controlling_term *tty.Term
terminal_options TerminalStateOptions
screen_size ScreenSize
seen_inband_resize bool
escape_code_parser wcswidth.EscapeCodeParser
keep_going bool
death_signal unix.Signal

View File

@@ -10,6 +10,7 @@ import (
"io"
"os"
"os/signal"
"strconv"
"strings"
"time"
@@ -82,8 +83,36 @@ func (self *Loop) update_screen_size() error {
return nil
}
func (self *Loop) handle_csi(raw []byte) error {
func (self *Loop) handle_csi(raw []byte) (err error) {
csi := string(raw)
if len(csi) > 2 {
if strings.HasSuffix(csi, "t") && strings.HasPrefix(csi, "48;") {
if parts := strings.Split(csi[3:len(csi)-1], ";"); len(parts) > 3 {
var parsed [4]int
ok := true
for i, x := range parts {
x, _, _ = strings.Cut(x, ":")
if parsed[i], err = strconv.Atoi(x); err != nil {
ok = false
break
}
}
if ok {
self.seen_inband_resize = true
old_size := self.screen_size
s := &self.screen_size
s.updated = true
s.HeightCells, s.WidthCells = uint(parsed[0]), uint(parsed[1])
s.HeightPx, s.WidthPx = uint(parsed[2]), uint(parsed[2])
s.CellWidth = s.WidthPx / s.WidthCells
s.CellHeight = s.HeightPx / s.HeightCells
if self.OnResize != nil {
return self.OnResize(old_size, self.screen_size)
}
return nil
}
}
}
ke := KeyEventFromCSI(csi)
if ke != nil {
return self.handle_key_event(ke)
@@ -95,6 +124,7 @@ func (self *Loop) handle_csi(raw []byte) error {
return self.handle_mouse_event(me)
}
}
}
if self.OnEscapeCode != nil {
return self.OnEscapeCode(CSI, raw)
}
@@ -272,6 +302,9 @@ func (self *Loop) on_SIGPIPE() error {
}
func (self *Loop) on_SIGWINCH() error {
if self.seen_inband_resize {
return nil
}
self.screen_size.updated = false
if self.OnResize != nil {
old_size := self.screen_size
@@ -313,6 +346,7 @@ func (self *Loop) run() (err error) {
}()
self.keep_going = true
self.seen_inband_resize = false
self.pending_mouse_events = utils.NewRingBuffer[MouseEvent](4)
// tty_write_channel is buffered so there is no race between initial
// queueing and startup of writer thread and also as a performance

View File

@@ -65,6 +65,7 @@ const (
ALTERNATE_SCREEN Mode = 1049 | private
BRACKETED_PASTE Mode = 2004 | private
PENDING_UPDATE Mode = 2026 | private
INBAND_RESIZE_NOTIFICATION Mode = 2048 | private
HANDLE_TERMIOS_SIGNALS Mode = kitty.HandleTermiosSignals | private
)
@@ -127,7 +128,7 @@ func (self *TerminalStateOptions) SetStateEscapeCodes() string {
reset_modes(&sb,
IRM, DECKM, DECSCNM, BRACKETED_PASTE, FOCUS_TRACKING,
MOUSE_BUTTON_TRACKING, MOUSE_MOTION_TRACKING, MOUSE_MOVE_TRACKING, MOUSE_UTF8_MODE, MOUSE_SGR_MODE)
set_modes(&sb, DECARM, DECAWM, DECTCEM)
set_modes(&sb, DECARM, DECAWM, DECTCEM, INBAND_RESIZE_NOTIFICATION)
if self.Alternate_screen {
set_modes(&sb, ALTERNATE_SCREEN)
sb.WriteString(CLEAR_SCREEN)
@@ -169,6 +170,7 @@ func (self *TerminalStateOptions) ResetStateEscapeCodes() string {
sb.WriteString(RESTORE_COLORS)
}
sb.WriteString(RESTORE_CURSOR)
reset_modes(&sb, INBAND_RESIZE_NOTIFICATION)
return sb.String()
}