fix deadlock with searchbar
This commit is contained in:
+29
-34
@@ -24,8 +24,9 @@ type BrowsingPane struct {
|
|||||||
widget.BaseWidget
|
widget.BaseWidget
|
||||||
|
|
||||||
searchBar *searchField
|
searchBar *searchField
|
||||||
searchTimer *time.Timer
|
pendingSearchLock sync.Mutex
|
||||||
searchTimerLock sync.Mutex
|
pendingSearch bool
|
||||||
|
searchGoroutine bool
|
||||||
cancelPendingSearch context.CancelFunc
|
cancelPendingSearch context.CancelFunc
|
||||||
curPage Page
|
curPage Page
|
||||||
|
|
||||||
@@ -138,33 +139,37 @@ func (b *BrowsingPane) SetPage(p Page) {
|
|||||||
|
|
||||||
func (b *BrowsingPane) onSearchTextChanged(text string) {
|
func (b *BrowsingPane) onSearchTextChanged(text string) {
|
||||||
if text == "" {
|
if text == "" {
|
||||||
if b.cancelPendingSearch != nil {
|
|
||||||
b.cancelPendingSearch()
|
|
||||||
b.cancelPendingSearch = nil
|
|
||||||
}
|
|
||||||
b.sendSearch("")
|
b.sendSearch("")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
b.searchTimerLock.Lock()
|
b.pendingSearchLock.Lock()
|
||||||
defer b.searchTimerLock.Unlock()
|
defer b.pendingSearchLock.Unlock()
|
||||||
if b.searchTimer == nil {
|
b.pendingSearch = true
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
if !b.searchGoroutine {
|
||||||
b.cancelPendingSearch = cancel
|
go b.waitAndSearch()
|
||||||
b.searchTimer = time.NewTimer(200 * time.Millisecond)
|
b.searchGoroutine = true
|
||||||
go func(ctx context.Context, trigger <-chan time.Time) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BrowsingPane) waitAndSearch() {
|
||||||
|
t := time.NewTicker(200 * time.Millisecond)
|
||||||
|
var getReadyToSearch bool
|
||||||
|
var done bool
|
||||||
|
for !done {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-t.C:
|
||||||
b.searchTimerLock.Lock()
|
b.pendingSearchLock.Lock()
|
||||||
defer b.searchTimerLock.Unlock()
|
if b.pendingSearch {
|
||||||
b.searchTimer = nil
|
getReadyToSearch = true
|
||||||
case <-trigger:
|
b.pendingSearch = false
|
||||||
|
} else if getReadyToSearch {
|
||||||
b.sendSearch(b.searchBar.Text)
|
b.sendSearch(b.searchBar.Text)
|
||||||
b.searchTimerLock.Lock()
|
t.Stop()
|
||||||
defer b.searchTimerLock.Unlock()
|
b.searchGoroutine = false
|
||||||
b.searchTimer = nil
|
done = true
|
||||||
|
}
|
||||||
|
b.pendingSearchLock.Unlock()
|
||||||
}
|
}
|
||||||
}(ctx, b.searchTimer.C)
|
|
||||||
} else {
|
|
||||||
b.resetSearchTimer(200 * time.Millisecond)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,13 +182,3 @@ func (b *BrowsingPane) sendSearch(query string) {
|
|||||||
func (b *BrowsingPane) CreateRenderer() fyne.WidgetRenderer {
|
func (b *BrowsingPane) CreateRenderer() fyne.WidgetRenderer {
|
||||||
return widget.NewSimpleRenderer(b.container)
|
return widget.NewSimpleRenderer(b.container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BrowsingPane) resetSearchTimer(d time.Duration) {
|
|
||||||
if b.searchTimer == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !b.searchTimer.Stop() {
|
|
||||||
<-b.searchTimer.C
|
|
||||||
}
|
|
||||||
b.searchTimer.Reset(d)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user