diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/os/input.c | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-usermarks.tar.gz rneovim-usermarks.tar.bz2 rneovim-usermarks.zip |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/os/input.c')
-rw-r--r-- | src/nvim/os/input.c | 113 |
1 files changed, 64 insertions, 49 deletions
diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index bfe6d59dc6..759b3cf83c 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -3,25 +3,33 @@ #include <assert.h> #include <stdbool.h> +#include <stdint.h> +#include <stdio.h> #include <string.h> #include <uv.h> #include "nvim/api/private/defs.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" +#include "nvim/buffer_defs.h" #include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/event/rstream.h" +#include "nvim/event/stream.h" #include "nvim/getchar.h" +#include "nvim/gettext.h" +#include "nvim/globals.h" #include "nvim/keycodes.h" +#include "nvim/log.h" +#include "nvim/macros.h" #include "nvim/main.h" -#include "nvim/mbyte.h" -#include "nvim/memory.h" #include "nvim/msgpack_rpc/channel.h" +#include "nvim/option_defs.h" #include "nvim/os/input.h" +#include "nvim/os/time.h" #include "nvim/profile.h" -#include "nvim/screen.h" +#include "nvim/rbuffer.h" #include "nvim/state.h" -#include "nvim/ui.h" #include "nvim/vim.h" #define READ_BUFFER_SIZE 0xfff @@ -36,8 +44,9 @@ typedef enum { static Stream read_stream = { .closed = true }; // Input before UI starts. static RBuffer *input_buffer = NULL; static bool input_eof = false; -static int global_fd = -1; static bool blocking = false; +static int cursorhold_time = 0; ///< time waiting for CursorHold event +static int cursorhold_tb_change_cnt = 0; ///< tb_change_cnt when waiting started #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/input.c.generated.h" @@ -48,25 +57,14 @@ void input_init(void) input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN); } -void input_global_fd_init(int fd) -{ - global_fd = fd; -} - -/// Global TTY (or pipe for "-es") input stream, before UI starts. -int input_global_fd(void) -{ - return global_fd; -} - -void input_start(int fd) +void input_start(void) { if (!read_stream.closed) { return; } - input_global_fd_init(fd); - rstream_init_fd(&main_loop, &read_stream, fd, READ_BUFFER_SIZE); + used_stdin = true; + rstream_init_fd(&main_loop, &read_stream, STDIN_FILENO, READ_BUFFER_SIZE); rstream_start(&read_stream, input_read_cb, NULL); } @@ -97,13 +95,25 @@ static void create_cursorhold_event(bool events_enabled) multiqueue_put(main_loop.events, cursorhold_event, 0); } +static void restart_cursorhold_wait(int tb_change_cnt) +{ + cursorhold_time = 0; + cursorhold_tb_change_cnt = tb_change_cnt; +} + /// Low level input function /// /// wait until either the input buffer is non-empty or, if `events` is not NULL /// until `events` is non-empty. int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *events) { + // This check is needed so that feeding typeahead from RPC can prevent CursorHold. + if (tb_change_cnt != cursorhold_tb_change_cnt) { + restart_cursorhold_wait(tb_change_cnt); + } + if (maxlen && rbuffer_size(input_buffer)) { + restart_cursorhold_wait(tb_change_cnt); return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); } @@ -118,18 +128,22 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *e return 0; } } else { - if ((result = inbuf_poll((int)p_ut, events)) == kInputNone) { + uint64_t wait_start = os_hrtime(); + cursorhold_time = MIN(cursorhold_time, (int)p_ut); + if ((result = inbuf_poll((int)p_ut - cursorhold_time, events)) == kInputNone) { if (read_stream.closed && silent_mode) { // Drained eventloop & initial input; exit silent/batch-mode (-es/-Es). read_error_exit(); } - + restart_cursorhold_wait(tb_change_cnt); if (trigger_cursorhold() && !typebuf_changed(tb_change_cnt)) { create_cursorhold_event(events == main_loop.events); } else { before_blocking(); result = inbuf_poll(-1, events); } + } else { + cursorhold_time += (int)((os_hrtime() - wait_start) / 1000000); } } @@ -141,6 +155,7 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt, MultiQueue *e } if (maxlen && rbuffer_size(input_buffer)) { + restart_cursorhold_wait(tb_change_cnt); // Safe to convert rbuffer_read to int, it will never overflow since we use // relatively small buffers. return (int)rbuffer_read(input_buffer, (char *)buf, (size_t)maxlen); @@ -239,7 +254,8 @@ size_t input_enqueue(String keys) uint8_t buf[19] = { 0 }; // Do not simplify the keys here. Simplification will be done later. unsigned int new_size - = trans_special((const uint8_t **)&ptr, (size_t)(end - ptr), buf, FSK_KEYCODE, true, NULL); + = trans_special((const char **)&ptr, (size_t)(end - ptr), (char *)buf, FSK_KEYCODE, true, + NULL); if (new_size) { new_size = handle_mouse_event(&ptr, buf, new_size); @@ -287,36 +303,35 @@ static uint8_t check_multiclick(int code, int grid, int row, int col) 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 - || code == KE_MOUSEDOWN - || code == KE_MOUSEUP - || code == KE_MOUSELEFT - || code == KE_MOUSERIGHT) { + if ((code >= KE_MOUSEDOWN && code <= KE_MOUSERIGHT) || code == KE_MOUSEMOVE) { 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; + + // For click events the number of clicks is updated. + if (code == KE_LEFTMOUSE || code == KE_RIGHTMOUSE || code == KE_MIDDLEMOUSE) { + 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_time = mouse_time; } - orig_mouse_code = code; + // For drag and release events the number of clicks is kept. + 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) { @@ -347,7 +362,8 @@ static unsigned int handle_mouse_event(char **ptr, uint8_t *buf, unsigned int bu if (type != KS_EXTRA || !((mouse_code >= KE_LEFTMOUSE && mouse_code <= KE_RIGHTRELEASE) - || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT))) { + || (mouse_code >= KE_MOUSEDOWN && mouse_code <= KE_MOUSERIGHT) + || mouse_code == KE_MOUSEMOVE)) { return bufsize; } @@ -450,9 +466,8 @@ static InbufPollResult inbuf_poll(int ms, MultiQueue *events) if (input_ready(events)) { return kInputAvail; - } else { - return input_eof ? kInputEof : kInputNone; } + return input_eof ? kInputEof : kInputNone; } void input_done(void) |