From 2d95064ff61e19941c516d3d819c09e57c5076f0 Mon Sep 17 00:00:00 2001 From: Dmitry Maluka Date: Thu, 1 Dec 2022 22:53:38 +0100 Subject: [PATCH] Make a pane active whenever any mouse button is pressed on it Since now bufpane handles mouse move and release events generically and separately from mouse press events, that creates a mess when we dispatch a mouse press event to an inactive pane without making it active. For example: 1. Click the right button on an inactive pane. It remains inactive. 2. Then click the left button on it. It becomes active, and an unexpected text selection appears. The reason is that the release event for the first click was dispatched to a wrong pane - the (then) active one, so the (then) inactive pane didn't get the release event and treats the second click not as a mouse press but as a mouse move. The simplest way to fix it is to avoid this scenario entirely, i.e. always activate the pane when clicking any mouse button on it, not just the left button. For mouse wheel motion events we keep the existing behavior: the pane gets the event but doesn't become active. Mouse wheel motion events are not affected by the described issue, as they have no paired "release" events. --- internal/action/tab.go | 51 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/internal/action/tab.go b/internal/action/tab.go index 0967df3a..4227547f 100644 --- a/internal/action/tab.go +++ b/internal/action/tab.go @@ -226,34 +226,40 @@ func NewTabFromPane(x, y, width, height int, pane Pane) *Tab { // HandleEvent takes a tcell event and usually dispatches it to the current // active pane. However if the event is a resize or a mouse event where the user // is interacting with the UI (resizing splits) then the event is consumed here -// If the event is a mouse event in a pane, that pane will become active and get -// the event +// If the event is a mouse press event in a pane, that pane will become active +// and get the event func (t *Tab) HandleEvent(event tcell.Event) { switch e := event.(type) { case *tcell.EventMouse: mx, my := e.Position() - switch e.Buttons() { - case tcell.Button1: + btn := e.Buttons() + switch { + case btn & ^(tcell.WheelUp|tcell.WheelDown|tcell.WheelLeft|tcell.WheelRight) != tcell.ButtonNone: + // button press or drag wasReleased := t.release t.release = false - if t.resizing != nil { - var size int - if t.resizing.Kind == views.STVert { - size = mx - t.resizing.X - } else { - size = my - t.resizing.Y + 1 + + if btn == tcell.Button1 { + if t.resizing != nil { + var size int + if t.resizing.Kind == views.STVert { + size = mx - t.resizing.X + } else { + size = my - t.resizing.Y + 1 + } + t.resizing.ResizeSplit(size) + t.Resize() + return + } + if wasReleased { + t.resizing = t.GetMouseSplitNode(buffer.Loc{mx, my}) + if t.resizing != nil { + return + } } - t.resizing.ResizeSplit(size) - t.Resize() - return } if wasReleased { - t.resizing = t.GetMouseSplitNode(buffer.Loc{mx, my}) - if t.resizing != nil { - return - } - for i, p := range t.Panes { v := p.GetView() inpane := mx >= v.X && mx < v.X+v.Width && my >= v.Y && my < v.Y+v.Height @@ -263,10 +269,15 @@ func (t *Tab) HandleEvent(event tcell.Event) { } } } - case tcell.ButtonNone: - t.resizing = nil + case btn == tcell.ButtonNone: + // button release t.release = true + if t.resizing != nil { + t.resizing = nil + return + } default: + // wheel move for _, p := range t.Panes { v := p.GetView() inpane := mx >= v.X && mx < v.X+v.Width && my >= v.Y && my < v.Y+v.Height