diff --git a/terminal/TerminalWidget.cpp b/terminal/TerminalWidget.cpp index fcbe3687..9709115b 100644 --- a/terminal/TerminalWidget.cpp +++ b/terminal/TerminalWidget.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,14 @@ static constexpr auto BRIGHT_MAGENTA = ui::Color::from_u32(0xffff00ff); static constexpr auto BRIGHT_CYAN = ui::Color::from_u32(0xff00ffff); static constexpr auto BRIGHT_GRAY = ui::Color::from_u32(0xffffffff); +static long get_time_in_milliseconds() +{ + struct timespec ts; + check(clock_gettime(CLOCK_REALTIME, &ts) == 0); + + return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + static void sigchld_handler(int) { wait(NULL); @@ -74,6 +83,8 @@ Result TerminalWidget::init(char* const* args) m_child_pid = child; + m_last_cursor_tick = get_time_in_milliseconds(); + return {}; } @@ -214,19 +225,45 @@ Result TerminalWidget::process() ssize_t nread = read(m_pty, buffer, BUFSIZ); if (nread < 0) { - if (errno == EAGAIN) return {}; - return err(errno); + if (errno == EAGAIN) nread = 0; + else + return err(errno); } query_termios(); + bool should_update_cursor = tick_cursor(); + for (ssize_t i = 0; i < nread; i++) TRY(putchar(buffer[i])); - ui::App::the().main_window()->draw(); + if (should_update_cursor || nread > 0) ui::App::the().main_window()->draw(); return {}; } +bool TerminalWidget::tick_cursor() +{ + if (!m_cursor_enabled) return false; + + long now = get_time_in_milliseconds(); + long diff = now - m_last_cursor_tick; + m_last_cursor_tick = now; + + m_current_cursor_timeout -= (int)diff; + if (m_current_cursor_timeout <= 0) + { + m_current_cursor_timeout = CURSOR_TIMEOUT; + m_cursor_activated = !m_cursor_activated; + + if (m_cursor_activated) draw_cursor(); + else + erase_current_char(); + return true; + } + + return false; +} + void TerminalWidget::query_termios() { tcgetattr(m_pty, &m_settings); @@ -511,7 +548,7 @@ void TerminalWidget::put_code_point(wchar_t c) } // Erase the current cursor. - if (m_cursor_enabled) erase_current_char(); + if (m_cursor_activated) erase_current_char(); bool should_draw_cursor = m_cursor_enabled; diff --git a/terminal/TerminalWidget.h b/terminal/TerminalWidget.h index 0c18bd74..d29cb3ad 100644 --- a/terminal/TerminalWidget.h +++ b/terminal/TerminalWidget.h @@ -34,8 +34,10 @@ class TerminalWidget : public ui::Widget static constexpr int CURSOR_TIMEOUT = 500; int m_current_cursor_timeout = CURSOR_TIMEOUT; - bool m_cursor_activated = true; - bool m_cursor_enabled = false; + bool m_cursor_activated = false; + bool m_cursor_enabled = true; + + long m_last_cursor_tick; int m_x_position { 0 }; int m_y_position { 0 }; @@ -47,6 +49,8 @@ class TerminalWidget : public ui::Widget void query_termios(); + bool tick_cursor(); + Utf8StateDecoder m_decoder; Option m_escape_parser;