diff options
author | Björn Linse <bjorn.linse@gmail.com> | 2019-01-20 13:36:20 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-20 13:36:20 +0100 |
commit | 62254d2cc0d3cbd0e8aea75657ffb82e29ccfdfd (patch) | |
tree | 2a0e717767dfe5cb793edf3feefdaf983a87942e /src/nvim/os/input.c | |
parent | ed6b44e1be2e0a8a1245ec3295040a092d3a05e3 (diff) | |
parent | a2be9c7218d7fb431191cd6146fba61bcd1e193e (diff) | |
download | rneovim-62254d2cc0d3cbd0e8aea75657ffb82e29ccfdfd.tar.gz rneovim-62254d2cc0d3cbd0e8aea75657ffb82e29ccfdfd.tar.bz2 rneovim-62254d2cc0d3cbd0e8aea75657ffb82e29ccfdfd.zip |
Merge pull request #9429 from bfredl/grid_mouse
API/UI: add nvim_input_mouse() including multigrid mouse support
Diffstat (limited to 'src/nvim/os/input.c')
-rw-r--r-- | src/nvim/os/input.c | 109 |
1 files changed, 74 insertions, 35 deletions
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index f62253cbce..5e2c9ecb36 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -236,6 +236,53 @@ size_t input_enqueue(String keys) return rv; } +static uint8_t check_multiclick(int code, int grid, int row, int col) +{ + static int orig_num_clicks = 0; + static int orig_mouse_code = 0; + static int orig_mouse_grid = 0; + static int orig_mouse_col = 0; + static int orig_mouse_row = 0; + static uint64_t orig_mouse_time = 0; // time of previous mouse click + + if (code == KE_LEFTRELEASE || code == KE_RIGHTRELEASE + || code == KE_MIDDLERELEASE) { + return 0; + } + uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns) + + // compute the time elapsed since the previous mouse click and + // convert p_mouse from ms to ns + uint64_t timediff = mouse_time - orig_mouse_time; + uint64_t mouset = (uint64_t)p_mouset * 1000000; + if (code == orig_mouse_code + && timediff < mouset + && orig_num_clicks != 4 + && orig_mouse_grid == grid + && orig_mouse_col == col + && orig_mouse_row == row) { + orig_num_clicks++; + } else { + orig_num_clicks = 1; + } + orig_mouse_code = code; + orig_mouse_grid = grid; + orig_mouse_col = col; + orig_mouse_row = row; + orig_mouse_time = mouse_time; + + uint8_t modifiers = 0; + if (orig_num_clicks == 2) { + modifiers |= MOD_MASK_2CLICK; + } else if (orig_num_clicks == 3) { + modifiers |= MOD_MASK_3CLICK; + } else if (orig_num_clicks == 4) { + modifiers |= MOD_MASK_4CLICK; + } + return modifiers; +} + + // Mouse event handling code(Extract row/col if available and detect multiple // clicks) static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, @@ -274,48 +321,16 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, if (row >= Rows) { row = (int)Rows - 1; } + mouse_grid = 0; mouse_row = row; mouse_col = col; } *ptr += advance; } - static int orig_num_clicks = 0; - if (mouse_code != KE_LEFTRELEASE && mouse_code != KE_RIGHTRELEASE - && mouse_code != KE_MIDDLERELEASE) { - static int orig_mouse_code = 0; - static int orig_mouse_col = 0; - static int orig_mouse_row = 0; - static uint64_t orig_mouse_time = 0; // time of previous mouse click - uint64_t mouse_time = os_hrtime(); // time of current mouse click (ns) - - // compute the time elapsed since the previous mouse click and - // convert p_mouse from ms to ns - uint64_t timediff = mouse_time - orig_mouse_time; - uint64_t mouset = (uint64_t)p_mouset * 1000000; - if (mouse_code == orig_mouse_code - && timediff < mouset - && orig_num_clicks != 4 - && orig_mouse_col == mouse_col - && orig_mouse_row == mouse_row) { - orig_num_clicks++; - } else { - orig_num_clicks = 1; - } - orig_mouse_code = mouse_code; - orig_mouse_col = mouse_col; - orig_mouse_row = mouse_row; - orig_mouse_time = mouse_time; - } + uint8_t modifiers = check_multiclick(mouse_code, mouse_grid, + mouse_row, mouse_col); - uint8_t modifiers = 0; - if (orig_num_clicks == 2) { - modifiers |= MOD_MASK_2CLICK; - } else if (orig_num_clicks == 3) { - modifiers |= MOD_MASK_3CLICK; - } else if (orig_num_clicks == 4) { - modifiers |= MOD_MASK_4CLICK; - } if (modifiers) { if (buf[1] != KS_MODIFIER) { @@ -334,6 +349,30 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, return bufsize; } +size_t input_enqueue_mouse(int code, uint8_t modifier, + int grid, int row, int col) +{ + modifier |= check_multiclick(code, grid, row, col); + uint8_t buf[7], *p = buf; + if (modifier) { + p[0] = K_SPECIAL; + p[1] = KS_MODIFIER; + p[2] = modifier; + p += 3; + } + p[0] = K_SPECIAL; + p[1] = KS_EXTRA; + p[2] = (uint8_t)code; + + mouse_grid = grid; + mouse_row = row; + mouse_col = col; + + size_t written = 3 + (size_t)(p-buf); + rbuffer_write(input_buffer, (char *)buf, written); + return written; +} + /// @return true if the main loop is blocked and waiting for input. bool input_blocking(void) { |