diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go index ca04a2fa9..2fd37bb9a 100644 --- a/pkg/gui/context/base_context.go +++ b/pkg/gui/context/base_context.go @@ -212,3 +212,7 @@ func (self *BaseContext) NeedsRerenderOnHeightChange() bool { func (self *BaseContext) Title() string { return "" } + +func (self *BaseContext) TotalContentHeight() int { + return self.view.ViewLinesHeight() +} diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go index 773f946a9..bce3ae344 100644 --- a/pkg/gui/context/list_context_trait.go +++ b/pkg/gui/context/list_context_trait.go @@ -140,3 +140,11 @@ func (self *ListContextTrait) RangeSelectEnabled() bool { func (self *ListContextTrait) RenderOnlyVisibleLines() bool { return self.renderOnlyVisibleLines } + +func (self *ListContextTrait) TotalContentHeight() int { + result := self.list.Len() + if self.getNonModelItems != nil { + result += len(self.getNonModelItems()) + } + return result +} diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 62c2233dd..03cd07b60 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -73,6 +73,19 @@ func (gui *Gui) layout(g *gocui.Gui) error { } mustRerender := false + newHeight := dimensionsObj.Y1 - dimensionsObj.Y0 + 2*frameOffset + maxOriginY := context.TotalContentHeight() + if !view.CanScrollPastBottom { + maxOriginY -= newHeight - 1 + } + if oldOriginY := view.OriginY(); oldOriginY > maxOriginY { + view.ScrollUp(oldOriginY - maxOriginY) + // the view might not have scrolled actually (if it was at the limit + // already), so we need to check if it did + if oldOriginY != view.OriginY() && context.NeedsRerenderOnHeightChange() { + mustRerender = true + } + } if context.NeedsRerenderOnWidthChange() == types.NEEDS_RERENDER_ON_WIDTH_CHANGE_WHEN_WIDTH_CHANGES { // view.Width() returns the width -1 for some reason oldWidth := view.Width() + 1 diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index 2948f2eda..f48a6b595 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -71,6 +71,9 @@ type IBaseContext interface { // determined independently. HasControlledBounds() bool + // the total height of the content that the view is currently showing + TotalContentHeight() int + // to what extent the view needs to be rerendered when its width changes NeedsRerenderOnWidthChange() NeedsRerenderOnWidthChangeLevel