Skip to content

Commit be921f0

Browse files
committed
Rerender visible lines when scrolling by page
This fixes a bug in ListContextTrait.FocusLine whereby the view would go blank when scrolling by page (using ',' or '.') in views that have renderOnlyVisibleLines set to true but refreshViewportOnChange set to false. Currently we don't have any such views; the only ones who use renderOnlyVisibleLines are commits and subcommits, and they also use refreshViewportOnChange. However, we are going to add one in the next commit, and eventually it might be a good idea to convert all our list views to that by default, and get rid of the renderOnlyVisibleLines flag.
1 parent a01c9a9 commit be921f0

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

pkg/gui/context/list_context_trait.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ type ListContextTrait struct {
2121
// If this is true, we only render the visible lines of the list. Useful for lists that can
2222
// get very long, because it can save a lot of memory
2323
renderOnlyVisibleLines bool
24+
// If renderOnlyVisibleLines is true, needRerenderVisibleLines indicates whether we need to
25+
// rerender the visible lines e.g. because the scroll position changed
26+
needRerenderVisibleLines bool
2427
}
2528

2629
func (self *ListContextTrait) IsListContext() {}
@@ -50,8 +53,8 @@ func (self *ListContextTrait) FocusLine(scrollIntoView bool) {
5053
self.refreshViewport()
5154
} else if self.renderOnlyVisibleLines {
5255
newOrigin, _ := self.GetViewTrait().ViewPortYBounds()
53-
if oldOrigin != newOrigin {
54-
self.HandleRender()
56+
if oldOrigin != newOrigin || self.needRerenderVisibleLines {
57+
self.refreshViewport()
5558
}
5659
}
5760
return nil
@@ -106,6 +109,7 @@ func (self *ListContextTrait) HandleRender() {
106109
startIdx, length := self.GetViewTrait().ViewPortYBounds()
107110
content := self.renderLines(startIdx, startIdx+length)
108111
self.GetViewTrait().SetViewPortContentAndClearEverythingElse(content)
112+
self.needRerenderVisibleLines = false
109113
} else {
110114
content := self.renderLines(-1, -1)
111115
self.GetViewTrait().SetContent(content)
@@ -142,6 +146,10 @@ func (self *ListContextTrait) RenderOnlyVisibleLines() bool {
142146
return self.renderOnlyVisibleLines
143147
}
144148

149+
func (self *ListContextTrait) SetNeedRerenderVisibleLines() {
150+
self.needRerenderVisibleLines = true
151+
}
152+
145153
func (self *ListContextTrait) TotalContentHeight() int {
146154
result := self.list.Len()
147155
if self.getNonModelItems != nil {

pkg/gui/controllers/list_controller.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ func (self *ListController) handlePageChange(delta int) error {
178178
}
179179
}
180180

181+
// Since we already scrolled the view above, the normal mechanism that
182+
// ListContextTrait.FocusLine uses for deciding whether rerendering is needed won't work. It is
183+
// based on checking whether the origin was changed by the call to FocusPoint in that function,
184+
// but since we scrolled the view directly above, the origin has already been updated. So we
185+
// must tell it explicitly to rerender.
186+
self.context.SetNeedRerenderVisibleLines()
187+
181188
// Since we are maintaining the scroll position ourselves above, there's no point in passing
182189
// ScrollSelectionIntoView=true here.
183190
self.context.HandleFocus(types.OnFocusOpts{})

pkg/gui/types/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ type IListContext interface {
182182
IsListContext() // used for type switch
183183
RangeSelectEnabled() bool
184184
RenderOnlyVisibleLines() bool
185+
SetNeedRerenderVisibleLines()
185186

186187
IndexForGotoBottom() int
187188
}

0 commit comments

Comments
 (0)