From b819388acc4faa46e296f4e1f173b2cf2be8799f Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sun, 26 Dec 2021 14:17:19 -0500 Subject: Hide cursor during redraws --- goldfishterm/simple.cc | 18 ++++++++++++++++++ goldfishterm/simple.h | 10 ++++++++++ src/ui/terminal/line.cc | 9 +++++++++ 3 files changed, 37 insertions(+) diff --git a/goldfishterm/simple.cc b/goldfishterm/simple.cc index 9c4c9a9..88ceef0 100644 --- a/goldfishterm/simple.cc +++ b/goldfishterm/simple.cc @@ -23,6 +23,7 @@ #include "goldfishterm/internal/emit.h" #include "goldfishterm/terminfo.h" +#include "third_party/abseil/absl/strings/str_cat.h" #include "third_party/abseil/absl/strings/string_view.h" namespace goldfishterm { @@ -48,6 +49,19 @@ absl::string_view TerminalNameFromEnvironment() { return name; } +StringCapability CursorVisibilityCapability(CursorVisibility v) { + switch (v) { + case CursorVisibility::kInvisible: + return StringCapability::kCursorInvisible; + case CursorVisibility::kNormal: + return StringCapability::kCursorNormal; + case CursorVisibility::kVeryVisible: + return StringCapability::kCursorVisible; + default: + throw std::invalid_argument(absl::StrCat("invalid CursorVisibility ", v)); + } +} + } // namespace SimpleTerminalOutput::SimpleTerminalOutput() @@ -59,6 +73,10 @@ SimpleTerminalOutput::SimpleTerminalOutput(const termios& tty) baud_ = cfgetospeed(&tty); } +void SimpleTerminalOutput::SetCursorVisibility(CursorVisibility v) { + return Emit(CursorVisibilityCapability(v)); +} + void SimpleTerminalOutput::Emit( StringCapability cap, std::vector parameters) { diff --git a/goldfishterm/simple.h b/goldfishterm/simple.h index 3f5cc9f..48a7789 100644 --- a/goldfishterm/simple.h +++ b/goldfishterm/simple.h @@ -26,6 +26,13 @@ namespace goldfishterm { +// The type of cursor in use. +enum class CursorVisibility { + kInvisible, + kNormal, + kVeryVisible, +}; + // Looks up escape sequences for the terminal described in the TERM environment // variable, and allows sending those escape sequences to standard output. // @@ -58,6 +65,9 @@ class SimpleTerminalOutput final { // Moves the cursor down one line. void CursorDown() { Emit(StringCapability::kCursorDown); } + // Sets the cursor visibility. + void SetCursorVisibility(CursorVisibility); + private: void Emit(StringCapability, std::vector = {}); diff --git a/src/ui/terminal/line.cc b/src/ui/terminal/line.cc index 0ae2d30..0848b22 100644 --- a/src/ui/terminal/line.cc +++ b/src/ui/terminal/line.cc @@ -39,6 +39,8 @@ namespace ec { namespace { +using ::goldfishterm::CursorVisibility; + constexpr absl::string_view kBeginningOfLine = "\r"; int CheckedCall(const char* what_arg, int r) { @@ -94,6 +96,7 @@ TerminalLine::~TerminalLine() noexcept { pthread_cancel(sigwinch_watcher_.native_handle()); sigwinch_watcher_.join(); + tty_->SetCursorVisibility(CursorVisibility::kNormal); ExitRawMode(); // Move the cursor to the start of the next line. @@ -107,6 +110,8 @@ void TerminalLine::SetLine(std::string text) { void TerminalLine::Refresh() { absl::MutexLock lock(&mu_); + tty_->SetCursorVisibility(CursorVisibility::kInvisible); + tty_->Flush(); tty_->BeginningOfLine(); if (line_.size() < columns_) { // We can fit the whole line and the cursor on the screen at once. @@ -117,6 +122,7 @@ void TerminalLine::Refresh() { tty_->Write(absl::string_view(&*line_.end() - to_display, to_display)); } tty_->ClearToEndOfLine(); + tty_->SetCursorVisibility(CursorVisibility::kNormal); tty_->Flush(); } @@ -145,11 +151,14 @@ void TerminalLine::Beep() { void TerminalLine::PrintLine(absl::string_view message) { { absl::MutexLock lock(&mu_); + tty_->SetCursorVisibility(CursorVisibility::kInvisible); + tty_->Flush(); tty_->BeginningOfLine(); tty_->CursorDown(); tty_->Write(message); tty_->BeginningOfLine(); tty_->CursorDown(); + tty_->SetCursorVisibility(CursorVisibility::kNormal); } Refresh(); // includes a flush } -- cgit v1.2.3