Skip to content

Commit d5b4f7b

Browse files
committed
Rerender certain views when their width changes
Situations where a view's width changes: - changing screen modes - enter staging or patch building - resizing the terminal window For the first of these we currently have special code to force a rerender, since some views render different content depending on whether they are in full-screen mode. We'll be able to remove that code now, since this new generic mechanism takes care of that too. But we will need this more general mechanism for cases where views truncate their content to the view width; we'll add one example for that later in this branch.
1 parent 3cee4de commit d5b4f7b

File tree

8 files changed

+88
-52
lines changed

8 files changed

+88
-52
lines changed

pkg/gui/context/base_context.go

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ type BaseContext struct {
2020
onFocusFn onFocusFn
2121
onFocusLostFn onFocusLostFn
2222

23-
focusable bool
24-
transient bool
25-
hasControlledBounds bool
26-
highlightOnFocus bool
23+
focusable bool
24+
transient bool
25+
hasControlledBounds bool
26+
needsRerenderOnWidthChange bool
27+
highlightOnFocus bool
2728

2829
*ParentContextMgr
2930
}
@@ -36,14 +37,15 @@ type (
3637
var _ types.IBaseContext = &BaseContext{}
3738

3839
type NewBaseContextOpts struct {
39-
Kind types.ContextKind
40-
Key types.ContextKey
41-
View *gocui.View
42-
WindowName string
43-
Focusable bool
44-
Transient bool
45-
HasUncontrolledBounds bool // negating for the sake of making false the default
46-
HighlightOnFocus bool
40+
Kind types.ContextKind
41+
Key types.ContextKey
42+
View *gocui.View
43+
WindowName string
44+
Focusable bool
45+
Transient bool
46+
HasUncontrolledBounds bool // negating for the sake of making false the default
47+
HighlightOnFocus bool
48+
NeedsRerenderOnWidthChange bool
4749

4850
OnGetOptionsMap func() map[string]string
4951
}
@@ -54,17 +56,18 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext {
5456
hasControlledBounds := !opts.HasUncontrolledBounds
5557

5658
return &BaseContext{
57-
kind: opts.Kind,
58-
key: opts.Key,
59-
view: opts.View,
60-
windowName: opts.WindowName,
61-
onGetOptionsMap: opts.OnGetOptionsMap,
62-
focusable: opts.Focusable,
63-
transient: opts.Transient,
64-
hasControlledBounds: hasControlledBounds,
65-
highlightOnFocus: opts.HighlightOnFocus,
66-
ParentContextMgr: &ParentContextMgr{},
67-
viewTrait: viewTrait,
59+
kind: opts.Kind,
60+
key: opts.Key,
61+
view: opts.View,
62+
windowName: opts.WindowName,
63+
onGetOptionsMap: opts.OnGetOptionsMap,
64+
focusable: opts.Focusable,
65+
transient: opts.Transient,
66+
hasControlledBounds: hasControlledBounds,
67+
highlightOnFocus: opts.HighlightOnFocus,
68+
needsRerenderOnWidthChange: opts.NeedsRerenderOnWidthChange,
69+
ParentContextMgr: &ParentContextMgr{},
70+
viewTrait: viewTrait,
6871
}
6972
}
7073

@@ -190,6 +193,10 @@ func (self *BaseContext) HasControlledBounds() bool {
190193
return self.hasControlledBounds
191194
}
192195

196+
func (self *BaseContext) NeedsRerenderOnWidthChange() bool {
197+
return self.needsRerenderOnWidthChange
198+
}
199+
193200
func (self *BaseContext) Title() string {
194201
return ""
195202
}

pkg/gui/context/branches_context.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext {
4040
FilteredListViewModel: viewModel,
4141
ListContextTrait: &ListContextTrait{
4242
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
43-
View: c.Views().Branches,
44-
WindowName: "branches",
45-
Key: LOCAL_BRANCHES_CONTEXT_KEY,
46-
Kind: types.SIDE_CONTEXT,
47-
Focusable: true,
43+
View: c.Views().Branches,
44+
WindowName: "branches",
45+
Key: LOCAL_BRANCHES_CONTEXT_KEY,
46+
Kind: types.SIDE_CONTEXT,
47+
Focusable: true,
48+
NeedsRerenderOnWidthChange: true,
4849
})),
4950
ListRenderer: ListRenderer{
5051
list: viewModel,

pkg/gui/context/local_commits_context.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
6868
SearchTrait: NewSearchTrait(c),
6969
ListContextTrait: &ListContextTrait{
7070
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
71-
View: c.Views().Commits,
72-
WindowName: "commits",
73-
Key: LOCAL_COMMITS_CONTEXT_KEY,
74-
Kind: types.SIDE_CONTEXT,
75-
Focusable: true,
71+
View: c.Views().Commits,
72+
WindowName: "commits",
73+
Key: LOCAL_COMMITS_CONTEXT_KEY,
74+
Kind: types.SIDE_CONTEXT,
75+
Focusable: true,
76+
NeedsRerenderOnWidthChange: true,
7677
})),
7778
ListRenderer: ListRenderer{
7879
list: viewModel,

pkg/gui/context/reflog_commits_context.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ func NewReflogCommitsContext(c *ContextCommon) *ReflogCommitsContext {
4343
FilteredListViewModel: viewModel,
4444
ListContextTrait: &ListContextTrait{
4545
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
46-
View: c.Views().ReflogCommits,
47-
WindowName: "commits",
48-
Key: REFLOG_COMMITS_CONTEXT_KEY,
49-
Kind: types.SIDE_CONTEXT,
50-
Focusable: true,
46+
View: c.Views().ReflogCommits,
47+
WindowName: "commits",
48+
Key: REFLOG_COMMITS_CONTEXT_KEY,
49+
Kind: types.SIDE_CONTEXT,
50+
Focusable: true,
51+
NeedsRerenderOnWidthChange: true,
5152
})),
5253
ListRenderer: ListRenderer{
5354
list: viewModel,

pkg/gui/context/remote_branches_context.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ func NewRemoteBranchesContext(
3636
DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.RemoteBranchesDynamicTitle),
3737
ListContextTrait: &ListContextTrait{
3838
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
39-
View: c.Views().RemoteBranches,
40-
WindowName: "branches",
41-
Key: REMOTE_BRANCHES_CONTEXT_KEY,
42-
Kind: types.SIDE_CONTEXT,
43-
Focusable: true,
44-
Transient: true,
39+
View: c.Views().RemoteBranches,
40+
WindowName: "branches",
41+
Key: REMOTE_BRANCHES_CONTEXT_KEY,
42+
Kind: types.SIDE_CONTEXT,
43+
Focusable: true,
44+
Transient: true,
45+
NeedsRerenderOnWidthChange: true,
4546
})),
4647
ListRenderer: ListRenderer{
4748
list: viewModel,

pkg/gui/context/sub_commits_context.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,13 @@ func NewSubCommitsContext(
115115
DynamicTitleBuilder: NewDynamicTitleBuilder(c.Tr.SubCommitsDynamicTitle),
116116
ListContextTrait: &ListContextTrait{
117117
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
118-
View: c.Views().SubCommits,
119-
WindowName: "branches",
120-
Key: SUB_COMMITS_CONTEXT_KEY,
121-
Kind: types.SIDE_CONTEXT,
122-
Focusable: true,
123-
Transient: true,
118+
View: c.Views().SubCommits,
119+
WindowName: "branches",
120+
Key: SUB_COMMITS_CONTEXT_KEY,
121+
Kind: types.SIDE_CONTEXT,
122+
Focusable: true,
123+
Transient: true,
124+
NeedsRerenderOnWidthChange: true,
124125
})),
125126
ListRenderer: ListRenderer{
126127
list: viewModel,

pkg/gui/layout.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ func (gui *Gui) layout(g *gocui.Gui) error {
4444
}
4545
}
4646

47+
contextsToRerender := []types.Context{}
48+
4749
// we assume that the view has already been created.
48-
setViewFromDimensions := func(viewName string, windowName string) (*gocui.View, error) {
50+
setViewFromDimensions := func(context types.Context) (*gocui.View, error) {
51+
viewName := context.GetViewName()
52+
windowName := context.GetWindowName()
53+
4954
dimensionsObj, ok := viewDimensions[windowName]
5055

5156
view, err := g.View(viewName)
@@ -67,6 +72,16 @@ func (gui *Gui) layout(g *gocui.Gui) error {
6772
if view.Frame {
6873
frameOffset = 0
6974
}
75+
76+
if context.NeedsRerenderOnWidthChange() {
77+
// view.Width() returns the width -1 for some reason
78+
oldWidth := view.Width() + 1
79+
newWidth := dimensionsObj.X1 - dimensionsObj.X0 + 2*frameOffset
80+
if oldWidth != newWidth {
81+
contextsToRerender = append(contextsToRerender, context)
82+
}
83+
}
84+
7085
_, err = g.SetView(
7186
viewName,
7287
dimensionsObj.X0-frameOffset,
@@ -85,7 +100,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
85100
continue
86101
}
87102

88-
_, err := setViewFromDimensions(context.GetViewName(), context.GetWindowName())
103+
_, err := setViewFromDimensions(context)
89104
if err != nil && !gocui.IsUnknownView(err) {
90105
return err
91106
}
@@ -146,6 +161,12 @@ func (gui *Gui) layout(g *gocui.Gui) error {
146161
}
147162
}
148163

164+
for _, context := range contextsToRerender {
165+
if err := context.HandleRender(); err != nil {
166+
return err
167+
}
168+
}
169+
149170
// here is a good place log some stuff
150171
// if you run `lazygit --logs`
151172
// this will let you see these branches as prettified json

pkg/gui/types/context.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ type IBaseContext interface {
6060
// determined independently.
6161
HasControlledBounds() bool
6262

63+
// true if the view needs to be rerendered when its width changes
64+
NeedsRerenderOnWidthChange() bool
65+
6366
// returns the desired title for the view upon activation. If there is no desired title (returns empty string), then
6467
// no title will be set
6568
Title() string

0 commit comments

Comments
 (0)