ui: process tcell events in a separate go routine from rendering
The UI runs off a 16 ms ticker. If no render is required, and no event is seen, aerc waits 16 ms before checking for new events or render requests. This severely limits handling of events from tcell, and is particularly noticeable on pasting of large quantities of text. Process tcell events in a separate go routine from the render loop. Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Moritz Poldrack <moritz@poldrack.dev> Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
parent
fad90c2956
commit
c947811e9f
2 changed files with 17 additions and 17 deletions
1
aerc.go
1
aerc.go
|
@ -241,6 +241,7 @@ func main() {
|
||||||
setWindowTitle()
|
setWindowTitle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go ui.Run()
|
||||||
for !ui.ShouldExit() {
|
for !ui.ShouldExit() {
|
||||||
for aerc.Tick() {
|
for aerc.Tick() {
|
||||||
// Continue updating our internal state
|
// Continue updating our internal state
|
||||||
|
|
33
lib/ui/ui.go
33
lib/ui/ui.go
|
@ -85,23 +85,6 @@ func (state *UI) Close() {
|
||||||
func (state *UI) Tick() bool {
|
func (state *UI) Tick() bool {
|
||||||
more := false
|
more := false
|
||||||
|
|
||||||
select {
|
|
||||||
case event := <-state.tcEvents:
|
|
||||||
if event, ok := event.(*tcell.EventResize); ok {
|
|
||||||
state.screen.Clear()
|
|
||||||
width, height := event.Size()
|
|
||||||
state.ctx = NewContext(width, height, state.screen, state.onPopover)
|
|
||||||
state.Content.Invalidate()
|
|
||||||
}
|
|
||||||
// if we have a popover, and it can handle the event, it does so
|
|
||||||
if state.popover == nil || !state.popover.Event(event) {
|
|
||||||
// otherwise, we send the event to the main content
|
|
||||||
state.Content.Event(event)
|
|
||||||
}
|
|
||||||
more = true
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
wasInvalid := atomic.SwapInt32(&state.invalid, 0)
|
wasInvalid := atomic.SwapInt32(&state.invalid, 0)
|
||||||
if wasInvalid != 0 {
|
if wasInvalid != 0 {
|
||||||
if state.popover != nil {
|
if state.popover != nil {
|
||||||
|
@ -126,3 +109,19 @@ func (state *UI) Tick() bool {
|
||||||
func (state *UI) EnableMouse() {
|
func (state *UI) EnableMouse() {
|
||||||
state.screen.EnableMouse()
|
state.screen.EnableMouse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (state *UI) Run() {
|
||||||
|
for event := range state.tcEvents {
|
||||||
|
if event, ok := event.(*tcell.EventResize); ok {
|
||||||
|
state.screen.Clear()
|
||||||
|
width, height := event.Size()
|
||||||
|
state.ctx = NewContext(width, height, state.screen, state.onPopover)
|
||||||
|
state.Content.Invalidate()
|
||||||
|
}
|
||||||
|
// if we have a popover, and it can handle the event, it does so
|
||||||
|
if state.popover == nil || !state.popover.Event(event) {
|
||||||
|
// otherwise, we send the event to the main content
|
||||||
|
state.Content.Event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue