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;
bool visible;
} cursor;
int pressed_button; // which mouse button is pressed
bool pending_resize; // pending width/height
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);
if (!term->pressed_button) {
// press the button if not already pressed
vterm_mouse_button(term->vt, button, 1, mod);
term->pressed_button = button;
if (button) {
vterm_mouse_button(term->vt, button, pressed, mod);
}
}
@ -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
// program. translate and forward the event
int button;
bool drag = false;
bool pressed = false;
switch (c) {
case K_LEFTDRAG:
drag = true; FALLTHROUGH;
case K_LEFTMOUSE:
pressed = true; FALLTHROUGH;
case K_LEFTRELEASE:
button = 1; break;
case K_MOUSEMOVE:
drag = true; button = 0; break;
button = 0; break;
case K_MIDDLEDRAG:
drag = true; FALLTHROUGH;
case K_MIDDLEMOUSE:
pressed = true; FALLTHROUGH;
case K_MIDDLERELEASE:
button = 2; break;
case K_RIGHTDRAG:
drag = true; FALLTHROUGH;
case K_RIGHTMOUSE:
pressed = true; FALLTHROUGH;
case K_RIGHTRELEASE:
button = 3; break;
case K_MOUSEDOWN:
button = 4; break;
pressed = true; button = 4; break;
case K_MOUSEUP:
button = 5; break;
pressed = true; button = 5; break;
default:
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,
sizeof(term->textbuf));
terminal_send(term, term->textbuf, len);

View File

@ -66,7 +66,7 @@ describe(':terminal mouse', function()
]])
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
feed('<LeftMouse><1,2>')
screen:expect([[
@ -78,6 +78,36 @@ describe(':terminal mouse', function()
"#{1: } |
{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)
it('will forward mouse scroll to the program', function()
@ -94,6 +124,60 @@ describe(':terminal mouse', function()
]])
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()
if helpers.pending_win32(pending) then return end
nvim('command', 'set number')