diff --git a/README.md b/README.md index accb86f..864e045 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ * __Dynamic Total__: [Set total](https://github.com/vbauerster/mpb/issues/9#issuecomment-344448984) while bar is running * __Dynamic Addition__: Additional bar could be added at later time * __Dynamic Removal__: Remove particular bar, before or after completion -* __Dynamic Resize__: Bars are trying to resize at terminal width change, but don't expect much here +* __Dynamic Resize__: Adaptive bar resize (doesn't work inside tmux) * __Cancellation__: Cancel whole rendering process * __Predefined Decoratros__: Elapsed time, [Ewmaest](https://github.com/dgryski/trifles/tree/master/ewmaest) based ETA, Percentage, Bytes counter * __Decorator's width sync__: Synchronized decorator's width among multiple bars diff --git a/bar.go b/bar.go index 4e0d4e9..3e0943b 100644 --- a/bar.go +++ b/bar.go @@ -355,7 +355,7 @@ func (s *state) draw(termWidth int, prependWs, appendWs *widthSync) { if termWidth <= 0 { - termWidth = s.width + termWidth = 2 } stat := newStatistics(s) @@ -383,19 +383,24 @@ prependCount := utf8.RuneCount(s.bufP.Bytes()) appendCount := utf8.RuneCount(s.bufA.Bytes()) - s.fillBar(s.width) + if termWidth > s.width { + s.fillBar(s.width) + } else { + s.fillBar(termWidth - prependCount - appendCount) + } barCount := utf8.RuneCount(s.bufB.Bytes()) totalCount := prependCount + barCount + appendCount if totalCount > termWidth { - shrinkWidth := termWidth - prependCount - appendCount - s.fillBar(shrinkWidth) + s.fillBar(termWidth - prependCount - appendCount) } s.bufA.WriteByte('\n') } func (s *state) fillBar(width int) { s.bufB.Reset() + s.bufB.WriteRune(s.format[rLeft]) if width <= 2 { + s.bufB.WriteRune(s.format[rRight]) return } @@ -403,8 +408,6 @@ barWidth := width - 2 completedWidth := decor.CalcPercentage(s.total, s.current, barWidth) - - s.bufB.WriteRune(s.format[rLeft]) if s.refill != nil { till := decor.CalcPercentage(s.total, s.refill.till, barWidth) diff --git a/draw_test.go b/draw_test.go index 9e45b38..15d7c4f 100644 --- a/draw_test.go +++ b/draw_test.go @@ -17,7 +17,7 @@ { termWidth: 2, barWidth: 100, - want: "", + want: "[]", }, { termWidth: 3, diff --git a/progress.go b/progress.go index 291305e..9f07eb1 100644 --- a/progress.go +++ b/progress.go @@ -4,8 +4,10 @@ "fmt" "io" "os" + "os/signal" "runtime" "sync" + "syscall" "time" "github.com/vbauerster/mpb/cwriter" @@ -177,14 +179,22 @@ // server monitors underlying channels and renders any progress bars func (p *Progress) server(conf pConf) { + winch := make(chan os.Signal, 1) + signal.Notify(winch, syscall.SIGWINCH) + defer func() { if conf.shutdownNotifier != nil { close(conf.shutdownNotifier) } + signal.Stop(winch) close(p.done) }() numP, numA := -1, -1 + + var timer *time.Timer + var resumeTicker <-chan time.Time + resumeDelay := 300 * time.Millisecond for { select { @@ -202,10 +212,26 @@ if numA == -1 { numA = b0.NumOfAppenders() } - err := conf.writeAndFlush(numP, numA) + tw, _, _ := cwriter.TermSize() + err := conf.writeAndFlush(tw, numP, numA) if err != nil { fmt.Fprintln(os.Stderr, err) } + case <-winch: + tw, _, _ := cwriter.TermSize() + err := conf.writeAndFlush(tw-tw/6, numP, numA) + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + if timer != nil && timer.Reset(resumeDelay) { + break + } + conf.ticker.Stop() + timer = time.NewTimer(resumeDelay) + resumeTicker = timer.C + case <-resumeTicker: + conf.ticker = time.NewTicker(conf.rr) + resumeTicker = nil case <-conf.cancel: conf.ticker.Stop() conf.cancel = nil @@ -255,7 +281,7 @@ return ws } -func (p *pConf) writeAndFlush(numP, numA int) (err error) { +func (p *pConf) writeAndFlush(tw, numP, numA int) (err error) { if p.beforeRender != nil { p.beforeRender(p.bars) } @@ -267,8 +293,6 @@ prependWs := newWidthSync(wSyncTimeout, len(p.bars), numP) appendWs := newWidthSync(wSyncTimeout, len(p.bars), numA) - - tw, _, _ := cwriter.TermSize() sequence := make([]<-chan *writeBuf, len(p.bars)) for i, b := range p.bars {