tty: modify WindowSize method to return windowsize object

Modify the WindowSize method of the Tty interface to return a WindowSize
object. This object includes the window size in pixels, for use in
direct drawing of sixels. Terminals that do not support this feature
will have pixel sizes of 0,0.
This commit is contained in:
Tim Culverhouse 2023-03-19 10:30:08 -05:00 committed by Garrett D'Amore
parent bfc5242f05
commit c5c66b8427
4 changed files with 42 additions and 23 deletions

View File

@ -27,6 +27,7 @@ import (
"syscall"
"time"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
@ -133,11 +134,14 @@ func (tty *stdIoTty) Stop() error {
return nil
}
func (tty *stdIoTty) WindowSize() (int, int, error) {
w, h, err := term.GetSize(tty.fd)
func (tty *stdIoTty) WindowSize() (WindowSize, error) {
size := WindowSize{}
ws, err := unix.IoctlGetWinsize(tty.fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
return size, err
}
w := int(ws.Col)
h := int(ws.Row)
if w == 0 {
w, _ = strconv.Atoi(os.Getenv("COLUMNS"))
}
@ -150,7 +154,11 @@ func (tty *stdIoTty) WindowSize() (int, int, error) {
if h == 0 {
h = 25 // default
}
return w, h, nil
size.Width = w
size.Height = h
size.PixelWidth = int(ws.Xpixel)
size.PixelHeight = int(ws.Ypixel)
return size, nil
}
func (tty *stdIoTty) NotifyResize(cb func()) {

View File

@ -1091,19 +1091,22 @@ func (t *tScreen) Size() (int, int) {
}
func (t *tScreen) resize() {
if w, h, e := t.tty.WindowSize(); e == nil {
if w != t.w || h != t.h {
t.cx = -1
t.cy = -1
t.cells.Resize(w, h)
t.cells.Invalidate()
t.h = h
t.w = w
ev := NewEventResize(w, h)
_ = t.PostEvent(ev)
}
ws, err := t.tty.WindowSize()
if err != nil {
return
}
if ws.Width == t.w && ws.Height == t.h {
return
}
t.cx = -1
t.cy = -1
t.cells.Resize(ws.Width, ws.Height)
t.cells.Invalidate()
t.h = ws.Height
t.w = ws.Width
ev := &EventResize{t: time.Now(), ws: ws}
_ = t.PostEvent(ev)
}
func (t *tScreen) Colors() int {
@ -1894,8 +1897,8 @@ func (t *tScreen) engage() error {
return err
}
t.running = true
if w, h, err := t.tty.WindowSize(); err == nil && w != 0 && h != 0 {
t.cells.Resize(w, h)
if ws, err := t.tty.WindowSize(); err == nil && ws.Width != 0 && ws.Height != 0 {
t.cells.Resize(ws.Width, ws.Height)
}
stopQ := make(chan struct{})
t.stopQ = stopQ

2
tty.go
View File

@ -50,7 +50,7 @@ type Tty interface {
// WindowSize is called to determine the terminal dimensions. This might be determined
// by an ioctl or other means.
WindowSize() (width int, height int, err error)
WindowSize() (WindowSize, error)
io.ReadWriteCloser
}

View File

@ -27,6 +27,7 @@ import (
"syscall"
"time"
"golang.org/x/sys/unix"
"golang.org/x/term"
)
@ -136,11 +137,14 @@ func (tty *devTty) Stop() error {
return nil
}
func (tty *devTty) WindowSize() (int, int, error) {
w, h, err := term.GetSize(tty.fd)
func (tty *devTty) WindowSize() (WindowSize, error) {
size := WindowSize{}
ws, err := unix.IoctlGetWinsize(tty.fd, unix.TIOCGWINSZ)
if err != nil {
return 0, 0, err
return size, err
}
w := int(ws.Col)
h := int(ws.Row)
if w == 0 {
w, _ = strconv.Atoi(os.Getenv("COLUMNS"))
}
@ -153,7 +157,11 @@ func (tty *devTty) WindowSize() (int, int, error) {
if h == 0 {
h = 25 // default
}
return w, h, nil
size.Width = w
size.Height = h
size.PixelWidth = int(ws.Xpixel)
size.PixelHeight = int(ws.Ypixel)
return size, nil
}
func (tty *devTty) NotifyResize(cb func()) {