From 8668cab243710fe412c008b6f77f0efca116b89b Mon Sep 17 00:00:00 2001 From: skanehira Date: Sun, 28 Apr 2019 21:24:26 +0900 Subject: [PATCH 1/2] Improve get terminal window size in the docker container #15 --- gui.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/gui.go b/gui.go index 4be6119e..913375fd 100644 --- a/gui.go +++ b/gui.go @@ -6,6 +6,10 @@ package gocui import ( standardErrors "errors" + "os" + "os/signal" + "syscall" + "unsafe" "github.com/go-errors/errors" @@ -83,7 +87,8 @@ type Gui struct { // NewGui returns a new Gui object with a given output mode. func NewGui(mode OutputMode, supportOverlaps bool) (*Gui, error) { - if err := termbox.Init(); err != nil { + err := termbox.Init() + if err != nil { return nil, err } @@ -97,7 +102,10 @@ func NewGui(mode OutputMode, supportOverlaps bool) (*Gui, error) { g.tbEvents = make(chan termbox.Event, 20) g.userEvents = make(chan userEvent, 20) - g.maxX, g.maxY = termbox.Size() + g.maxX, g.maxY, err = g.getTermSize() + if err != nil { + return nil, err + } g.BgColor, g.FgColor = ColorDefault, ColorDefault g.SelBgColor, g.SelFgColor = ColorDefault, ColorDefault @@ -740,3 +748,44 @@ func IsUnknownView(err error) bool { func IsQuit(err error) bool { return err.Error() == ErrQuit.Error() } + +func (g *Gui) getTermSize() (int, int, error) { + var sz struct { + rows uint16 + cols uint16 + } + + var termw, termh int + + out, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) + if err != nil { + return 0, 0, err + } + defer out.Close() + + signalCh := make(chan os.Signal, 1) + signal.Notify(signalCh, syscall.SIGWINCH, syscall.SIGINT) + + for { + _, _, _ = syscall.Syscall(syscall.SYS_IOCTL, + out.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz))) + + // check terminal window size + termw, termh = int(sz.cols), int(sz.rows) + if termw > 0 && termh > 0 { + return termw, termh, nil + } + + select { + case signal := <-signalCh: + switch signal { + // when the terminal window size is changed + case syscall.SIGWINCH: + continue + // ctrl + c to cancel + case syscall.SIGINT: + return 0, 0, errors.New("stop to get term window size") + } + } + } +} From 5b7b2afd738782750a96f8d21b995bdf29d52dd6 Mon Sep 17 00:00:00 2001 From: skanehira Date: Mon, 29 Apr 2019 08:18:11 +0900 Subject: [PATCH 2/2] fixed some - Add documents for new function - Only inside the container to use original get terminal window function --- gui.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gui.go b/gui.go index 913375fd..209686da 100644 --- a/gui.go +++ b/gui.go @@ -8,6 +8,7 @@ import ( standardErrors "errors" "os" "os/signal" + "runtime" "syscall" "unsafe" @@ -102,9 +103,13 @@ func NewGui(mode OutputMode, supportOverlaps bool) (*Gui, error) { g.tbEvents = make(chan termbox.Event, 20) g.userEvents = make(chan userEvent, 20) - g.maxX, g.maxY, err = g.getTermSize() - if err != nil { - return nil, err + if runtime.GOOS != "windows" { + g.maxX, g.maxY, err = g.getTermWindowSize() + if err != nil { + return nil, err + } + } else { + g.maxX, g.maxY = termbox.Size() } g.BgColor, g.FgColor = ColorDefault, ColorDefault @@ -749,7 +754,9 @@ func IsQuit(err error) bool { return err.Error() == ErrQuit.Error() } -func (g *Gui) getTermSize() (int, int, error) { +// getTermWindowSize is get terminal window size on linux or unix. +// When gocui run inside the docker contaienr need to check and get the window size. +func (g *Gui) getTermWindowSize() (int, int, error) { var sz struct { rows uint16 cols uint16