Skip to content

Commit e052c1d

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 6f13ed8 commit e052c1d

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
@@ -105,6 +108,7 @@ func (self *ListContextTrait) HandleRender() {
105108
startIdx, length := self.GetViewTrait().ViewPortYBounds()
106109
content := self.renderLines(startIdx, startIdx+length)
107110
self.GetViewTrait().SetViewPortContentAndClearEverythingElse(totalLength, content)
111+
self.needRerenderVisibleLines = false
108112
} else {
109113
content := self.renderLines(-1, -1)
110114
self.GetViewTrait().SetContent(content)
@@ -141,6 +145,10 @@ func (self *ListContextTrait) RenderOnlyVisibleLines() bool {
141145
return self.renderOnlyVisibleLines
142146
}
143147

148+
func (self *ListContextTrait) SetNeedRerenderVisibleLines() {
149+
self.needRerenderVisibleLines = true
150+
}
151+
144152
func (self *ListContextTrait) TotalContentHeight() int {
145153
result := self.list.Len()
146154
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)