terminal: Add cursor support
This commit is contained in:
parent
dd3359b09b
commit
945dc6c732
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user