Reset mouse release state after restarting the screen

When we temporarily disable the screen (e.g. during TermMessage or
RunInteractiveShell), if the mouse is pressed when the screen is still
active and then released when the screen is already stopped, we aren't
able to catch this mouse release event, so we erroneously think that the
mouse is still pressed after the screen is restarted. This results in
wrong behavior due to a mouse press event treated as a mouse move event,
e.g. upon the left button click we see an unexpected text selection.

So need to reset the mouse release state to "released" after restarting
the screen, assuming it is always released when the screen is restarted.
This commit is contained in:
Dmitry Maluka 2022-11-05 11:41:04 +01:00
parent 124fa9e2e7
commit e5093892fd
3 changed files with 30 additions and 3 deletions

View file

@ -325,6 +325,12 @@ func (h *BufPane) PluginCBRune(cb string, r rune) bool {
return b
}
func (h *BufPane) resetMouse() {
for me := range h.mousePressed {
delete(h.mousePressed, me)
}
}
// OpenBuffer opens the given buffer in this pane.
func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
h.Buf.Close()
@ -335,9 +341,7 @@ func (h *BufPane) OpenBuffer(b *buffer.Buffer) {
h.initialRelocate()
// Set mouseReleased to true because we assume the mouse is not being
// pressed when the editor is opened
for me := range h.mousePressed {
delete(h.mousePressed, me)
}
h.resetMouse()
// Set isOverwriteMode to false, because we assume we are in the default
// mode when editor is opened
h.isOverwriteMode = false

View file

@ -161,6 +161,21 @@ func InitTabs(bufs []*buffer.Buffer) {
}
}
}
screen.RestartCallback = func() {
// The mouse could be released after the screen was stopped, so that
// we couldn't catch the mouse release event and would erroneously think
// that it is still pressed. So need to reset the mouse release state
// after the screen is restarted.
for _, t := range Tabs.List {
t.release = true
for _, p := range t.Panes {
if bp, ok := p.(*BufPane); ok {
bp.resetMouse()
}
}
}
}
}
func MainTab() *Tab {

View file

@ -22,6 +22,10 @@ var Screen tcell.Screen
// Events is the channel of tcell events
var Events chan (tcell.Event)
// RestartCallback is called when the screen is restarted after it was
// temporarily shut down
var RestartCallback func()
// The lock is necessary since the screen is polled on a separate thread
var lock sync.Mutex
@ -134,6 +138,10 @@ func TempStart(screenWasNil bool) {
if !screenWasNil {
Init()
Unlock()
if RestartCallback != nil {
RestartCallback()
}
}
}