From 05cdacc8d4089a08cf19873951fbdcac8f579749 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Mon, 31 Jan 2022 16:25:42 -0600 Subject: [PATCH] Prevent queued-up flash() calls from blocking input Closes #8610. --- src/reader.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/reader.cpp b/src/reader.cpp index 62c3af304..23e10dba5 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -628,6 +629,9 @@ class reader_data_t : public std::enable_shared_from_this { /// Whether this is the first prompt. bool first_prompt{true}; + /// The time when the last flash() completed + std::chrono::time_point last_flash; + /// The representation of the current screen contents. screen_t screen; @@ -1879,6 +1883,15 @@ void reader_data_t::select_completion_in_direction(selection_motion_t dir) { /// Flash the screen. This function changes the color of the current line momentarily. void reader_data_t::flash() { + // Multiple flashes may be enqueued by keypress repeat events and can pile up to cause a + // significant delay in processing future input while all the flash() calls complete, as we + // effectively sleep for 100ms each go. See #8610. + auto now = std::chrono::steady_clock::now(); + if ((now - last_flash) < std::chrono::milliseconds{50}) { + last_flash = now; + return; + } + struct timespec pollint; editable_line_t *el = &command_line; layout_data_t data = make_layout_data(); @@ -1901,6 +1914,10 @@ void reader_data_t::flash() { data.colors = std::move(saved_colors); this->rendered_layout = std::move(data); paint_layout(L"unflash"); + + // Save the time we stopped flashing as the time of the most recent flash. We can't just + // increment the old `now` value because the sleep is non-deterministic. + last_flash = std::chrono::steady_clock::now(); } maybe_t reader_data_t::get_selection() const {