@@ 23,7 23,7 @@ type Terminal struct {
screen tcell.Screen
view views.View
- redrawChan chan struct{}
+ close bool
views.WidgetWatchers
}
@@ 49,31 49,33 @@ func WithWindowManipulator(wm termutil.WindowManipulator) Option {
func (t *Terminal) Run(cmd *exec.Cmd) error {
w, h := t.view.Size()
- t.redrawChan = make(chan struct{}, 10)
+ tmr := time.NewTicker(16 * time.Millisecond)
go func() {
for {
select {
- case <-t.redrawChan:
- t.screen.PostEvent(NewRedrawEvent())
- // term.Draw()
- // s.Show()
+ case <-tmr.C:
+ if t.close {
+ return
+ }
+ if t.term.ShouldRedraw() {
+ t.PostEventWidgetContent(t)
+ t.term.SetRedraw(false)
+ }
}
}
}()
- return t.term.Run(cmd, t.redrawChan, uint16(h), uint16(w))
-}
-
-type RedrawEvent struct {
- when time.Time
-}
-
-func NewRedrawEvent() *RedrawEvent {
- return &RedrawEvent{
- when: time.Now(),
+ err := t.term.Run(cmd, uint16(h), uint16(w))
+ if err != nil {
+ return err
}
+ t.Close()
+ return nil
}
-func (e RedrawEvent) When() time.Time { return e.when }
+func (t *Terminal) Close() {
+ t.close = true
+ t.term.Pty().Close()
+}
func (t *Terminal) SetView(view views.View) {
t.view = view
@@ 23,22 23,19 @@ const (
type Terminal struct {
windowManipulator WindowManipulator
pty *os.File
- updateChan chan struct{}
processChan chan MeasuredRune
- closeChan chan struct{}
buffers []*Buffer
activeBuffer *Buffer
mouseMode MouseMode
mouseExtMode MouseExtMode
theme *Theme
- renderDebounce *time.Timer
+ redraw bool
}
// NewTerminal creates a new terminal instance
func New(options ...Option) *Terminal {
term := &Terminal{
processChan: make(chan MeasuredRune, 0xffff),
- closeChan: make(chan struct{}),
theme: &Theme{},
}
for _, opt := range options {
@@ 119,8 116,7 @@ func (t *Terminal) SetSize(rows, cols uint16) error {
}
// Run starts the terminal/shell proxying process
-func (t *Terminal) Run(c *exec.Cmd, updateChan chan struct{}, rows uint16, cols uint16) error {
- t.updateChan = updateChan
+func (t *Terminal) Run(c *exec.Cmd, rows uint16, cols uint16) error {
c.Env = append(os.Environ(), "TERM=xterm-256color")
// Start the command with a pty.
@@ 148,34 144,29 @@ func (t *Terminal) Run(c *exec.Cmd, updateChan chan struct{}, rows uint16, cols
go t.process()
_, _ = io.Copy(t, t.pty)
- close(t.closeChan)
return nil
}
-func (t *Terminal) requestRender() {
- if t.renderDebounce != nil {
- t.renderDebounce.Stop()
- }
- // 4 milliseconds = 250Hz. Probably don't need to render faster than
- // that
- t.renderDebounce = time.AfterFunc(4*time.Millisecond, func() {
- t.updateChan <- struct{}{}
- })
+func (t *Terminal) ShouldRedraw() bool {
+ return t.redraw
+}
+
+func (t *Terminal) SetRedraw(b bool) {
+ t.redraw = b
}
func (t *Terminal) process() {
for {
- select {
- case <-t.closeChan:
+ mr, ok := <-t.processChan
+ if !ok {
return
- case mr := <-t.processChan:
- if mr.Rune == 0x1b { // ANSI escape char, which means this is a sequence
- if t.handleANSI(t.processChan) {
- t.requestRender()
- }
- } else if t.processRunes(mr) { // otherwise it's just an individual rune we need to process
- t.requestRender()
+ }
+ if mr.Rune == 0x1b { // ANSI escape char, which means this is a sequence
+ if t.handleANSI(t.processChan) {
+ t.SetRedraw(true)
}
+ } else if t.processRunes(mr) { // otherwise it's just an individual rune we need to process
+ t.SetRedraw(true)
}
}
}