diff --git a/pkg/gui/context/base_context.go b/pkg/gui/context/base_context.go index 42147636858..acece19942a 100644 --- a/pkg/gui/context/base_context.go +++ b/pkg/gui/context/base_context.go @@ -20,10 +20,11 @@ type BaseContext struct { onFocusFn onFocusFn onFocusLostFn onFocusLostFn - focusable bool - transient bool - hasControlledBounds bool - highlightOnFocus bool + focusable bool + transient bool + hasControlledBounds bool + needsRerenderOnWidthChange bool + highlightOnFocus bool *ParentContextMgr } @@ -36,14 +37,15 @@ type ( var _ types.IBaseContext = &BaseContext{} type NewBaseContextOpts struct { - Kind types.ContextKind - Key types.ContextKey - View *gocui.View - WindowName string - Focusable bool - Transient bool - HasUncontrolledBounds bool // negating for the sake of making false the default - HighlightOnFocus bool + Kind types.ContextKind + Key types.ContextKey + View *gocui.View + WindowName string + Focusable bool + Transient bool + HasUncontrolledBounds bool // negating for the sake of making false the default + HighlightOnFocus bool + NeedsRerenderOnWidthChange bool OnGetOptionsMap func() map[string]string } @@ -54,17 +56,18 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext { hasControlledBounds := !opts.HasUncontrolledBounds return &BaseContext{ - kind: opts.Kind, - key: opts.Key, - view: opts.View, - windowName: opts.WindowName, - onGetOptionsMap: opts.OnGetOptionsMap, - focusable: opts.Focusable, - transient: opts.Transient, - hasControlledBounds: hasControlledBounds, - highlightOnFocus: opts.HighlightOnFocus, - ParentContextMgr: &ParentContextMgr{}, - viewTrait: viewTrait, + kind: opts.Kind, + key: opts.Key, + view: opts.View, + windowName: opts.WindowName, + onGetOptionsMap: opts.OnGetOptionsMap, + focusable: opts.Focusable, + transient: opts.Transient, + hasControlledBounds: hasControlledBounds, + highlightOnFocus: opts.HighlightOnFocus, + needsRerenderOnWidthChange: opts.NeedsRerenderOnWidthChange, + ParentContextMgr: &ParentContextMgr{}, + viewTrait: viewTrait, } } @@ -190,6 +193,10 @@ func (self *BaseContext) HasControlledBounds() bool { return self.hasControlledBounds } +func (self *BaseContext) NeedsRerenderOnWidthChange() bool { + return self.needsRerenderOnWidthChange +} + func (self *BaseContext) Title() string { return "" } diff --git a/pkg/gui/context/branches_context.go b/pkg/gui/context/branches_context.go index 68324d02090..79dfc7adc31 100644 --- a/pkg/gui/context/branches_context.go +++ b/pkg/gui/context/branches_context.go @@ -40,11 +40,12 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext { FilteredListViewModel: viewModel, ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().Branches, - WindowName: "branches", - Key: LOCAL_BRANCHES_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().Branches, + WindowName: "branches", + Key: LOCAL_BRANCHES_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index fa91e6a79e4..e0172638daa 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -68,11 +68,12 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext { SearchTrait: NewSearchTrait(c), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().Commits, - WindowName: "commits", - Key: LOCAL_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().Commits, + WindowName: "commits", + Key: LOCAL_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/reflog_commits_context.go b/pkg/gui/context/reflog_commits_context.go index a90507e8664..8dc52cde70a 100644 --- a/pkg/gui/context/reflog_commits_context.go +++ b/pkg/gui/context/reflog_commits_context.go @@ -43,11 +43,12 @@ func NewReflogCommitsContext(c *ContextCommon) *ReflogCommitsContext { FilteredListViewModel: viewModel, ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().ReflogCommits, - WindowName: "commits", - Key: REFLOG_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, + View: c.Views().ReflogCommits, + WindowName: "commits", + Key: REFLOG_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/remote_branches_context.go b/pkg/gui/context/remote_branches_context.go index 144a8c369f6..82d37b6139f 100644 --- a/pkg/gui/context/remote_branches_context.go +++ b/pkg/gui/context/remote_branches_context.go @@ -36,12 +36,13 @@ func NewRemoteBranchesContext( DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.RemoteBranchesDynamicTitle), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().RemoteBranches, - WindowName: "branches", - Key: REMOTE_BRANCHES_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, - Transient: true, + View: c.Views().RemoteBranches, + WindowName: "branches", + Key: REMOTE_BRANCHES_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + Transient: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 7bf34d190c8..79b0d97814d 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -115,12 +115,13 @@ func NewSubCommitsContext( DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.SubCommitsDynamicTitle), ListContextTrait: &ListContextTrait{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ - View: c.Views().SubCommits, - WindowName: "branches", - Key: SUB_COMMITS_CONTEXT_KEY, - Kind: types.SIDE_CONTEXT, - Focusable: true, - Transient: true, + View: c.Views().SubCommits, + WindowName: "branches", + Key: SUB_COMMITS_CONTEXT_KEY, + Kind: types.SIDE_CONTEXT, + Focusable: true, + Transient: true, + NeedsRerenderOnWidthChange: true, })), ListRenderer: ListRenderer{ list: viewModel, diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 2f6e21b7384..7b43f8aaa34 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -44,8 +44,13 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } + contextsToRerender := []types.Context{} + // we assume that the view has already been created. - setViewFromDimensions := func(viewName string, windowName string) (*gocui.View, error) { + setViewFromDimensions := func(context types.Context) (*gocui.View, error) { + viewName := context.GetViewName() + windowName := context.GetWindowName() + dimensionsObj, ok := viewDimensions[windowName] view, err := g.View(viewName) @@ -67,6 +72,16 @@ func (gui *Gui) layout(g *gocui.Gui) error { if view.Frame { frameOffset = 0 } + + if context.NeedsRerenderOnWidthChange() { + // view.Width() returns the width -1 for some reason + oldWidth := view.Width() + 1 + newWidth := dimensionsObj.X1 - dimensionsObj.X0 + 2*frameOffset + if oldWidth != newWidth { + contextsToRerender = append(contextsToRerender, context) + } + } + _, err = g.SetView( viewName, dimensionsObj.X0-frameOffset, @@ -85,7 +100,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { continue } - _, err := setViewFromDimensions(context.GetViewName(), context.GetWindowName()) + _, err := setViewFromDimensions(context) if err != nil && !gocui.IsUnknownView(err) { return err } @@ -146,6 +161,12 @@ func (gui *Gui) layout(g *gocui.Gui) error { } } + for _, context := range contextsToRerender { + if err := context.HandleRender(); err != nil { + return err + } + } + // here is a good place log some stuff // if you run `lazygit --logs` // this will let you see these branches as prettified json diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index c47945aee79..aca694228aa 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -60,6 +60,9 @@ type IBaseContext interface { // determined independently. HasControlledBounds() bool + // true if the view needs to be rerendered when its width changes + NeedsRerenderOnWidthChange() bool + // returns the desired title for the view upon activation. If there is no desired title (returns empty string), then // no title will be set Title() string