terminal: Add cursor support

This commit is contained in:
apio 2023-09-16 13:12:39 +02:00
parent dd3359b09b
commit 945dc6c732
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 47 additions and 6 deletions

View File

@ -6,6 +6,7 @@
#include <os/Process.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <ui/App.h>
#include <unistd.h>
@ -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<void> TerminalWidget::init(char* const* args)
m_child_pid = child;
m_last_cursor_tick = get_time_in_milliseconds();
return {};
}
@ -214,19 +225,45 @@ Result<void> 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;

View File

@ -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<EscapeSequenceParser> m_escape_parser;