mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-08-08 22:36:49 +02:00
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.
This commit is contained in:
@@ -357,3 +357,19 @@ func (self *ContextMgr) CurrentPopup() []types.Context {
|
||||
return context.GetKind() == types.TEMPORARY_POPUP || context.GetKind() == types.PERSISTENT_POPUP
|
||||
})
|
||||
}
|
||||
|
||||
func (self *ContextMgr) NextInStack(c types.Context) types.Context {
|
||||
self.RLock()
|
||||
defer self.RUnlock()
|
||||
|
||||
for i := range self.ContextStack {
|
||||
if self.ContextStack[i].GetKey() == c.GetKey() {
|
||||
if i == 0 {
|
||||
return nil
|
||||
}
|
||||
return self.ContextStack[i-1]
|
||||
}
|
||||
}
|
||||
|
||||
panic("context not in stack")
|
||||
}
|
||||
|
@@ -131,7 +131,9 @@ func (self *ContextLinesController) currentSidePanel() types.Context {
|
||||
currentContext := self.c.Context().CurrentStatic()
|
||||
if currentContext.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY ||
|
||||
currentContext.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {
|
||||
return currentContext.GetParentContext()
|
||||
if sidePanelContext := self.c.Context().NextInStack(currentContext); sidePanelContext != nil {
|
||||
return sidePanelContext
|
||||
}
|
||||
}
|
||||
|
||||
return currentContext
|
||||
|
@@ -56,21 +56,16 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
||||
func (self *MainViewController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
|
||||
return []*gocui.ViewMouseBinding{
|
||||
{
|
||||
ViewName: self.context.GetViewName(),
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: func(opts gocui.ViewMouseBindingOpts) error {
|
||||
if self.isFocused() {
|
||||
return self.onClick(opts)
|
||||
}
|
||||
|
||||
self.context.SetParentContext(self.otherContext.GetParentContext())
|
||||
self.c.Context().Push(self.context, types.OnFocusOpts{
|
||||
ClickedWindowName: self.context.GetWindowName(),
|
||||
ClickedViewLineIdx: opts.Y,
|
||||
})
|
||||
|
||||
return nil
|
||||
},
|
||||
ViewName: self.context.GetViewName(),
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: self.onClickInAlreadyFocusedView,
|
||||
FocusedView: self.context.GetViewName(),
|
||||
},
|
||||
{
|
||||
ViewName: self.context.GetViewName(),
|
||||
Key: gocui.MouseLeft,
|
||||
Handler: self.onClickInOtherViewOfMainViewPair,
|
||||
FocusedView: self.otherContext.GetViewName(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -81,7 +76,6 @@ func (self *MainViewController) Context() types.Context {
|
||||
|
||||
func (self *MainViewController) togglePanel() error {
|
||||
if self.otherContext.GetView().Visible {
|
||||
self.otherContext.SetParentContext(self.context.GetParentContext())
|
||||
self.c.Context().Push(self.otherContext, types.OnFocusOpts{})
|
||||
}
|
||||
|
||||
@@ -93,14 +87,23 @@ func (self *MainViewController) escape() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *MainViewController) onClick(opts gocui.ViewMouseBindingOpts) error {
|
||||
parentCtx := self.context.GetParentContext()
|
||||
if parentCtx.GetOnClickFocusedMainView() != nil {
|
||||
return parentCtx.GetOnClickFocusedMainView()(self.context.GetViewName(), opts.Y)
|
||||
func (self *MainViewController) onClickInAlreadyFocusedView(opts gocui.ViewMouseBindingOpts) error {
|
||||
sidePanelContext := self.c.Context().NextInStack(self.context)
|
||||
if sidePanelContext != nil && sidePanelContext.GetOnClickFocusedMainView() != nil {
|
||||
return sidePanelContext.GetOnClickFocusedMainView()(self.context.GetViewName(), opts.Y)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *MainViewController) onClickInOtherViewOfMainViewPair(opts gocui.ViewMouseBindingOpts) error {
|
||||
self.c.Context().Push(self.context, types.OnFocusOpts{
|
||||
ClickedWindowName: self.context.GetWindowName(),
|
||||
ClickedViewLineIdx: opts.Y,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *MainViewController) openSearch() error {
|
||||
if manager := self.c.GetViewBufferManagerForView(self.context.GetView()); manager != nil {
|
||||
manager.ReadToEnd(func() {
|
||||
@@ -112,7 +115,3 @@ func (self *MainViewController) openSearch() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *MainViewController) isFocused() bool {
|
||||
return self.c.Context().Current().GetKey() == self.context.GetKey()
|
||||
}
|
||||
|
@@ -106,7 +106,9 @@ func (self *RenameSimilarityThresholdController) currentSidePanel() types.Contex
|
||||
currentContext := self.c.Context().CurrentStatic()
|
||||
if currentContext.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY ||
|
||||
currentContext.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {
|
||||
return currentContext.GetParentContext()
|
||||
if sidePanelContext := self.c.Context().NextInStack(currentContext); sidePanelContext != nil {
|
||||
return sidePanelContext
|
||||
}
|
||||
}
|
||||
|
||||
return currentContext
|
||||
|
@@ -60,20 +60,18 @@ func (self *SwitchToFocusedMainViewController) Context() types.Context {
|
||||
}
|
||||
|
||||
func (self *SwitchToFocusedMainViewController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
|
||||
return self.focusMainView("main")
|
||||
return self.focusMainView(self.c.Contexts().Normal)
|
||||
}
|
||||
|
||||
func (self *SwitchToFocusedMainViewController) onClickSecondary(opts gocui.ViewMouseBindingOpts) error {
|
||||
return self.focusMainView("secondary")
|
||||
return self.focusMainView(self.c.Contexts().NormalSecondary)
|
||||
}
|
||||
|
||||
func (self *SwitchToFocusedMainViewController) handleFocusMainView() error {
|
||||
return self.focusMainView("main")
|
||||
return self.focusMainView(self.c.Contexts().Normal)
|
||||
}
|
||||
|
||||
func (self *SwitchToFocusedMainViewController) focusMainView(mainViewName string) error {
|
||||
mainViewContext := self.c.Helpers().Window.GetContextForWindow(mainViewName)
|
||||
mainViewContext.SetParentContext(self.context)
|
||||
func (self *SwitchToFocusedMainViewController) focusMainView(mainViewContext types.Context) error {
|
||||
if context, ok := mainViewContext.(types.ISearchableContext); ok {
|
||||
context.ClearSearchString()
|
||||
}
|
||||
|
@@ -300,6 +300,7 @@ type IContextMgr interface {
|
||||
CurrentStatic() Context
|
||||
CurrentSide() Context
|
||||
CurrentPopup() []Context
|
||||
NextInStack(context Context) Context
|
||||
IsCurrent(c Context) bool
|
||||
IsCurrentOrParent(c Context) bool
|
||||
ForEach(func(Context))
|
||||
|
@@ -152,9 +152,9 @@ func (gui *Gui) postRefreshUpdate(c types.Context) {
|
||||
// just don't rerender the view while searching, on the assumption that users will probably
|
||||
// either search or change their data, but not both at the same time.
|
||||
if !currentCtx.GetView().IsSearching() {
|
||||
parentCtx := currentCtx.GetParentContext()
|
||||
if parentCtx.GetKey() == c.GetKey() {
|
||||
parentCtx.HandleRenderToMain()
|
||||
sidePanelContext := gui.State.ContextMgr.NextInStack(currentCtx)
|
||||
if sidePanelContext != nil && sidePanelContext.GetKey() == c.GetKey() {
|
||||
sidePanelContext.HandleRenderToMain()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user