mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Let a mouse binding opt into firing while a popup panel is focused
Mouse clicks on a view other than the focused popup panel are normally swallowed by the ShouldHandleMouseEvent gate, so a registered click handler can't run while a modal is up. Hyperlink clicks already dodge this by being handled in an earlier phase; generalize that to ordinary mouse bindings via a HandleWhenPopupPanelFocused flag, dispatched before the gate. No binding sets it yet, so behavior is unchanged. This is what lets a click on the main view stay live behind a popup (e.g. opening a diff line in the editor while the commit-message panel is in front), the way the wheel already scrolls it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a31755de22
commit
aa4ff00898
|
|
@ -86,6 +86,14 @@ type ViewMouseBinding struct {
|
|||
|
||||
// must be a mouse key
|
||||
Key KeyName
|
||||
|
||||
// If true, this binding is dispatched before ShouldHandleMouseEvent is
|
||||
// consulted, so it fires even when a popup panel is focused and the click
|
||||
// lands on a view other than that panel (which is normally swallowed). This
|
||||
// is the same early phase that hyperlink clicks are handled in; use it for
|
||||
// clicks that must stay live behind a popup, e.g. opening a diff line in the
|
||||
// editor from the main view behind the commit-message panel.
|
||||
HandleWhenPopupPanelFocused bool
|
||||
}
|
||||
|
||||
type ViewMouseBindingOpts struct {
|
||||
|
|
@ -1740,6 +1748,22 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
|
|||
}
|
||||
}
|
||||
|
||||
var mouseOpts ViewMouseBindingOpts
|
||||
if IsMouseKey(ev.Key) {
|
||||
isDoubleClick := g.recordClickInfo(newX, newY, ev.Key.KeyName(), v)
|
||||
mouseOpts = ViewMouseBindingOpts{X: newX, Y: newY, Key: ev.Key.KeyName(), IsDoubleClick: isDoubleClick}
|
||||
|
||||
// Dispatch bindings that opt into firing while a popup panel is focused
|
||||
// before the gate below gets a chance to reject the click.
|
||||
matched, err := g.execMouseKeybindings(v, ev, mouseOpts, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if matched {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if g.ShouldHandleMouseEvent != nil {
|
||||
if !g.ShouldHandleMouseEvent(v, ev.Key.KeyName()) {
|
||||
// Give clients a chance to reject clicks, for example clicks in inactive views
|
||||
|
|
@ -1789,9 +1813,7 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
|
|||
}
|
||||
|
||||
if IsMouseKey(ev.Key) {
|
||||
isDoubleClick := g.recordClickInfo(newX, newY, ev.Key.KeyName(), v)
|
||||
opts := ViewMouseBindingOpts{X: newX, Y: newY, Key: ev.Key.KeyName(), IsDoubleClick: isDoubleClick}
|
||||
matched, err := g.execMouseKeybindings(v, ev, opts)
|
||||
matched, err := g.execMouseKeybindings(v, ev, mouseOpts, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1855,11 +1877,12 @@ func (g *Gui) recordClickInfo(x, y int, key KeyName, v *View) bool {
|
|||
return isDoubleClick
|
||||
}
|
||||
|
||||
func (g *Gui) execMouseKeybindings(view *View, ev *GocuiEvent, opts ViewMouseBindingOpts) (bool, error) {
|
||||
func (g *Gui) execMouseKeybindings(view *View, ev *GocuiEvent, opts ViewMouseBindingOpts, handleWhenPopupPanelFocused bool) (bool, error) {
|
||||
isMatch := func(binding *ViewMouseBinding) bool {
|
||||
return binding.ViewName == view.Name() &&
|
||||
ev.Key.KeyName() == binding.Key &&
|
||||
ev.Key.Mod() == binding.Modifier
|
||||
ev.Key.Mod() == binding.Modifier &&
|
||||
binding.HandleWhenPopupPanelFocused == handleWhenPopupPanelFocused
|
||||
}
|
||||
|
||||
// first pass looks for ones that match the focused view
|
||||
|
|
|
|||
Loading…
Reference in a new issue