Skip to content

Commit 6705428

Browse files
authored
Fix crash when clicking in the status view (#4567)
- **PR Description** The status view is not supposed to be focusable right now. (This might change soon, but for now it isn't.) Pressing '0' on it does nothing. However, clicking on it would still focus it, because the click handler in MainViewController assumed that when the clicked view doesn't have the focus, then its "other" view must have, and we just want to toggle the focus between the two (like when pressing tab). It didn't take the possibility into account that the current side panel isn't focusable at all; if it was, then its SwitchToFocusedMainViewController would have handled the click. To fix this, check if the "other" view has the focus before handling the click, and do nothing otherwise. This also fixes clicking in the main views of the Worktrees or Submodules tabs, or any other tabs whose main views are not focusable. Fixes #4566.
2 parents eecb59d + bbd17ab commit 6705428

File tree

7 files changed

+53
-35
lines changed

7 files changed

+53
-35
lines changed

pkg/gui/context.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,19 @@ func (self *ContextMgr) CurrentPopup() []types.Context {
357357
return context.GetKind() == types.TEMPORARY_POPUP || context.GetKind() == types.PERSISTENT_POPUP
358358
})
359359
}
360+
361+
func (self *ContextMgr) NextInStack(c types.Context) types.Context {
362+
self.RLock()
363+
defer self.RUnlock()
364+
365+
for i := range self.ContextStack {
366+
if self.ContextStack[i].GetKey() == c.GetKey() {
367+
if i == 0 {
368+
return nil
369+
}
370+
return self.ContextStack[i-1]
371+
}
372+
}
373+
374+
panic("context not in stack")
375+
}

pkg/gui/controllers/context_lines_controller.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ func (self *ContextLinesController) currentSidePanel() types.Context {
131131
currentContext := self.c.Context().CurrentStatic()
132132
if currentContext.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY ||
133133
currentContext.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {
134-
return currentContext.GetParentContext()
134+
if sidePanelContext := self.c.Context().NextInStack(currentContext); sidePanelContext != nil {
135+
return sidePanelContext
136+
}
135137
}
136138

137139
return currentContext

pkg/gui/controllers/main_view_controller.go

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,16 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
5656
func (self *MainViewController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
5757
return []*gocui.ViewMouseBinding{
5858
{
59-
ViewName: self.context.GetViewName(),
60-
Key: gocui.MouseLeft,
61-
Handler: func(opts gocui.ViewMouseBindingOpts) error {
62-
if self.isFocused() {
63-
return self.onClick(opts)
64-
}
65-
66-
self.context.SetParentContext(self.otherContext.GetParentContext())
67-
self.c.Context().Push(self.context, types.OnFocusOpts{
68-
ClickedWindowName: self.context.GetWindowName(),
69-
ClickedViewLineIdx: opts.Y,
70-
})
71-
72-
return nil
73-
},
59+
ViewName: self.context.GetViewName(),
60+
Key: gocui.MouseLeft,
61+
Handler: self.onClickInAlreadyFocusedView,
62+
FocusedView: self.context.GetViewName(),
63+
},
64+
{
65+
ViewName: self.context.GetViewName(),
66+
Key: gocui.MouseLeft,
67+
Handler: self.onClickInOtherViewOfMainViewPair,
68+
FocusedView: self.otherContext.GetViewName(),
7469
},
7570
}
7671
}
@@ -81,7 +76,6 @@ func (self *MainViewController) Context() types.Context {
8176

8277
func (self *MainViewController) togglePanel() error {
8378
if self.otherContext.GetView().Visible {
84-
self.otherContext.SetParentContext(self.context.GetParentContext())
8579
self.c.Context().Push(self.otherContext, types.OnFocusOpts{})
8680
}
8781

@@ -93,14 +87,23 @@ func (self *MainViewController) escape() error {
9387
return nil
9488
}
9589

96-
func (self *MainViewController) onClick(opts gocui.ViewMouseBindingOpts) error {
97-
parentCtx := self.context.GetParentContext()
98-
if parentCtx.GetOnClickFocusedMainView() != nil {
99-
return parentCtx.GetOnClickFocusedMainView()(self.context.GetViewName(), opts.Y)
90+
func (self *MainViewController) onClickInAlreadyFocusedView(opts gocui.ViewMouseBindingOpts) error {
91+
sidePanelContext := self.c.Context().NextInStack(self.context)
92+
if sidePanelContext != nil && sidePanelContext.GetOnClickFocusedMainView() != nil {
93+
return sidePanelContext.GetOnClickFocusedMainView()(self.context.GetViewName(), opts.Y)
10094
}
10195
return nil
10296
}
10397

98+
func (self *MainViewController) onClickInOtherViewOfMainViewPair(opts gocui.ViewMouseBindingOpts) error {
99+
self.c.Context().Push(self.context, types.OnFocusOpts{
100+
ClickedWindowName: self.context.GetWindowName(),
101+
ClickedViewLineIdx: opts.Y,
102+
})
103+
104+
return nil
105+
}
106+
104107
func (self *MainViewController) openSearch() error {
105108
if manager := self.c.GetViewBufferManagerForView(self.context.GetView()); manager != nil {
106109
manager.ReadToEnd(func() {
@@ -112,7 +115,3 @@ func (self *MainViewController) openSearch() error {
112115

113116
return nil
114117
}
115-
116-
func (self *MainViewController) isFocused() bool {
117-
return self.c.Context().Current().GetKey() == self.context.GetKey()
118-
}

pkg/gui/controllers/rename_similarity_threshold_controller.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,9 @@ func (self *RenameSimilarityThresholdController) currentSidePanel() types.Contex
106106
currentContext := self.c.Context().CurrentStatic()
107107
if currentContext.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY ||
108108
currentContext.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {
109-
return currentContext.GetParentContext()
109+
if sidePanelContext := self.c.Context().NextInStack(currentContext); sidePanelContext != nil {
110+
return sidePanelContext
111+
}
110112
}
111113

112114
return currentContext

pkg/gui/controllers/switch_to_focused_main_view_controller.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,18 @@ func (self *SwitchToFocusedMainViewController) Context() types.Context {
6060
}
6161

6262
func (self *SwitchToFocusedMainViewController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
63-
return self.focusMainView("main")
63+
return self.focusMainView(self.c.Contexts().Normal)
6464
}
6565

6666
func (self *SwitchToFocusedMainViewController) onClickSecondary(opts gocui.ViewMouseBindingOpts) error {
67-
return self.focusMainView("secondary")
67+
return self.focusMainView(self.c.Contexts().NormalSecondary)
6868
}
6969

7070
func (self *SwitchToFocusedMainViewController) handleFocusMainView() error {
71-
return self.focusMainView("main")
71+
return self.focusMainView(self.c.Contexts().Normal)
7272
}
7373

74-
func (self *SwitchToFocusedMainViewController) focusMainView(mainViewName string) error {
75-
mainViewContext := self.c.Helpers().Window.GetContextForWindow(mainViewName)
76-
mainViewContext.SetParentContext(self.context)
74+
func (self *SwitchToFocusedMainViewController) focusMainView(mainViewContext types.Context) error {
7775
if context, ok := mainViewContext.(types.ISearchableContext); ok {
7876
context.ClearSearchString()
7977
}

pkg/gui/types/context.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ type IContextMgr interface {
300300
CurrentStatic() Context
301301
CurrentSide() Context
302302
CurrentPopup() []Context
303+
NextInStack(context Context) Context
303304
IsCurrent(c Context) bool
304305
IsCurrentOrParent(c Context) bool
305306
ForEach(func(Context))

pkg/gui/view_helpers.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ func (gui *Gui) postRefreshUpdate(c types.Context) {
152152
// just don't rerender the view while searching, on the assumption that users will probably
153153
// either search or change their data, but not both at the same time.
154154
if !currentCtx.GetView().IsSearching() {
155-
parentCtx := currentCtx.GetParentContext()
156-
if parentCtx.GetKey() == c.GetKey() {
157-
parentCtx.HandleRenderToMain()
155+
sidePanelContext := gui.State.ContextMgr.NextInStack(currentCtx)
156+
if sidePanelContext != nil && sidePanelContext.GetKey() == c.GetKey() {
157+
sidePanelContext.HandleRenderToMain()
158158
}
159159
}
160160
}

0 commit comments

Comments
 (0)