From b7be868798d017f435e7f67b9803bb51922c652f Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 24 Apr 2019 23:53:31 -0700 Subject: [PATCH] Fix race conditions caused by writing to view --- main.go | 25 ------------------------- modules/clocks/widget.go | 7 ++++++- modules/security/widget.go | 6 +++++- modules/status/widget.go | 12 +++++++++--- modules/todo/widget.go | 8 ++++++-- wtf/bargraph.go | 11 ++++++----- 6 files changed, 32 insertions(+), 37 deletions(-) diff --git a/main.go b/main.go index 988ce487..56976c2f 100644 --- a/main.go +++ b/main.go @@ -122,30 +122,6 @@ func watchForConfigChanges(app *tview.Application, configFilePath string, grid * } } -func enableAppRefresh(app *tview.Application) { - defaultInterval := 100 - - refreshInterval := Config.UInt("wtf.refreshInterval", defaultInterval) - if refreshInterval < defaultInterval { - refreshInterval = defaultInterval - } - - interval := time.Duration(refreshInterval) * time.Millisecond - - tick := time.NewTicker(interval) - quit := make(chan struct{}) - - for { - select { - case <-tick.C: - app.Draw() - case <-quit: - tick.Stop() - return - } - } -} - /* -------------------- Main -------------------- */ func main() { @@ -181,7 +157,6 @@ func main() { app.SetInputCapture(keyboardIntercept) go watchForConfigChanges(app, flags.Config, display.Grid, pages) - go enableAppRefresh(app) if err := app.SetRoot(pages, true).Run(); err != nil { fmt.Printf("Error: %v\n", err) diff --git a/modules/clocks/widget.go b/modules/clocks/widget.go index e65cb584..3f1591c6 100644 --- a/modules/clocks/widget.go +++ b/modules/clocks/widget.go @@ -11,6 +11,7 @@ import ( type Widget struct { wtf.TextWidget + app *tview.Application clockColl ClockCollection dateFormat string timeFormat string @@ -21,6 +22,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), + app: app, settings: settings, dateFormat: settings.dateFormat, timeFormat: settings.timeFormat, @@ -34,7 +36,10 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - widget.display(widget.clockColl.Sorted(widget.settings.sort), widget.dateFormat, widget.timeFormat) + widget.app.QueueUpdateDraw(func() { + sortedClocks := widget.clockColl.Sorted(widget.settings.sort) + widget.display(sortedClocks, widget.dateFormat, widget.timeFormat) + }) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/security/widget.go b/modules/security/widget.go index b656ab71..b10b7013 100644 --- a/modules/security/widget.go +++ b/modules/security/widget.go @@ -11,6 +11,7 @@ import ( type Widget struct { wtf.TextWidget + app *tview.Application settings *Settings } @@ -18,6 +19,7 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ TextWidget: wtf.NewTextWidget(app, settings.common, false), + app: app, settings: settings, } @@ -35,7 +37,9 @@ func (widget *Widget) Refresh() { data := NewSecurityData() data.Fetch() - widget.View.SetText(widget.contentFrom(data)) + widget.app.QueueUpdateDraw(func() { + widget.View.SetText(widget.contentFrom(data)) + }) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/status/widget.go b/modules/status/widget.go index e9a07650..cf02188d 100644 --- a/modules/status/widget.go +++ b/modules/status/widget.go @@ -9,7 +9,9 @@ type Widget struct { wtf.TextWidget CurrentIcon int - settings *Settings + + app *tview.Application + settings *Settings } func NewWidget(app *tview.Application, settings *Settings) *Widget { @@ -17,7 +19,9 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { TextWidget: wtf.NewTextWidget(app, settings.common, false), CurrentIcon: 0, - settings: settings, + + app: app, + settings: settings, } return &widget @@ -26,7 +30,9 @@ func NewWidget(app *tview.Application, settings *Settings) *Widget { /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - widget.View.SetText(widget.animation()) + widget.app.QueueUpdateDraw(func() { + widget.View.SetText(widget.animation()) + }) } /* -------------------- Unexported Functions -------------------- */ diff --git a/modules/todo/widget.go b/modules/todo/widget.go index 342e1076..4036fbd7 100644 --- a/modules/todo/widget.go +++ b/modules/todo/widget.go @@ -72,9 +72,12 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * func (widget *Widget) Refresh() { widget.load() - widget.display() - widget.View.SetTitle(widget.ContextualTitle(widget.Name())) + widget.app.QueueUpdateDraw(func() { + widget.display() + widget.View.SetTitle(widget.ContextualTitle(widget.Name())) + }) + } func (widget *Widget) SetList(newList checklist.Checklist) { @@ -265,6 +268,7 @@ func (widget *Widget) modalFocus(form *tview.Form) { frame := widget.modalFrame(form) widget.pages.AddPage("modal", frame, false, true) widget.app.SetFocus(frame) + widget.app.Draw() } func (widget *Widget) modalForm(lbl, text string) *tview.Form { diff --git a/wtf/bargraph.go b/wtf/bargraph.go index 979813c6..e636b3e6 100644 --- a/wtf/bargraph.go +++ b/wtf/bargraph.go @@ -48,7 +48,10 @@ func NewBarGraph(app *tview.Application, name string, configKey string, focusabl Config.UInt(fmt.Sprintf("wtf.mods.%s.position.height", configKey)), ) - widget.addView(app, configKey) + widget.View = widget.addView(configKey) + widget.View.SetChangedFunc(func() { + app.Draw() + }) return widget } @@ -109,7 +112,7 @@ func (widget *BarGraph) TextView() *tview.TextView { /* -------------------- Unexported Functions -------------------- */ -func (widget *BarGraph) addView(app *tview.Application, configKey string) { +func (widget *BarGraph) addView(configKey string) *tview.TextView { view := tview.NewTextView() view.SetBackgroundColor(ColorFor(Config.UString("wtf.colors.background", "black"))) @@ -125,15 +128,13 @@ func (widget *BarGraph) addView(app *tview.Application, configKey string) { )) view.SetWrap(false) - widget.View = view + return view } // BuildBars will build a string of * to represent your data of [time][value] // time should be passed as a int64 func (widget *BarGraph) BuildBars(data []Bar) { - widget.View.SetText(BuildStars(data, widget.maxStars, widget.starChar)) - } //BuildStars build the string to display