From 41db607cc9f43b2d5c0702cf7bb6e6874cbc4d2b Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Fri, 8 May 2020 16:12:48 -0700 Subject: [PATCH] Fix mutex usage in List.MouseHandler --- demos/presentation/main.go | 2 +- list.go | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/demos/presentation/main.go b/demos/presentation/main.go index e441fc3..c99ae58 100644 --- a/demos/presentation/main.go +++ b/demos/presentation/main.go @@ -40,7 +40,7 @@ func main() { if debugPort > 0 { go func() { - log.Println(http.ListenAndServe(fmt.Sprintf("localhost:%d", debugPort), nil)) + log.Fatal(http.ListenAndServe(fmt.Sprintf("localhost:%d", debugPort), nil)) }() } diff --git a/list.go b/list.go index 331d0bf..891d3f7 100644 --- a/list.go +++ b/list.go @@ -904,9 +904,7 @@ func (l *List) InputHandler() func(event *tcell.EventKey, setFocus func(p Primit } x, y, _, _ := l.GetInnerRect() - l.Unlock() - l.ContextMenu.show(l.currentItem, x+offsetX, y+offsetY, setFocus) - l.Lock() + defer l.ContextMenu.show(l.currentItem, x+offsetX, y+offsetY, setFocus) } else if l.currentItem >= 0 && l.currentItem < len(l.items) { item := l.items[l.currentItem] if item.Enabled { @@ -1015,14 +1013,18 @@ func (l *List) indexAtPoint(x, y int) int { // MouseHandler returns the mouse handler for this primitive. func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { return l.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) { + l.Lock() + // Pass events to context menu. if l.ContextMenu.open && l.ContextMenu.list != nil && l.ContextMenu.list.InRect(event.Position()) { - l.ContextMenu.list.MouseHandler()(action, event, setFocus) + defer l.ContextMenu.list.MouseHandler()(action, event, setFocus) consumed = true + l.Unlock() return } if !l.InRect(event.Position()) { + l.Unlock() return false, nil } @@ -1030,33 +1032,44 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse, switch action { case MouseLeftClick: if l.ContextMenu.open { - l.ContextMenu.hide(setFocus) + defer l.ContextMenu.hide(setFocus) consumed = true + l.Unlock() return } + l.Unlock() setFocus(l) + l.Lock() + index := l.indexAtPoint(event.Position()) if index != -1 { item := l.items[index] if item.Enabled { l.currentItem = index if item.Selected != nil { + l.Unlock() item.Selected() + l.Lock() } if l.selected != nil { + l.Unlock() l.selected(index, item.MainText, item.SecondaryText, item.Shortcut) + l.Lock() } if index != l.currentItem && l.changed != nil { + l.Unlock() l.changed(index, item.MainText, item.SecondaryText, item.Shortcut) + l.Lock() } } } consumed = true case MouseMiddleClick: if l.ContextMenu.open { - l.ContextMenu.hide(setFocus) + defer l.ContextMenu.hide(setFocus) consumed = true + l.Unlock() return } case MouseRightDown: @@ -1068,16 +1081,16 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse, if item.Enabled { l.currentItem = index if index != l.currentItem && l.changed != nil { + l.Unlock() l.changed(index, item.MainText, item.SecondaryText, item.Shortcut) + l.Lock() } } } if l.ContextMenu.list != nil && len(l.ContextMenu.list.items) > 0 { - l.Unlock() - l.ContextMenu.show(l.currentItem, x, y, setFocus) - l.Lock() l.ContextMenu.drag = true + defer l.ContextMenu.show(l.currentItem, x, y, setFocus) } else { defer l.MouseHandler()(MouseLeftClick, event, setFocus) } @@ -1111,6 +1124,7 @@ func (l *List) MouseHandler() func(action MouseAction, event *tcell.EventMouse, consumed = true } + l.Unlock() return }) }