From e220bedc7976ffc561c47f53d0453f93bca1d6c1 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 29 Jun 2019 13:28:09 +1000 Subject: [PATCH] support actual mouse support and focusing the main view --- Gopkg.lock | 4 +- pkg/gui/containers_panel.go | 8 +- pkg/gui/images_panel.go | 8 +- pkg/gui/keybindings.go | 108 +++++++++++++++--- pkg/gui/layout.go | 4 + pkg/gui/main_panel.go | 44 ++++++- pkg/gui/options_menu_panel.go | 22 ++++ pkg/gui/services_panel.go | 8 +- pkg/gui/status_panel.go | 10 +- pkg/gui/view_helpers.go | 20 +--- pkg/gui/volumes_panel.go | 8 +- pkg/i18n/english.go | 4 + vendor/github.com/jesseduffield/gocui/gui.go | 37 ++++-- vendor/github.com/jesseduffield/gocui/view.go | 3 + 14 files changed, 216 insertions(+), 72 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 5d2b3e83..dbcf1ecd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -131,11 +131,11 @@ [[projects]] branch = "master" - digest = "1:697738bf0065442016622def39cf22041c6f40df99d5315d845b0d528f96377f" + digest = "1:f38f5b4c589578819e4316ece29b7e3516907f2662c68ab92442c5fcc6b41781" name = "github.com/jesseduffield/gocui" packages = ["."] pruneopts = "NUT" - revision = "32197598edc52af42d76b8cba78ed788074b4647" + revision = "117e4fb79d29e3908cb7a7bed5e991a321fde7fd" [[projects]] branch = "master" diff --git a/pkg/gui/containers_panel.go b/pkg/gui/containers_panel.go index 36d489db..671c2fdd 100644 --- a/pkg/gui/containers_panel.go +++ b/pkg/gui/containers_panel.go @@ -42,10 +42,6 @@ func (gui *Gui) handleContainersClick(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleContainerSelect(g *gocui.Gui, v *gocui.View) error { - if _, err := gui.g.SetCurrentView(v.Name()); err != nil { - return err - } - container, err := gui.getSelectedContainer() if err != nil { if err != gui.Errors.ErrNoContainers { @@ -314,7 +310,7 @@ func (gui *Gui) refreshContainersAndServices() error { } func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } @@ -325,7 +321,7 @@ func (gui *Gui) handleContainersNextLine(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleContainersPrevLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } diff --git a/pkg/gui/images_panel.go b/pkg/gui/images_panel.go index c1e8d317..91ba7f8a 100644 --- a/pkg/gui/images_panel.go +++ b/pkg/gui/images_panel.go @@ -41,10 +41,6 @@ func (gui *Gui) handleImagesClick(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleImageSelect(g *gocui.Gui, v *gocui.View) error { - if _, err := gui.g.SetCurrentView(v.Name()); err != nil { - return err - } - Image, err := gui.getSelectedImage(g) if err != nil { if err != gui.Errors.ErrNoImages { @@ -151,7 +147,7 @@ func (gui *Gui) refreshStateImages() error { } func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } @@ -162,7 +158,7 @@ func (gui *Gui) handleImagesNextLine(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleImagesPrevLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 6dbc3cad..4753582c 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -153,6 +153,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleStatusNextContext, Description: gui.Tr.NextContext, }, + { + ViewName: "status", + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleStatusClick, + Description: gui.Tr.NextContext, + }, { ViewName: "status", Key: 'm', @@ -366,12 +373,66 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handlePruneVolumes, Description: gui.Tr.PruneVolumes, }, + { + ViewName: "main", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleExitMain, + Description: gui.Tr.Return, + }, + { + ViewName: "main", + Key: gocui.KeyArrowLeft, + Modifier: gocui.ModNone, + Handler: gui.scrollLeftMain, + }, + { + ViewName: "main", + Key: gocui.KeyArrowRight, + Modifier: gocui.ModNone, + Handler: gui.scrollRightMain, + }, + { + ViewName: "main", + Key: 'h', + Modifier: gocui.ModNone, + Handler: gui.scrollLeftMain, + }, + { + ViewName: "main", + Key: 'l', + Modifier: gocui.ModNone, + Handler: gui.scrollRightMain, + }, + { + ViewName: "", + Key: 'J', + Modifier: gocui.ModNone, + Handler: gui.scrollDownMain, + }, + { + ViewName: "", + Key: 'K', + Modifier: gocui.ModNone, + Handler: gui.scrollUpMain, + }, + { + ViewName: "", + Key: 'H', + Modifier: gocui.ModNone, + Handler: gui.scrollLeftMain, + }, + { + ViewName: "", + Key: 'L', + Modifier: gocui.ModNone, + Handler: gui.scrollRightMain, + }, } // TODO: add more views here for _, viewName := range []string{"status", "services", "containers", "images", "volumes", "menu"} { bindings = append(bindings, []*Binding{ - {ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView}, {ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView}, {ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView}, {ViewName: viewName, Key: 'h', Modifier: gocui.ModNone, Handler: gui.previousView}, @@ -379,30 +440,41 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { }...) } - listPanelMap := map[string]struct { - prevLine func(*gocui.Gui, *gocui.View) error - nextLine func(*gocui.Gui, *gocui.View) error - focus func(*gocui.Gui, *gocui.View) error + panelMap := map[string]struct { + onKeyUpPress func(*gocui.Gui, *gocui.View) error + onKeyDownPress func(*gocui.Gui, *gocui.View) error + onClick func(*gocui.Gui, *gocui.View) error }{ - "menu": {prevLine: gui.handleMenuPrevLine, nextLine: gui.handleMenuNextLine, focus: gui.handleMenuClick}, - "services": {prevLine: gui.handleServicesPrevLine, nextLine: gui.handleServicesNextLine, focus: gui.handleServicesClick}, - "containers": {prevLine: gui.handleContainersPrevLine, nextLine: gui.handleContainersNextLine, focus: gui.handleContainersClick}, - "images": {prevLine: gui.handleImagesPrevLine, nextLine: gui.handleImagesNextLine, focus: gui.handleImagesClick}, - "volumes": {prevLine: gui.handleVolumesPrevLine, nextLine: gui.handleVolumesNextLine, focus: gui.handleVolumesClick}, + "menu": {onKeyUpPress: gui.handleMenuPrevLine, onKeyDownPress: gui.handleMenuNextLine, onClick: gui.handleMenuClick}, + "services": {onKeyUpPress: gui.handleServicesPrevLine, onKeyDownPress: gui.handleServicesNextLine, onClick: gui.handleServicesClick}, + "containers": {onKeyUpPress: gui.handleContainersPrevLine, onKeyDownPress: gui.handleContainersNextLine, onClick: gui.handleContainersClick}, + "images": {onKeyUpPress: gui.handleImagesPrevLine, onKeyDownPress: gui.handleImagesNextLine, onClick: gui.handleImagesClick}, + "volumes": {onKeyUpPress: gui.handleVolumesPrevLine, onKeyDownPress: gui.handleVolumesNextLine, onClick: gui.handleVolumesClick}, + "main": {onKeyUpPress: gui.scrollUpMain, onKeyDownPress: gui.scrollDownMain, onClick: gui.handleMainClick}, } - for viewName, functions := range listPanelMap { + for viewName, functions := range panelMap { bindings = append(bindings, []*Binding{ - {ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.prevLine}, - {ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.prevLine}, - {ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: functions.prevLine}, - {ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.nextLine}, - {ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.nextLine}, - {ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: functions.nextLine}, - {ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: functions.focus}, + {ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: functions.onKeyUpPress}, + {ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: functions.onKeyUpPress}, + {ViewName: viewName, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: functions.onKeyUpPress}, + {ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: functions.onKeyDownPress}, + {ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: functions.onKeyDownPress}, + {ViewName: viewName, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: functions.onKeyDownPress}, + {ViewName: viewName, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: functions.onClick}, }...) } + for _, viewName := range []string{"status", "services", "containers", "images", "volumes"} { + bindings = append(bindings, &Binding{ + ViewName: viewName, + Key: gocui.KeyEnter, + Modifier: gocui.ModNone, + Handler: gui.handleEnterMain, + Description: gui.Tr.FocusMain, + }) + } + return bindings } diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 57c968e0..2d21dae5 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -41,6 +41,10 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error { return nil } + if !gui.isPopupPanel(newView.Name()) { + v.ParentView = nil + } + // refocusing because in responsive mode (when the window is very short) we want to ensure that after the view size changes we can still see the last selected item if err := gui.focusPointInView(v); err != nil { return err diff --git a/pkg/gui/main_panel.go b/pkg/gui/main_panel.go index 2037ff05..5dc15763 100644 --- a/pkg/gui/main_panel.go +++ b/pkg/gui/main_panel.go @@ -7,7 +7,7 @@ import ( ) func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("main") + mainView := gui.getMainView() mainView.Autoscroll = false ox, oy := mainView.Origin() newOy := int(math.Max(0, float64(oy-gui.Config.UserConfig.Gui.ScrollHeight))) @@ -15,7 +15,7 @@ func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("main") + mainView := gui.getMainView() ox, oy := mainView.Origin() y := oy if !gui.Config.UserConfig.Gui.ScrollPastBottom { @@ -27,6 +27,21 @@ func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error { return mainView.SetOrigin(ox, oy+gui.Config.UserConfig.Gui.ScrollHeight) } +func (gui *Gui) scrollLeftMain(g *gocui.Gui, v *gocui.View) error { + mainView := gui.getMainView() + ox, oy := mainView.Origin() + newOx := int(math.Max(0, float64(ox-gui.Config.UserConfig.Gui.ScrollHeight))) + + return mainView.SetOrigin(newOx, oy) +} + +func (gui *Gui) scrollRightMain(g *gocui.Gui, v *gocui.View) error { + mainView := gui.getMainView() + ox, oy := mainView.Origin() + + return mainView.SetOrigin(ox+gui.Config.UserConfig.Gui.ScrollHeight, oy) +} + func (gui *Gui) autoScrollMain(g *gocui.Gui, v *gocui.View) error { gui.getMainView().Autoscroll = true return nil @@ -37,6 +52,11 @@ func (gui *Gui) onMainTabClick(tabIndex int) error { viewName := gui.currentViewName() + mainView := gui.getMainView() + if viewName == "main" && mainView.ParentView != nil { + viewName = mainView.ParentView.Name() + } + switch viewName { case "services": gui.State.Panels.Services.ContextIndex = tabIndex @@ -57,3 +77,23 @@ func (gui *Gui) onMainTabClick(tabIndex int) error { return nil } + +func (gui *Gui) handleEnterMain(g *gocui.Gui, v *gocui.View) error { + mainView := gui.getMainView() + mainView.ParentView = v + + return gui.switchFocus(gui.g, v, mainView) +} + +func (gui *Gui) handleExitMain(g *gocui.Gui, v *gocui.View) error { + v.ParentView = nil + return gui.returnFocus(gui.g, v) +} + +func (gui *Gui) handleMainClick(g *gocui.Gui, v *gocui.View) error { + currentView := gui.g.CurrentView() + + v.ParentView = currentView + + return gui.switchFocus(gui.g, currentView, v) +} diff --git a/pkg/gui/options_menu_panel.go b/pkg/gui/options_menu_panel.go index 2f204ab1..7f071076 100644 --- a/pkg/gui/options_menu_panel.go +++ b/pkg/gui/options_menu_panel.go @@ -26,6 +26,28 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding { } } + // check if we have any keybindings from our parent view to add + if v.ParentView != nil { + L: + for _, binding := range bindings { + if binding.GetKey() != "" && binding.Description != "" { + if binding.ViewName == v.ParentView.Name() { + // if we haven't got a conflict we will display the binding + for _, ownBinding := range bindingsPanel { + if ownBinding.GetKey() == binding.GetKey() { + continue L + } + } + bindingsPanel = append(bindingsPanel, binding) + } + } + } + } + + // } else if v.ParentView != nil && binding.ViewName == v.ParentView.Name() { + // // only add this if we don't have our own matching binding + // bindingsPanel = append(bindingsPanel, binding) + // append dummy element to have a separator between // panel and global keybindings bindingsPanel = append(bindingsPanel, &Binding{}) diff --git a/pkg/gui/services_panel.go b/pkg/gui/services_panel.go index 09d90326..44bd7d65 100644 --- a/pkg/gui/services_panel.go +++ b/pkg/gui/services_panel.go @@ -39,10 +39,6 @@ func (gui *Gui) handleServicesClick(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleServiceSelect(g *gocui.Gui, v *gocui.View) error { - if _, err := gui.g.SetCurrentView(v.Name()); err != nil { - return err - } - service, err := gui.getSelectedService() if err != nil { return nil @@ -133,7 +129,7 @@ func (gui *Gui) renderServiceLogs(service *commands.Service) error { } func (gui *Gui) handleServicesNextLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } @@ -144,7 +140,7 @@ func (gui *Gui) handleServicesNextLine(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleServicesPrevLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index a959c90d..e4d215a5 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -39,7 +39,7 @@ func (gui *Gui) refreshStatus() error { return nil } -func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { +func (gui *Gui) handleStatusClick(g *gocui.Gui, v *gocui.View) error { if gui.popupPanelFocused() { return nil } @@ -48,6 +48,14 @@ func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { return err } + return gui.handleStatusSelect(g, v) +} + +func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error { + if gui.popupPanelFocused() { + return nil + } + key := gui.getStatusContexts()[gui.State.Panels.Status.ContextIndex] if !gui.shouldRefresh(key) { return nil diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index f866b309..9e9ccb66 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -301,22 +301,6 @@ func (gui *Gui) resizePopupPanel(g *gocui.Gui, v *gocui.View) error { return err } -// generalFocusLine takes a lineNumber to focus, and a bottomLine to ensure we can see -func (gui *Gui) generalFocusLine(lineNumber int, bottomLine int, v *gocui.View) error { - _, height := v.Size() - overScroll := bottomLine - height + 1 - if overScroll < 0 { - overScroll = 0 - } - if err := v.SetOrigin(0, overScroll); err != nil { - return err - } - if err := v.SetCursor(0, lineNumber-overScroll); err != nil { - return err - } - return nil -} - func (gui *Gui) changeSelectedLine(line *int, total int, up bool) { if up { if *line == -1 || *line == 0 { @@ -389,6 +373,10 @@ func (gui *Gui) handleClick(v *gocui.View, itemCount int, selectedLine *int, han return nil } + if _, err := gui.g.SetCurrentView(v.Name()); err != nil { + return err + } + _, cy := v.Cursor() _, oy := v.Origin() diff --git a/pkg/gui/volumes_panel.go b/pkg/gui/volumes_panel.go index 63a11de4..d3bef6a7 100644 --- a/pkg/gui/volumes_panel.go +++ b/pkg/gui/volumes_panel.go @@ -38,10 +38,6 @@ func (gui *Gui) handleVolumesClick(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleVolumeSelect(g *gocui.Gui, v *gocui.View) error { - if _, err := gui.g.SetCurrentView(v.Name()); err != nil { - return err - } - volume, err := gui.getSelectedVolume() if err != nil { if err != gui.Errors.ErrNoVolumes { @@ -144,7 +140,7 @@ func (gui *Gui) refreshVolumes() error { } func (gui *Gui) handleVolumesNextLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } @@ -155,7 +151,7 @@ func (gui *Gui) handleVolumesNextLine(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleVolumesPrevLine(g *gocui.Gui, v *gocui.View) error { - if gui.popupPanelFocused() { + if gui.popupPanelFocused() || gui.g.CurrentView() != v { return nil } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 15b55fc9..1d42c3e5 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -31,6 +31,8 @@ type TranslationSet struct { RemoveWithVolumes string MustForceToRemoveContainer string Confirm string + Return string + FocusMain string StopContainer string RestartingStatus string StoppingStatus string @@ -94,6 +96,8 @@ func englishSet() TranslationSet { Donate: "Donate", Confirm: "Confirm", + Return: "return", + FocusMain: "focus main panel", Navigate: "navigate", Execute: "execute", Close: "close", diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index fe7dc403..5751fc56 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -394,6 +394,7 @@ func (g *Gui) SetManager(managers ...Manager) { g.currentView = nil g.views = nil g.keybindings = nil + g.tabClickBindings = nil go func() { g.tbEvents <- termbox.Event{Type: termbox.EventResize} }() } @@ -509,14 +510,7 @@ func (g *Gui) flush() error { continue } if v.Frame { - var fgColor, bgColor Attribute - if g.Highlight && v == g.currentView { - fgColor = g.SelFgColor - bgColor = g.SelBgColor - } else { - fgColor = g.FgColor - bgColor = g.BgColor - } + fgColor, bgColor := g.viewColors(v) if err := g.drawFrameEdges(v, fgColor, bgColor); err != nil { return err @@ -543,6 +537,13 @@ func (g *Gui) flush() error { return nil } +func (g *Gui) viewColors(v *View) (Attribute, Attribute) { + if g.Highlight && v == g.currentView { + return g.SelFgColor, g.SelBgColor + } + return g.FgColor, g.BgColor +} + // drawFrameEdges draws the horizontal and vertical edges of a view. func (g *Gui) drawFrameEdges(v *View, fgColor, bgColor Attribute) error { runeH, runeV := '─', '│' @@ -668,10 +669,20 @@ func (g *Gui) drawTitle(v *View, fgColor, bgColor Attribute) error { } else if x > v.x1-2 || x >= g.maxX { break } + currentFgColor := fgColor currentBgColor := bgColor + // if you are the current view and you have multiple tabs, de-highlight the non-selected tabs + if v == g.currentView && len(v.Tabs) > 0 { + currentFgColor = v.FgColor + currentBgColor = v.BgColor + } + if i >= currentTabStart && i <= currentTabEnd { - currentFgColor = v.SelFgColor - AttrBold + currentFgColor = v.SelFgColor + if v != g.currentView { + currentFgColor -= AttrBold + } currentBgColor = v.SelBgColor } if err := g.SetRune(x, v.y0, ch, currentFgColor, currentBgColor); err != nil { @@ -787,6 +798,8 @@ func (g *Gui) onKey(ev *termbox.Event) error { // and event. The value of matched is true if there is a match and no errors. func (g *Gui) execKeybindings(v *View, ev *termbox.Event) (matched bool, err error) { var globalKb *keybinding + var matchingParentViewKb *keybinding + for _, kb := range g.keybindings { if kb.handler == nil { continue @@ -797,10 +810,16 @@ func (g *Gui) execKeybindings(v *View, ev *termbox.Event) (matched bool, err err if kb.matchView(v) { return g.execKeybinding(v, kb) } + if kb.matchView(v.ParentView) { + matchingParentViewKb = kb + } if kb.viewName == "" && ((v != nil && !v.Editable) || (kb.ch == 0 && kb.key != KeyCtrlU && kb.key != KeyCtrlA && kb.key != KeyCtrlE)) { globalKb = kb } } + if matchingParentViewKb != nil { + return g.execKeybinding(v.ParentView, matchingParentViewKb) + } if globalKb != nil { return g.execKeybinding(v, globalKb) } diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 6b4f0bb1..03793057 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -100,6 +100,9 @@ type View struct { // IgnoreCarriageReturns tells us whether to ignore '\r' characters IgnoreCarriageReturns bool + + // ParentView is the view which catches events bubbled up from the given view if there's no matching handler + ParentView *View } type viewLine struct {