Skip to content

Commit f1e52af

Browse files
committed
fix: mouse movement
1 parent d1c6cd9 commit f1e52af

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

pkg/keys/mouse.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,11 @@ func (m Mouse) x10Bytes() []byte {
117117
func (m Mouse) sgrBytes() []byte {
118118
flags := m.mouseFlags()
119119

120-
// SGR doesn't use bitsRelease; instead the suffix encodes
121-
// press vs release.
122-
if !m.Down {
120+
// For press events, SGR uses the 'm' suffix to indicate
121+
// release, so bitsRelease should be cleared from the flags.
122+
// For motion events, bitsRelease in the flags byte indicates
123+
// no button is held and must be preserved.
124+
if m.Type == MousePress && !m.Down {
123125
flags &^= bitsRelease
124126
}
125127

@@ -152,8 +154,14 @@ func (m Mouse) Bytes(mode emu.ModeFlag) ([]byte, bool) {
152154
if m.Type == MouseMotion {
153155
return nil, false
154156
}
155-
case emu.ModeMouseMotion, emu.ModeMouseMany:
156-
// Report everything.
157+
case emu.ModeMouseMotion:
158+
// Mode 1002: report press, release, and motion with
159+
// button held (drag). Filter out no-button motion.
160+
if m.Type == MouseMotion && !m.Down {
161+
return nil, false
162+
}
163+
case emu.ModeMouseMany:
164+
// Mode 1003: report everything.
157165
default:
158166
return nil, false
159167
}

pkg/keys/mouse_test.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ func TestSGRMouse(t *testing.T) {
6363
testSGRMouseInput(t, "\x1b[<64;10;10M")
6464
// Wheel down
6565
testSGRMouseInput(t, "\x1b[<65;10;10M")
66-
// Motion with left button
66+
// Motion with left button (drag)
6767
testSGRMouseInput(t, "\x1b[<32;15;25M")
68+
// Motion without button
69+
testSGRMouseInput(t, "\x1b[<35;15;25M")
6870
// Ctrl+left click
6971
testSGRMouseInput(t, "\x1b[<16;5;5M")
7072
// Alt+left click
@@ -75,7 +77,8 @@ func TestSGRMouse(t *testing.T) {
7577

7678
func TestMouseFiltering(t *testing.T) {
7779
press := Mouse{Type: MousePress, Button: MouseLeft, Down: true}
78-
motion := Mouse{Type: MouseMotion, Down: true}
80+
drag := Mouse{Type: MouseMotion, Button: MouseLeft, Down: true}
81+
motion := Mouse{Type: MouseMotion, Down: false}
7982

8083
// No mouse mode → not reported.
8184
_, ok := press.Bytes(0)
@@ -84,16 +87,28 @@ func TestMouseFiltering(t *testing.T) {
8487
// X10 only reports presses.
8588
_, ok = press.Bytes(emu.ModeMouseX10)
8689
assert.True(t, ok)
87-
_, ok = motion.Bytes(emu.ModeMouseX10)
90+
_, ok = drag.Bytes(emu.ModeMouseX10)
8891
assert.False(t, ok)
8992

90-
// Button mode drops pure motion.
93+
// Button mode drops all motion.
9194
_, ok = press.Bytes(emu.ModeMouseButton)
9295
assert.True(t, ok)
96+
_, ok = drag.Bytes(emu.ModeMouseButton)
97+
assert.False(t, ok)
9398
_, ok = motion.Bytes(emu.ModeMouseButton)
9499
assert.False(t, ok)
95100

101+
// Motion mode (1002) reports drag but not no-button motion.
102+
_, ok = press.Bytes(emu.ModeMouseMotion)
103+
assert.True(t, ok)
104+
_, ok = drag.Bytes(emu.ModeMouseMotion)
105+
assert.True(t, ok)
106+
_, ok = motion.Bytes(emu.ModeMouseMotion)
107+
assert.False(t, ok)
108+
96109
// Many mode reports everything.
110+
_, ok = drag.Bytes(emu.ModeMouseMany)
111+
assert.True(t, ok)
97112
_, ok = motion.Bytes(emu.ModeMouseMany)
98113
assert.True(t, ok)
99114
}

0 commit comments

Comments
 (0)