summaryrefslogtreecommitdiffstats
path: root/pkg/gui
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-08-01 21:36:17 +1000
committerJesse Duffield <jessedduffield@gmail.com>2022-08-01 21:38:57 +1000
commitfab2e14b55455be370d8514871d60bc59adfbf30 (patch)
tree081a4a6870b29ab8ba271e877a49dc2f39b56732 /pkg/gui
parent81f80ce968f62facb2c16313cee769b83e61587b (diff)
fix issue caused by opening a menu over a prompt
Diffstat (limited to 'pkg/gui')
-rw-r--r--pkg/gui/context.go40
-rw-r--r--pkg/gui/context/menu_context.go2
-rw-r--r--pkg/gui/gui_common.go2
-rw-r--r--pkg/gui/types/context.go14
4 files changed, 40 insertions, 18 deletions
diff --git a/pkg/gui/context.go b/pkg/gui/context.go
index d2a99d84b..89356d956 100644
--- a/pkg/gui/context.go
+++ b/pkg/gui/context.go
@@ -79,9 +79,10 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
gui.State.ContextManager.Lock()
- // push onto stack
- // if we are switching to a side context, remove all other contexts in the stack
- if c.GetKind() == types.SIDE_CONTEXT {
+ if len(gui.State.ContextManager.ContextStack) == 0 {
+ gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c)
+ } else if c.GetKind() == types.SIDE_CONTEXT {
+ // if we are switching to a side context, remove all other contexts in the stack
for _, stackContext := range gui.State.ContextManager.ContextStack {
if stackContext.GetKey() != c.GetKey() {
if err := gui.deactivateContext(stackContext); err != nil {
@@ -91,12 +92,25 @@ func (gui *Gui) pushContext(c types.Context, opts ...types.OnFocusOpts) error {
}
}
gui.State.ContextManager.ContextStack = []types.Context{c}
- } else if len(gui.State.ContextManager.ContextStack) == 0 || gui.currentContextWithoutLock().GetKey() != c.GetKey() {
- // Do not append if the one at the end is the same context (e.g. opening a menu from a menu)
- // In that case we'll just close the menu entirely when the user hits escape.
+ } else {
+ topContext := gui.currentContextWithoutLock()
+
+ // if we're pushing the same context on, we do nothing.
+ if topContext.GetKey() != c.GetKey() {
+ // if top one is a temporary popup, we remove it. Ideally you'd be able to
+ // escape back to previous temporary popups, but because we're currently reusing
+ // views for this, you might not be able to get back to where you previously were.
+ if topContext.GetKind() == types.TEMPORARY_POPUP {
+ if err := gui.deactivateContext(topContext); err != nil {
+ gui.State.ContextManager.Unlock()
+ return err
+ }
- // TODO: think about other exceptional cases
- gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c)
+ _, gui.State.ContextManager.ContextStack = slices.Pop(gui.State.ContextManager.ContextStack)
+ }
+
+ gui.State.ContextManager.ContextStack = append(gui.State.ContextManager.ContextStack, c)
+ }
}
gui.State.ContextManager.Unlock()
@@ -111,7 +125,7 @@ func (gui *Gui) pushContextWithView(viewName string) error {
return gui.c.PushContext(gui.State.ViewContextMap.Get(viewName))
}
-func (gui *Gui) returnFromContext() error {
+func (gui *Gui) popContext() error {
gui.State.ContextManager.Lock()
if len(gui.State.ContextManager.ContextStack) == 1 {
@@ -120,12 +134,10 @@ func (gui *Gui) returnFromContext() error {
return nil
}
- n := len(gui.State.ContextManager.ContextStack) - 1
-
- currentContext := gui.State.ContextManager.ContextStack[n]
- newContext := gui.State.ContextManager.ContextStack[n-1]
+ var currentContext types.Context
+ currentContext, gui.State.ContextManager.ContextStack = slices.Pop(gui.State.ContextManager.ContextStack)
- gui.State.ContextManager.ContextStack = gui.State.ContextManager.ContextStack[:n]
+ newContext := gui.State.ContextManager.ContextStack[len(gui.State.ContextManager.ContextStack)-1]
gui.g.SetCurrentContext(string(newContext.GetKey()))
diff --git a/pkg/gui/context/menu_context.go b/pkg/gui/context/menu_context.go
index 489f412f0..f71feaeae 100644
--- a/pkg/gui/context/menu_context.go
+++ b/pkg/gui/context/menu_context.go
@@ -36,7 +36,7 @@ func NewMenuContext(
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "menu",
Key: "menu",
- Kind: types.PERSISTENT_POPUP,
+ Kind: types.TEMPORARY_POPUP,
OnGetOptionsMap: getOptionsMap,
Focusable: true,
}), ContextCallbackOpts{
diff --git a/pkg/gui/gui_common.go b/pkg/gui/gui_common.go
index 7d8354bf6..89abe92ba 100644
--- a/pkg/gui/gui_common.go
+++ b/pkg/gui/gui_common.go
@@ -43,7 +43,7 @@ func (self *guiCommon) PushContext(context types.Context, opts ...types.OnFocusO
}
func (self *guiCommon) PopContext() error {
- return self.gui.returnFromContext()
+ return self.gui.popContext()
}
func (self *guiCommon) CurrentContext() types.Context {
diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go
index 253bb62ef..7dec9b9db 100644
--- a/pkg/gui/types/context.go
+++ b/pkg/gui/types/context.go
@@ -8,12 +8,22 @@ import (
type ContextKind int
const (
+ // this is your files, branches, commits, contexts etc. They're all on the left hand side
+ // and you can cycle through them.
SIDE_CONTEXT ContextKind = iota
+ // This is either the left or right 'main' contexts that appear to the right of the side contexts
MAIN_CONTEXT
- TEMPORARY_POPUP
+ // A persistent popup is one that has its own identity e.g. the commit message context.
+ // When you open a popup over it, we'll let you return to it upon pressing escape
PERSISTENT_POPUP
+ // A temporary popup is one that could be used for various things (e.g. a generic menu or confirmation popup).
+ // Because we re-use these contexts, they're temporary in that you can't return to them after you've switched from them
+ // to some other context, because the context you switched to might actually be the same context but rendering different content.
+ // We should really be able to spawn new contexts for menus/prompts so that we can actually return to old ones.
+ TEMPORARY_POPUP
+ // This contains the command log, underneath the main contexts.
EXTRAS_CONTEXT
- // only used by the one global context
+ // only used by the one global context, purely for the sake of defining keybindings globally
GLOBAL_CONTEXT
)