fix(terminal): correctly forward mouse events

This commit is contained in:
zeertzjq 2021-12-27 06:08:16 +08:00
parent 56f3c41f5f
commit e0956f7452
2 changed files with 100 additions and 23 deletions

View File

@ -135,7 +135,6 @@ struct terminal {
int row, col; int row, col;
bool visible; bool visible;
} cursor; } cursor;
int pressed_button; // which mouse button is pressed
bool pending_resize; // pending width/height bool pending_resize; // pending width/height
bool color_set[16]; bool color_set[16];
@ -1209,21 +1208,12 @@ static VTermKey convert_key(int key, VTermModifier *statep)
} }
} }
static void mouse_action(Terminal *term, int button, int row, int col, bool drag, VTermModifier mod) static void mouse_action(Terminal *term, int button, int row, int col, bool pressed,
VTermModifier mod)
{ {
if (term->pressed_button && (term->pressed_button != button || !drag)) {
// release the previous button
vterm_mouse_button(term->vt, term->pressed_button, 0, mod);
term->pressed_button = 0;
}
// move the mouse
vterm_mouse_move(term->vt, row, col, mod); vterm_mouse_move(term->vt, row, col, mod);
if (button) {
if (!term->pressed_button) { vterm_mouse_button(term->vt, button, pressed, mod);
// press the button if not already pressed
vterm_mouse_button(term->vt, button, 1, mod);
term->pressed_button = button;
} }
} }
@ -1242,32 +1232,35 @@ static bool send_mouse_event(Terminal *term, int c)
// event in the terminal window and mouse events was enabled by the // event in the terminal window and mouse events was enabled by the
// program. translate and forward the event // program. translate and forward the event
int button; int button;
bool drag = false; bool pressed = false;
switch (c) { switch (c) {
case K_LEFTDRAG: case K_LEFTDRAG:
drag = true; FALLTHROUGH;
case K_LEFTMOUSE: case K_LEFTMOUSE:
pressed = true; FALLTHROUGH;
case K_LEFTRELEASE:
button = 1; break; button = 1; break;
case K_MOUSEMOVE: case K_MOUSEMOVE:
drag = true; button = 0; break; button = 0; break;
case K_MIDDLEDRAG: case K_MIDDLEDRAG:
drag = true; FALLTHROUGH;
case K_MIDDLEMOUSE: case K_MIDDLEMOUSE:
pressed = true; FALLTHROUGH;
case K_MIDDLERELEASE:
button = 2; break; button = 2; break;
case K_RIGHTDRAG: case K_RIGHTDRAG:
drag = true; FALLTHROUGH;
case K_RIGHTMOUSE: case K_RIGHTMOUSE:
pressed = true; FALLTHROUGH;
case K_RIGHTRELEASE:
button = 3; break; button = 3; break;
case K_MOUSEDOWN: case K_MOUSEDOWN:
button = 4; break; pressed = true; button = 4; break;
case K_MOUSEUP: case K_MOUSEUP:
button = 5; break; pressed = true; button = 5; break;
default: default:
return false; return false;
} }
mouse_action(term, button, row, col - offset, drag, 0); mouse_action(term, button, row, col - offset, pressed, 0);
size_t len = vterm_output_read(term->vt, term->textbuf, size_t len = vterm_output_read(term->vt, term->textbuf,
sizeof(term->textbuf)); sizeof(term->textbuf));
terminal_send(term, term->textbuf, len); terminal_send(term, term->textbuf, len);

View File

@ -66,7 +66,7 @@ describe(':terminal mouse', function()
]]) ]])
end) end)
it('will forward mouse clicks to the program', function() it('will forward mouse press, drag and release to the program', function()
if helpers.pending_win32(pending) then return end if helpers.pending_win32(pending) then return end
feed('<LeftMouse><1,2>') feed('<LeftMouse><1,2>')
screen:expect([[ screen:expect([[
@ -78,6 +78,36 @@ describe(':terminal mouse', function()
"#{1: } | "#{1: } |
{3:-- TERMINAL --} | {3:-- TERMINAL --} |
]]) ]])
feed('<LeftDrag><2,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
@##{1: } |
{3:-- TERMINAL --} |
]])
feed('<LeftDrag><3,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
@$#{1: } |
{3:-- TERMINAL --} |
]])
feed('<LeftRelease><3,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
#$#{1: } |
{3:-- TERMINAL --} |
]])
end) end)
it('will forward mouse scroll to the program', function() it('will forward mouse scroll to the program', function()
@ -94,6 +124,60 @@ describe(':terminal mouse', function()
]]) ]])
end) end)
it('dragging and scrolling do not interfere with each other', function()
if helpers.pending_win32(pending) then return end
feed('<LeftMouse><1,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
"#{1: } |
{3:-- TERMINAL --} |
]])
feed('<ScrollWheelUp><1,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
`"#{1: } |
{3:-- TERMINAL --} |
]])
feed('<LeftDrag><2,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
@##{1: } |
{3:-- TERMINAL --} |
]])
feed('<ScrollWheelUp><2,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
`##{1: } |
{3:-- TERMINAL --} |
]])
feed('<LeftRelease><2,2>')
screen:expect([[
line27 |
line28 |
line29 |
line30 |
mouse enabled |
###{1: } |
{3:-- TERMINAL --} |
]])
end)
it('will forward mouse clicks to the program with the correct even if set nu', function() it('will forward mouse clicks to the program with the correct even if set nu', function()
if helpers.pending_win32(pending) then return end if helpers.pending_win32(pending) then return end
nvim('command', 'set number') nvim('command', 'set number')