aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbarenblat@gmail.com>2021-12-26 14:17:19 -0500
committerGravatar Benjamin Barenblat <bbarenblat@gmail.com>2021-12-26 14:55:35 -0500
commitb819388acc4faa46e296f4e1f173b2cf2be8799f (patch)
tree5d70c7c64f978055ec4e0ecba38bf7cd85af5a7f
parent4e2e8f87f9ee7d22d1d1dfcf581694cc9d912afc (diff)
Hide cursor during redraws
-rw-r--r--goldfishterm/simple.cc18
-rw-r--r--goldfishterm/simple.h10
-rw-r--r--src/ui/terminal/line.cc9
3 files changed, 37 insertions, 0 deletions
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<goldfishterm_internal::StringCapabilityParameter> 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<goldfishterm_internal::StringCapabilityParameter> = {});
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
}