summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2021-04-06 17:00:37 +1000
committerJesse Duffield <jessedduffield@gmail.com>2021-04-06 19:34:32 +1000
commit8eb802d3a090e16026ad0acfa69844f85229e2c1 (patch)
tree238de64d51a281896827f867ab5dcb92547af067
parent6fc031c523cfb8aa1a249997f76e24e8934b9a73 (diff)
fix flicker issue in main view
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--pkg/gui/tasks_adapter.go14
-rw-r--r--pkg/tasks/tasks.go14
-rw-r--r--vendor/github.com/jesseduffield/gocui/view.go43
-rw-r--r--vendor/modules.txt2
6 files changed, 65 insertions, 14 deletions
diff --git a/go.mod b/go.mod
index 98853adb9..d83bd8e04 100644
--- a/go.mod
+++ b/go.mod
@@ -20,7 +20,7 @@ require (
github.com/imdario/mergo v0.3.11
github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
- github.com/jesseduffield/gocui v0.3.1-0.20210405093708-e79dab8f7772
+ github.com/jesseduffield/gocui v0.3.1-0.20210406065942-1b0c68414064
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe // indirect
github.com/jesseduffield/yaml v2.1.0+incompatible
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
diff --git a/go.sum b/go.sum
index d2037e61e..3efe983fe 100644
--- a/go.sum
+++ b/go.sum
@@ -102,6 +102,10 @@ github.com/jesseduffield/gocui v0.3.1-0.20210405041826-439abd8b6e07 h1:BymGR28au
github.com/jesseduffield/gocui v0.3.1-0.20210405041826-439abd8b6e07/go.mod h1:QWq79xplEoyhQO+dgpk3sojjTVRKjQklyTlzm5nC5Kg=
github.com/jesseduffield/gocui v0.3.1-0.20210405093708-e79dab8f7772 h1:dg9krj10Udac4IcvlVCOAPktQkfggkgtqRmbDKk7Pzw=
github.com/jesseduffield/gocui v0.3.1-0.20210405093708-e79dab8f7772/go.mod h1:QWq79xplEoyhQO+dgpk3sojjTVRKjQklyTlzm5nC5Kg=
+github.com/jesseduffield/gocui v0.3.1-0.20210406065811-95ef6e13779b h1:3+4+muhhikpls5FePXSRNFgcdoPx8dTdqaCy3AqLz98=
+github.com/jesseduffield/gocui v0.3.1-0.20210406065811-95ef6e13779b/go.mod h1:QWq79xplEoyhQO+dgpk3sojjTVRKjQklyTlzm5nC5Kg=
+github.com/jesseduffield/gocui v0.3.1-0.20210406065942-1b0c68414064 h1:Oe+QJuUIOd2TU+A3BW5sT1eXqceoBcOOfyoHlGf7F8Y=
+github.com/jesseduffield/gocui v0.3.1-0.20210406065942-1b0c68414064/go.mod h1:QWq79xplEoyhQO+dgpk3sojjTVRKjQklyTlzm5nC5Kg=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe h1:qsVhCf2RFyyKIUe/+gJblbCpXMUki9rZrHuEctg6M/E=
github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe/go.mod h1:anMibpZtqNxjDbxrcDEAwSdaJ37vyUeM1f/M4uekib4=
github.com/jesseduffield/yaml v2.1.0+incompatible h1:HWQJ1gIv2zHKbDYNp0Jwjlj24K8aqpFHnMCynY1EpmE=
diff --git a/pkg/gui/tasks_adapter.go b/pkg/gui/tasks_adapter.go
index bc2fb8a24..d24344b49 100644
--- a/pkg/gui/tasks_adapter.go
+++ b/pkg/gui/tasks_adapter.go
@@ -83,13 +83,23 @@ func (gui *Gui) getManager(view *gocui.View) *tasks.ViewBufferManager {
gui.Log,
view,
func() {
- view.Clear()
+ // we could clear here, but that actually has the effect of causing a flicker
+ // where the view may contain no content momentarily as the gui refreshes.
+ // Instead, we're rewinding the write pointer so that we will just start
+ // overwriting the existing content from the top down. Once we've reached
+ // the end of the content do display, we call view.FlushStaleCells() to
+ // clear out the remaining content from the previous render.
+ view.Rewind()
},
func() {
gui.g.Update(func(*gocui.Gui) error {
return nil
})
- })
+ },
+ func() {
+ view.FlushStaleCells()
+ },
+ )
gui.viewBufferManagerMap[view.Name()] = manager
}
diff --git a/pkg/tasks/tasks.go b/pkg/tasks/tasks.go
index 5854b4f46..8287b3927 100644
--- a/pkg/tasks/tasks.go
+++ b/pkg/tasks/tasks.go
@@ -33,12 +33,13 @@ type ViewBufferManager struct {
readLines chan int
// beforeStart is the function that is called before starting a new task
- beforeStart func()
- refreshView func()
+ beforeStart func()
+ refreshView func()
+ flushStaleCells func()
}
-func NewViewBufferManager(log *logrus.Entry, writer io.Writer, beforeStart func(), refreshView func()) *ViewBufferManager {
- return &ViewBufferManager{Log: log, writer: writer, beforeStart: beforeStart, refreshView: refreshView, readLines: make(chan int, 1024)}
+func NewViewBufferManager(log *logrus.Entry, writer io.Writer, beforeStart func(), refreshView func(), flushStaleCells func()) *ViewBufferManager {
+ return &ViewBufferManager{Log: log, writer: writer, beforeStart: beforeStart, refreshView: refreshView, flushStaleCells: flushStaleCells, readLines: make(chan int, 1024)}
}
func (m *ViewBufferManager) ReadLines(n int) {
@@ -75,7 +76,7 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string
loaded := false
go utils.Safe(func() {
- ticker := time.NewTicker(time.Millisecond * 100)
+ ticker := time.NewTicker(time.Millisecond * 200)
defer ticker.Stop()
select {
case <-ticker.C:
@@ -114,6 +115,9 @@ func (m *ViewBufferManager) NewCmdTask(r io.Reader, cmd *exec.Cmd, prefix string
default:
}
if !ok {
+ // if we're here then there's nothing left to scan from the source
+ // so we're at the EOF and can flush the stale content
+ m.flushStaleCells()
m.refreshView()
break outer
}
diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go
index b13074242..2e4c4c1e3 100644
--- a/vendor/github.com/jesseduffield/gocui/view.go
+++ b/vendor/github.com/jesseduffield/gocui/view.go
@@ -518,16 +518,20 @@ func (v *View) writeCells(x, y int, cells []cell) {
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
// be called to clear the view's buffer.
func (v *View) Write(p []byte) (n int, err error) {
- v.tainted = true
v.writeMutex.Lock()
+ defer v.writeMutex.Unlock()
+
+ v.tainted = true
v.makeWriteable(v.wx, v.wy)
v.writeRunes(bytes.Runes(p))
- v.writeMutex.Unlock()
return len(p), nil
}
func (v *View) WriteRunes(p []rune) {
+ v.writeMutex.Lock()
+ defer v.writeMutex.Unlock()
+
v.tainted = true
// Fill with empty cells, if writing outside current view buffer
@@ -545,6 +549,8 @@ func (v *View) writeRunes(p []rune) {
for _, r := range p {
switch r {
case '\n':
+ // clear the rest of the line
+ v.lines[v.wy] = v.lines[v.wy][0:v.wx]
v.wy++
if v.wy >= len(v.lines) {
v.lines = append(v.lines, nil)
@@ -642,6 +648,15 @@ func (v *View) Read(p []byte) (n int, err error) {
// Rewind sets read and write pos to (0, 0).
func (v *View) Rewind() {
+ v.writeMutex.Lock()
+ defer v.writeMutex.Unlock()
+
+ v.rewind()
+}
+
+func (v *View) rewind() {
+ v.ei.reset()
+
if err := v.SetReadPos(0, 0); err != nil {
// SetReadPos returns error only if x and y are negative
// we are passing 0, 0, thus no error should occur.
@@ -832,13 +847,31 @@ func (v *View) realPosition(vx, vy int) (x, y int, err error) {
// And resets reading and writing offsets.
func (v *View) Clear() {
v.writeMutex.Lock()
- v.Rewind()
+ defer v.writeMutex.Unlock()
+
+ v.rewind()
v.tainted = true
- v.ei.reset()
v.lines = nil
v.viewLines = nil
v.clearRunes()
- v.writeMutex.Unlock()
+}
+
+// This is for when we've done a rewind for the sake of avoiding a flicker and
+// we've reached the end of the new content to display: we need to clear the remaining
+// content from the previous round.
+func (v *View) FlushStaleCells() {
+ v.writeMutex.Lock()
+ defer v.writeMutex.Unlock()
+
+ // need to wipe the end of the current line and all following lines
+ if len(v.lines) > 0 && v.wy < len(v.lines) {
+ // why this needs to be +1 but the 0:v.wx part doesn't, I'm not sure
+ v.lines = v.lines[0 : v.wy+1]
+
+ if len(v.lines[v.wy]) > 0 && v.wx < len(v.lines[v.wy]) {
+ v.lines[v.wy] = v.lines[v.wy][0:v.wx]
+ }
+ }
}
// clearRunes erases all the cells in the view.
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1bf4922de..f263b6ee6 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -149,7 +149,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
-# github.com/jesseduffield/gocui v0.3.1-0.20210405093708-e79dab8f7772
+# github.com/jesseduffield/gocui v0.3.1-0.20210406065942-1b0c68414064
## explicit
github.com/jesseduffield/gocui
# github.com/jesseduffield/termbox-go v0.0.0-20200823212418-a2289ed6aafe