mirror of
https://github.com/jesseduffield/lazydocker.git
synced 2026-07-22 07:11:01 +00:00
fix focus issues
This commit is contained in:
parent
fb7b28243b
commit
aa8504b8f6
8 changed files with 63 additions and 93 deletions
|
|
@ -204,30 +204,15 @@ func (gui *Gui) sidePanelChildren(width int, height int) []*boxlayout.Box {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: reintroduce
|
||||
// func (gui *Gui) currentSideWindowName() string {
|
||||
// // there is always one and only one cyclable context in the context stack. We'll look from top to bottom
|
||||
// gui.State.ContextManager.RLock()
|
||||
// defer gui.State.ContextManager.RUnlock()
|
||||
|
||||
// for idx := range gui.State.ContextManager.ContextStack {
|
||||
// reversedIdx := len(gui.State.ContextManager.ContextStack) - 1 - idx
|
||||
// context := gui.State.ContextManager.ContextStack[reversedIdx]
|
||||
|
||||
// if context.GetKind() == types.SIDE_CONTEXT {
|
||||
// return context.GetWindowName()
|
||||
// }
|
||||
// }
|
||||
|
||||
// return "files" // default
|
||||
// }
|
||||
|
||||
// TODO: do this better.
|
||||
func (gui *Gui) currentSideWindowName() string {
|
||||
windowName := gui.currentWindow()
|
||||
if !lo.Contains(gui.sideViewNames(), windowName) {
|
||||
return gui.peekPreviousView()
|
||||
// we expect that there is a side window somewhere in the view stack, so we will search from top to bottom
|
||||
for idx := range gui.State.ViewStack {
|
||||
reversedIdx := len(gui.State.ViewStack) - 1 - idx
|
||||
viewName := gui.State.ViewStack[reversedIdx]
|
||||
if lo.Contains(gui.sideViewNames(), viewName) {
|
||||
return viewName
|
||||
}
|
||||
}
|
||||
|
||||
return windowName
|
||||
return gui.initiallyFocusedViewName()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (gui *Gui) prepareConfirmationPanel(currentView *gocui.View, title, prompt
|
|||
confirmationView.Title = title
|
||||
confirmationView.Visible = true
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
return gui.switchFocus(gui.g, currentView, confirmationView, false)
|
||||
return gui.switchFocus(confirmationView)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
|
@ -96,8 +96,8 @@ func (gui *Gui) onNewPopupPanel() {
|
|||
gui.Views.Confirmation.Visible = false
|
||||
}
|
||||
|
||||
// it is very important that within this function we never include the original prompt in any error messages, because it may contain e.g. a user password
|
||||
// unparam complains that handleClose is alwans nil but one day it won't be nil.
|
||||
// It is very important that within this function we never include the original prompt in any error messages, because it may contain e.g. a user password.
|
||||
// The golangcilint unparam linter complains that handleClose is alwans nil but one day it won't be nil.
|
||||
// nolint:unparam
|
||||
func (gui *Gui) createConfirmationPanel(g *gocui.Gui, currentView *gocui.View, title, prompt string, handleConfirm, handleClose func(*gocui.Gui, *gocui.View) error) error {
|
||||
return gui.createPopupPanel(g, currentView, title, prompt, false, handleConfirm, handleClose)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ type Gui struct {
|
|||
|
||||
type Mutexes struct {
|
||||
SubprocessMutex sync.Mutex
|
||||
ViewStackMutex sync.Mutex
|
||||
}
|
||||
|
||||
type servicePanelState struct {
|
||||
|
|
|
|||
|
|
@ -117,16 +117,13 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||
}
|
||||
|
||||
if gui.g.CurrentView() == nil {
|
||||
v, err := gui.g.View(gui.peekPreviousView())
|
||||
viewName := gui.initiallyFocusedViewName()
|
||||
view, err := gui.g.View(viewName)
|
||||
if err != nil {
|
||||
viewName := gui.initiallyFocusedViewName()
|
||||
v, err = gui.g.View(viewName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gui.switchFocus(gui.g, nil, v, false); err != nil {
|
||||
if err := gui.switchFocus(view); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ func (gui *Gui) handleEnterMain(g *gocui.Gui, v *gocui.View) error {
|
|||
mainView := gui.getMainView()
|
||||
mainView.ParentView = v
|
||||
|
||||
return gui.switchFocus(gui.g, v, mainView, false)
|
||||
return gui.switchFocus(mainView)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleExitMain(g *gocui.Gui, v *gocui.View) error {
|
||||
|
|
@ -122,5 +122,5 @@ func (gui *Gui) handleMainClick(g *gocui.Gui, v *gocui.View) error {
|
|||
v.ParentView = currentView
|
||||
}
|
||||
|
||||
return gui.switchFocus(gui.g, currentView, v, false)
|
||||
return gui.switchFocus(v)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,8 +100,7 @@ func (gui *Gui) createMenu(title string, items interface{}, itemCount int, handl
|
|||
|
||||
gui.g.Update(func(g *gocui.Gui) error {
|
||||
menuView.Visible = true
|
||||
currentView := gui.g.CurrentView()
|
||||
return gui.switchFocus(gui.g, currentView, menuView, false)
|
||||
return gui.switchFocus(menuView)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ func (gui *Gui) runSubprocess(cmd *exec.Cmd) error {
|
|||
|
||||
gui.PauseBackgroundThreads = true
|
||||
|
||||
cmdErr := gui.runSubprocess(cmd)
|
||||
cmdErr := gui.runCommand(cmd)
|
||||
|
||||
if err := gui.g.Resume(); err != nil {
|
||||
return gui.createErrorPanel(gui.g, err.Error())
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
|||
panic(err)
|
||||
}
|
||||
gui.resetMainView()
|
||||
gui.popView()
|
||||
return gui.switchFocus(g, v, focusedView, false)
|
||||
return gui.switchFocus(focusedView)
|
||||
}
|
||||
|
||||
func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
|
|
@ -59,8 +58,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
|||
panic(err)
|
||||
}
|
||||
gui.resetMainView()
|
||||
gui.popView()
|
||||
return gui.switchFocus(g, v, focusedView, false)
|
||||
return gui.switchFocus(focusedView)
|
||||
}
|
||||
|
||||
func (gui *Gui) resetMainView() {
|
||||
|
|
@ -96,24 +94,48 @@ func (gui *Gui) newLineFocused(v *gocui.View) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) popView() string {
|
||||
if len(gui.State.ViewStack) > 0 {
|
||||
value := gui.State.ViewStack[len(gui.State.ViewStack)-1]
|
||||
gui.State.ViewStack = gui.State.ViewStack[:len(gui.State.ViewStack)-1]
|
||||
return value
|
||||
}
|
||||
// TODO: move some of this logic into our onFocusLost and onFocus hooks
|
||||
func (gui *Gui) switchFocus(newView *gocui.View) error {
|
||||
gui.Mutexes.ViewStackMutex.Lock()
|
||||
defer gui.Mutexes.ViewStackMutex.Unlock()
|
||||
|
||||
return ""
|
||||
return gui.switchFocusAux(newView)
|
||||
}
|
||||
|
||||
func (gui *Gui) peekPreviousView() string {
|
||||
if len(gui.State.ViewStack) > 0 {
|
||||
return gui.State.ViewStack[len(gui.State.ViewStack)-1]
|
||||
func (gui *Gui) switchFocusAux(newView *gocui.View) error {
|
||||
gui.pushView(newView.Name())
|
||||
gui.Log.Info("setting highlight to true for view " + newView.Name())
|
||||
gui.Log.Info("new focused view is " + newView.Name())
|
||||
if _, err := gui.g.SetCurrentView(newView.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ""
|
||||
gui.g.Cursor = newView.Editable
|
||||
|
||||
if err := gui.renderPanelOptions(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.newLineFocused(newView)
|
||||
}
|
||||
|
||||
func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error {
|
||||
gui.Mutexes.ViewStackMutex.Lock()
|
||||
defer gui.Mutexes.ViewStackMutex.Unlock()
|
||||
|
||||
if len(gui.State.ViewStack) <= 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
previousViewName := gui.State.ViewStack[len(gui.State.ViewStack)-2]
|
||||
previousView, err := g.View(previousViewName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.switchFocusAux(previousView)
|
||||
}
|
||||
|
||||
// Not to be called directly. Use `switchFocus` instead
|
||||
func (gui *Gui) pushView(name string) {
|
||||
// No matter what view we're pushing, we first remove all popup panels from the stack
|
||||
gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool {
|
||||
|
|
@ -122,51 +144,17 @@ func (gui *Gui) pushView(name string) {
|
|||
|
||||
// If we're pushing a side panel, we remove all other panels
|
||||
if lo.Contains(gui.sideViewNames(), name) {
|
||||
gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool {
|
||||
return viewName != "main"
|
||||
})
|
||||
gui.State.ViewStack = []string{}
|
||||
}
|
||||
|
||||
// If we're pushing a panel that's already in the stack, we remove it
|
||||
gui.State.ViewStack = lo.Filter(gui.State.ViewStack, func(viewName string, _ int) bool {
|
||||
return viewName != name
|
||||
})
|
||||
|
||||
gui.State.ViewStack = append(gui.State.ViewStack, name)
|
||||
}
|
||||
|
||||
func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error {
|
||||
previousViewName := gui.popView()
|
||||
previousView, err := g.View(previousViewName)
|
||||
if err != nil {
|
||||
// always fall back to services view if there's no 'previous' view stored
|
||||
previousView, err = g.View(gui.initiallyFocusedViewName())
|
||||
if err != nil {
|
||||
gui.Log.Error(err)
|
||||
}
|
||||
}
|
||||
return gui.switchFocus(g, v, previousView, true)
|
||||
}
|
||||
|
||||
// pass in oldView = nil if you don't want to be able to return to your old view
|
||||
// TODO: move some of this logic into our onFocusLost and onFocus hooks
|
||||
func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View, returning bool) error {
|
||||
// we assume we'll never want to return focus to a popup panel i.e.
|
||||
// we should never stack popup panels
|
||||
if oldView != nil && !gui.isPopupPanel(oldView.Name()) && !returning {
|
||||
gui.pushView(oldView.Name())
|
||||
}
|
||||
|
||||
gui.Log.Info("setting highlight to true for view " + newView.Name())
|
||||
gui.Log.Info("new focused view is " + newView.Name())
|
||||
if _, err := g.SetCurrentView(newView.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g.Cursor = newView.Editable
|
||||
|
||||
if err := gui.renderPanelOptions(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.newLineFocused(newView)
|
||||
}
|
||||
|
||||
// if the cursor down past the last item, move it to the last line
|
||||
// nolint:unparam
|
||||
func (gui *Gui) focusPoint(selectedX int, selectedY int, lineCount int, v *gocui.View) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue