summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-02-23 20:02:40 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-17 19:13:40 +1100
commit952a4f3f2388da4ab88005b02f264aca0172afe7 (patch)
treec26e7f2e67a9723f4da70ff635be3abddf876b9d /pkg
parent46e9946854086f170ec01f12daf075e197e420f7 (diff)
prevent interrupting confirmation panel
Diffstat (limited to 'pkg')
-rw-r--r--pkg/gui/confirmation_panel.go21
-rw-r--r--pkg/gui/gui.go11
2 files changed, 25 insertions, 7 deletions
diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go
index 0a61c50b5..a7050aba0 100644
--- a/pkg/gui/confirmation_panel.go
+++ b/pkg/gui/confirmation_panel.go
@@ -44,6 +44,10 @@ func (gui *Gui) wrappedPromptConfirmationFunction(handlersManageFocus bool, func
}
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
if !gui.Views.Confirmation.Visible {
return nil
@@ -164,13 +168,14 @@ func runeForMask(mask bool) rune {
}
func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
- // if a popup panel already appears we must ignore this current one. This is
- // not great but it prevents lost state. The proper solution is to have a stack of
- // 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.
- // One important popup we don't want to interrupt is the credentials popup
- // or a process might get stuck waiting on user input.
- if gui.currentContext().GetKey() == context.CONFIRMATION_CONTEXT_KEY {
+ gui.Mutexes.PopupMutex.Lock()
+ defer gui.Mutexes.PopupMutex.Unlock()
+
+ // we don't allow interruptions of non-loader popups in case we get stuck somehow
+ // e.g. a credentials popup never gets its required user input so a process hangs
+ // forever.
+ // 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")
return nil
}
@@ -208,6 +213,8 @@ func (gui *Gui) createPopupPanel(opts types.CreatePopupPanelOpts) error {
return err
}
+ gui.State.CurrentPopupOpts = &opts
+
return gui.c.PushContext(gui.State.Contexts.Confirmation)
}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 061c6e7ec..6b371699a 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -197,6 +197,8 @@ type GuiRepoState struct {
savedCommitMessage string
ScreenMode WindowMaximisation
+
+ CurrentPopupOpts *types.CreatePopupPanelOpts
}
type Controllers struct {
@@ -280,6 +282,7 @@ type guiMutexes struct {
LocalCommitsMutex *sync.Mutex
LineByLinePanelMutex *sync.Mutex
SubprocessMutex *sync.Mutex
+ PopupMutex *sync.Mutex
}
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 {
gui.State = state
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()
return
}
@@ -441,6 +451,7 @@ func NewGui(
LocalCommitsMutex: &sync.Mutex{},
LineByLinePanelMutex: &sync.Mutex{},
SubprocessMutex: &sync.Mutex{},
+ PopupMutex: &sync.Mutex{},
},
InitialDir: initialDir,
}