From 8a4ae3d664a22cfaa3ec05635d26a8d662458c7e Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 30 Sep 2019 22:00:55 +0200 Subject: tui: improve handle_background_color: short-circuit (#11067) * handle_background_color: short-circuit if handled already * Unit tests for handle_background_color * set waiting_for_bg_response to false in tui_terminal_after_startup By then it should have been received. --- src/nvim/tui/input.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/nvim/tui/input.c') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index ed9b410a19..876f00e03e 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -27,6 +27,7 @@ void tinput_init(TermInput *input, Loop *loop) input->loop = loop; input->paste = 0; input->in_fd = 0; + input->waiting_for_bg_response = false; input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE); uv_mutex_init(&input->key_buffer_mutex); uv_cond_init(&input->key_buffer_cond); @@ -443,6 +444,9 @@ static void set_bg_deferred(void **argv) // [1] https://en.wikipedia.org/wiki/Luma_%28video%29 static bool handle_background_color(TermInput *input) { + if (!input->waiting_for_bg_response) { + return false; + } size_t count = 0; size_t component = 0; size_t header_size = 0; @@ -463,6 +467,7 @@ static bool handle_background_color(TermInput *input) } else { return false; } + input->waiting_for_bg_response = false; rbuffer_consumed(input->read_stream.buffer, header_size); RBUFFER_EACH(input->read_stream.buffer, c, i) { count = i + 1; @@ -503,6 +508,12 @@ static bool handle_background_color(TermInput *input) } return true; } +#ifdef UNIT_TESTING +bool ut_handle_background_color(TermInput *input) +{ + return handle_background_color(input); +} +#endif static void tinput_read_cb(Stream *stream, RBuffer *buf, size_t count_, void *data, bool eof) -- cgit From f96d1e6bc416fe0d1d11321234637695ff0e514e Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Thu, 3 Oct 2019 08:04:24 +0200 Subject: tui: fix handling of bg response after suspend (#11145) `tui_terminal_after_startup` gets called right after resuming from suspending (via `Ctrl-z`) already (not delayed as with the startup itself), and would set `waiting_for_bg_response` to false then directly. This results in the terminal response not being processed then anymore, and leaking into Neovim itself. This changes it to try 5 times always, which means that it typically would stop after a few characters of input from the user typically, e.g. with tmux, which does not send a reply. While it might be better to have something based on the time (e.g. only wait for max 1s), this appears to be easier to do. Fixes regression in 8a4ae3d. --- src/nvim/tui/input.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/nvim/tui/input.c') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 876f00e03e..844bc0db40 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -27,7 +27,7 @@ void tinput_init(TermInput *input, Loop *loop) input->loop = loop; input->paste = 0; input->in_fd = 0; - input->waiting_for_bg_response = false; + input->waiting_for_bg_response = 0; input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE); uv_mutex_init(&input->key_buffer_mutex); uv_cond_init(&input->key_buffer_cond); @@ -444,7 +444,7 @@ static void set_bg_deferred(void **argv) // [1] https://en.wikipedia.org/wiki/Luma_%28video%29 static bool handle_background_color(TermInput *input) { - if (!input->waiting_for_bg_response) { + if (input->waiting_for_bg_response <= 0) { return false; } size_t count = 0; @@ -465,9 +465,13 @@ static bool handle_background_color(TermInput *input) header_size = 10; num_components = 4; } else { + input->waiting_for_bg_response--; + if (input->waiting_for_bg_response == 0) { + DLOG("did not get a response for terminal background query"); + } return false; } - input->waiting_for_bg_response = false; + input->waiting_for_bg_response = 0; rbuffer_consumed(input->read_stream.buffer, header_size); RBUFFER_EACH(input->read_stream.buffer, c, i) { count = i + 1; -- cgit From 91f4bb0aeec0b2ae983ea310ada73be5f35f7c5c Mon Sep 17 00:00:00 2001 From: erw7 Date: Mon, 18 Nov 2019 05:58:58 +0900 Subject: TUI: use stdio names instead of magic numbers #11410 --- src/nvim/tui/input.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/tui/input.c') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 844bc0db40..c71378463f 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -26,7 +26,7 @@ void tinput_init(TermInput *input, Loop *loop) { input->loop = loop; input->paste = 0; - input->in_fd = 0; + input->in_fd = STDIN_FILENO; input->waiting_for_bg_response = 0; input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE); uv_mutex_init(&input->key_buffer_mutex); @@ -36,7 +36,7 @@ void tinput_init(TermInput *input, Loop *loop) // echo q | nvim -es // ls *.md | xargs nvim #ifdef WIN32 - if (!os_isatty(0)) { + if (!os_isatty(input->in_fd)) { const HANDLE conin_handle = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, @@ -46,8 +46,8 @@ void tinput_init(TermInput *input, Loop *loop) assert(input->in_fd != -1); } #else - if (!os_isatty(0) && os_isatty(2)) { - input->in_fd = 2; + if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { + input->in_fd = STDERR_FILENO; } #endif input_global_fd_init(input->in_fd); -- cgit From 2c8016c7048051da9afd809b580cf8f2d2c69614 Mon Sep 17 00:00:00 2001 From: erw7 Date: Sat, 16 Nov 2019 13:45:37 +0900 Subject: Add stdin, stdout replacement functions --- src/nvim/tui/input.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/nvim/tui/input.c') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index c71378463f..951cb50c3c 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -14,6 +14,9 @@ #include "nvim/option.h" #include "nvim/os/os.h" #include "nvim/os/input.h" +#ifdef WIN32 +# include "nvim/os/os_win_console.h" +#endif #include "nvim/event/rstream.h" #define KEY_BUFFER_SIZE 0xfff @@ -37,13 +40,7 @@ void tinput_init(TermInput *input, Loop *loop) // ls *.md | xargs nvim #ifdef WIN32 if (!os_isatty(input->in_fd)) { - const HANDLE conin_handle = CreateFile("CONIN$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - (LPSECURITY_ATTRIBUTES)NULL, - OPEN_EXISTING, 0, (HANDLE)NULL); - input->in_fd = _open_osfhandle(conin_handle, _O_RDONLY); - assert(input->in_fd != -1); + input->in_fd = os_get_conin_fd(); } #else if (!os_isatty(input->in_fd) && os_isatty(STDERR_FILENO)) { -- cgit From 9333f86ab7d0e85d9f658bfe455860771de9b997 Mon Sep 17 00:00:00 2001 From: erw7 Date: Fri, 20 Mar 2020 03:31:10 +0900 Subject: TUI: do not use "nvim_get_option" in tui thread Since "nvim_get_option" is executed on the tui thread as a C function instead of msgpack-rpc, it accesses global variables that may change on the main thread. --- src/nvim/tui/input.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) (limited to 'src/nvim/tui/input.c') diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 951cb50c3c..bbee7e4712 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -31,6 +31,10 @@ void tinput_init(TermInput *input, Loop *loop) input->paste = 0; input->in_fd = STDIN_FILENO; input->waiting_for_bg_response = 0; + // The main thread is waiting for the UI thread to call CONTINUE, so it can + // safely access global variables. + input->ttimeout = (bool)p_ttimeout; + input->ttimeoutlen = p_ttm; input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE); uv_mutex_init(&input->key_buffer_mutex); uv_cond_init(&input->key_buffer_cond); @@ -285,21 +289,6 @@ static TermKeyResult tk_getkey(TermKey *tk, TermKeyKey *key, bool force) static void tinput_timer_cb(TimeWatcher *watcher, void *data); -static int get_key_code_timeout(void) -{ - Integer ms = -1; - // Check 'ttimeout' to determine if we should send ESC after 'ttimeoutlen'. - Error err = ERROR_INIT; - if (nvim_get_option(cstr_as_string("ttimeout"), &err).data.boolean) { - Object rv = nvim_get_option(cstr_as_string("ttimeoutlen"), &err); - if (!ERROR_SET(&err)) { - ms = rv.data.integer; - } - } - api_clear_error(&err); - return (int)ms; -} - static void tk_getkeys(TermInput *input, bool force) { TermKeyKey key; @@ -324,12 +313,11 @@ static void tk_getkeys(TermInput *input, bool force) // yet contain all the bytes required. `key` structure indicates what // termkey_getkey_force() would return. - int ms = get_key_code_timeout(); - - if (ms > 0) { + if (input->ttimeout && input->ttimeoutlen >= 0) { // Stop the current timer if already running time_watcher_stop(&input->timer_handle); - time_watcher_start(&input->timer_handle, tinput_timer_cb, (uint32_t)ms, 0); + time_watcher_start(&input->timer_handle, tinput_timer_cb, + (uint64_t)input->ttimeoutlen, 0); } else { tk_getkeys(input, true); } -- cgit