1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-10 22:42:00 +02:00

prevent interrupting confirmation panel

This commit is contained in:
Jesse Duffield
2022-02-23 20:02:40 +11:00
parent 46e9946854
commit 952a4f3f23
2 changed files with 25 additions and 7 deletions

View File

@@ -44,6 +44,10 @@ func (gui *Gui) wrappedPromptConfirmationFunction(handlersManageFocus bool, func
} }
func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error { func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error {
gui.Mutexes.PopupMutex.Lock()
gui.State.CurrentPopupOpts = nil
gui.Mutexes.PopupMutex.Unlock()
// we've already closed it so we can just return // we've already closed it so we can just return
if !gui.Views.Confirmation.Visible { if !gui.Views.Confirmation.Visible {
return nil return nil
@@ -164,13 +168,14 @@ func runeForMask(mask bool) rune {
} }
func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error { func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
// if a popup panel already appears we must ignore this current one. This is gui.Mutexes.PopupMutex.Lock()
// not great but it prevents lost state. The proper solution is to have a stack of defer gui.Mutexes.PopupMutex.Unlock()
// popups. We could have a queue of types.CreatePopupPanelOpts so that if you
// close a popup and there's another one in the queue we show that. // we don't allow interruptions of non-loader popups in case we get stuck somehow
// One important popup we don't want to interrupt is the credentials popup // e.g. a credentials popup never gets its required user input so a process hangs
// or a process might get stuck waiting on user input. // forever.
if gui.currentContext().GetKey() == context.CONFIRMATION_CONTEXT_KEY { // The proper solution is to have a queue of popup options
if gui.State.CurrentPopupOpts != nil && !gui.State.CurrentPopupOpts.HasLoader {
gui.Log.Error("ignoring create popup panel because a popup panel is already open") gui.Log.Error("ignoring create popup panel because a popup panel is already open")
return nil return nil
} }
@@ -208,6 +213,8 @@ func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
return err return err
} }
gui.State.CurrentPopupOpts = &opts
return gui.c.PushContext(gui.State.Contexts.Confirmation) return gui.c.PushContext(gui.State.Contexts.Confirmation)
} }

View File

@@ -197,6 +197,8 @@ type GuiRepoState struct {
savedCommitMessage string savedCommitMessage string
ScreenMode WindowMaximisation ScreenMode WindowMaximisation
CurrentPopupOpts *types.CreatePopupPanelOpts
} }
type Controllers struct { type Controllers struct {
@@ -280,6 +282,7 @@ type guiMutexes struct {
LocalCommitsMutex *sync.Mutex LocalCommitsMutex *sync.Mutex
LineByLinePanelMutex *sync.Mutex LineByLinePanelMutex *sync.Mutex
SubprocessMutex *sync.Mutex SubprocessMutex *sync.Mutex
PopupMutex *sync.Mutex
} }
func (gui *Gui) onNewRepo(filterPath string, reuseState bool) error { func (gui *Gui) onNewRepo(filterPath string, reuseState bool) error {
@@ -322,6 +325,13 @@ func (gui *Gui) resetState(filterPath string, reuseState bool) {
if state := gui.RepoStateMap[Repo(currentDir)]; state != nil { if state := gui.RepoStateMap[Repo(currentDir)]; state != nil {
gui.State = state gui.State = state
gui.State.ViewsSetup = false gui.State.ViewsSetup = false
// setting this to nil so we don't get stuck based on a popup that was
// previously opened
gui.Mutexes.PopupMutex.Lock()
gui.State.CurrentPopupOpts = nil
gui.Mutexes.PopupMutex.Unlock()
gui.syncViewContexts() gui.syncViewContexts()
return return
} }
@@ -441,6 +451,7 @@ func NewGui(
LocalCommitsMutex: &sync.Mutex{}, LocalCommitsMutex: &sync.Mutex{},
LineByLinePanelMutex: &sync.Mutex{}, LineByLinePanelMutex: &sync.Mutex{},
SubprocessMutex: &sync.Mutex{}, SubprocessMutex: &sync.Mutex{},
PopupMutex: &sync.Mutex{},
}, },
InitialDir: initialDir, InitialDir: initialDir,
} }