summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibVT
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibVT')
-rw-r--r--Userland/Libraries/LibVT/Terminal.cpp59
-rw-r--r--Userland/Libraries/LibVT/Terminal.h19
-rw-r--r--Userland/Libraries/LibVT/TerminalWidget.cpp83
-rw-r--r--Userland/Libraries/LibVT/TerminalWidget.h11
4 files changed, 93 insertions, 79 deletions
diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp
index 5eaacb682e..26381c6191 100644
--- a/Userland/Libraries/LibVT/Terminal.cpp
+++ b/Userland/Libraries/LibVT/Terminal.cpp
@@ -61,32 +61,6 @@ void Terminal::alter_ansi_mode(bool should_set, Parameters params)
void Terminal::alter_private_mode(bool should_set, Parameters params)
{
- auto steady_cursor_to_blinking = [](CursorStyle style) {
- switch (style) {
- case SteadyBar:
- return BlinkingBar;
- case SteadyBlock:
- return BlinkingBlock;
- case SteadyUnderline:
- return BlinkingUnderline;
- default:
- return style;
- }
- };
-
- auto blinking_cursor_to_steady = [](CursorStyle style) {
- switch (style) {
- case BlinkingBar:
- return SteadyBar;
- case BlinkingBlock:
- return SteadyBlock;
- case BlinkingUnderline:
- return SteadyUnderline;
- default:
- return style;
- }
- };
-
for (auto mode : params) {
switch (mode) {
case 1:
@@ -105,23 +79,22 @@ void Terminal::alter_private_mode(bool should_set, Parameters params)
case 12:
if (should_set) {
// Start blinking cursor
- m_cursor_style = steady_cursor_to_blinking(m_cursor_style);
+ m_client.set_cursor_blinking(true);
} else {
// Stop blinking cursor
- m_cursor_style = blinking_cursor_to_steady(m_cursor_style);
+ m_client.set_cursor_blinking(false);
}
- m_client.set_cursor_style(m_cursor_style);
break;
case 25:
if (should_set) {
// Show cursor
- m_cursor_style = m_saved_cursor_style;
- m_client.set_cursor_style(m_cursor_style);
+ m_cursor_shape = m_saved_cursor_shape;
+ m_client.set_cursor_shape(m_cursor_shape);
} else {
// Hide cursor
- m_saved_cursor_style = m_cursor_style;
- m_cursor_style = None;
- m_client.set_cursor_style(None);
+ m_saved_cursor_shape = m_cursor_shape;
+ m_cursor_shape = VT::CursorShape::None;
+ m_client.set_cursor_shape(VT::CursorShape::None);
}
break;
case 1047:
@@ -674,22 +647,28 @@ void Terminal::DECSCUSR(Parameters params)
style = params[0];
switch (style) {
case 1:
- m_client.set_cursor_style(BlinkingBlock);
+ m_client.set_cursor_shape(VT::CursorShape::Block);
+ m_client.set_cursor_blinking(true);
break;
case 2:
- m_client.set_cursor_style(SteadyBlock);
+ m_client.set_cursor_shape(VT::CursorShape::Block);
+ m_client.set_cursor_blinking(false);
break;
case 3:
- m_client.set_cursor_style(BlinkingUnderline);
+ m_client.set_cursor_shape(VT::CursorShape::Underline);
+ m_client.set_cursor_blinking(true);
break;
case 4:
- m_client.set_cursor_style(SteadyUnderline);
+ m_client.set_cursor_shape(VT::CursorShape::Underline);
+ m_client.set_cursor_blinking(false);
break;
case 5:
- m_client.set_cursor_style(BlinkingBar);
+ m_client.set_cursor_shape(VT::CursorShape::Bar);
+ m_client.set_cursor_blinking(true);
break;
case 6:
- m_client.set_cursor_style(SteadyBar);
+ m_client.set_cursor_shape(VT::CursorShape::Bar);
+ m_client.set_cursor_blinking(false);
break;
default:
dbgln("Unknown cursor style {}", style);
diff --git a/Userland/Libraries/LibVT/Terminal.h b/Userland/Libraries/LibVT/Terminal.h
index b3760b0106..65794d54e1 100644
--- a/Userland/Libraries/LibVT/Terminal.h
+++ b/Userland/Libraries/LibVT/Terminal.h
@@ -29,14 +29,11 @@ class VirtualConsole;
namespace VT {
-enum CursorStyle {
+enum class CursorShape {
None,
- BlinkingBlock,
- SteadyBlock,
- BlinkingUnderline,
- SteadyUnderline,
- BlinkingBar,
- SteadyBar
+ Block,
+ Underline,
+ Bar,
};
enum CursorKeysMode {
@@ -54,7 +51,8 @@ public:
virtual void terminal_did_resize(u16 columns, u16 rows) = 0;
virtual void terminal_history_changed(int delta) = 0;
virtual void emit(u8 const*, size_t) = 0;
- virtual void set_cursor_style(CursorStyle) = 0;
+ virtual void set_cursor_shape(CursorShape) = 0;
+ virtual void set_cursor_blinking(bool) = 0;
};
class Terminal : public EscapeSequenceExecutor {
@@ -428,8 +426,9 @@ protected:
bool m_swallow_current { false };
bool m_stomp { false };
- CursorStyle m_cursor_style { BlinkingBlock };
- CursorStyle m_saved_cursor_style { BlinkingBlock };
+ CursorShape m_cursor_shape { VT::CursorShape::Block };
+ CursorShape m_saved_cursor_shape { VT::CursorShape::Block };
+ bool m_cursor_is_blinking_set { true };
bool m_needs_bracketed_paste { false };
diff --git a/Userland/Libraries/LibVT/TerminalWidget.cpp b/Userland/Libraries/LibVT/TerminalWidget.cpp
index 02fda4cb79..93faffd022 100644
--- a/Userland/Libraries/LibVT/TerminalWidget.cpp
+++ b/Userland/Libraries/LibVT/TerminalWidget.cpp
@@ -170,7 +170,9 @@ void TerminalWidget::set_logical_focus(bool focus)
m_has_logical_focus = focus;
if (!m_has_logical_focus) {
m_cursor_blink_timer->stop();
- } else {
+ m_cursor_blink_state = true;
+ } else if (m_cursor_is_blinking_set) {
+ m_cursor_blink_timer->stop();
m_cursor_blink_state = true;
m_cursor_blink_timer->start();
}
@@ -208,9 +210,11 @@ void TerminalWidget::keydown_event(GUI::KeyEvent& event)
}
// Reset timer so cursor doesn't blink while typing.
- m_cursor_blink_timer->stop();
- m_cursor_blink_state = true;
- m_cursor_blink_timer->start();
+ if (m_cursor_is_blinking_set) {
+ m_cursor_blink_timer->stop();
+ m_cursor_blink_state = true;
+ m_cursor_blink_timer->start();
+ }
if (event.key() == KeyCode::Key_PageUp && event.modifiers() == Mod_Shift) {
m_scrollbar->decrease_slider_by(m_terminal.rows());
@@ -315,7 +319,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
for (size_t column = 0; column < line.length(); ++column) {
bool should_reverse_fill_for_cursor_or_selection = m_cursor_blink_state
- && (m_cursor_style == VT::CursorStyle::SteadyBlock || m_cursor_style == VT::CursorStyle::BlinkingBlock)
+ && m_cursor_shape == VT::CursorShape::Block
&& m_has_logical_focus
&& visual_row == row_with_cursor
&& column == m_terminal.cursor_column();
@@ -389,7 +393,7 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
for (size_t column = 0; column < line.length(); ++column) {
auto attribute = line.attribute_at(column);
bool should_reverse_fill_for_cursor_or_selection = m_cursor_blink_state
- && (m_cursor_style == VT::CursorStyle::SteadyBlock || m_cursor_style == VT::CursorStyle::BlinkingBlock)
+ && m_cursor_shape == VT::CursorShape::Block
&& m_has_logical_focus
&& visual_row == row_with_cursor
&& column == m_terminal.cursor_column();
@@ -421,18 +425,18 @@ void TerminalWidget::paint_event(GUI::PaintEvent& event)
if (m_terminal.cursor_row() >= (m_terminal.rows() - rows_from_history))
return;
- if (m_has_logical_focus && (m_cursor_style == VT::CursorStyle::BlinkingBlock || m_cursor_style == VT::CursorStyle::SteadyBlock))
+ if (m_has_logical_focus && m_cursor_shape == VT::CursorShape::Block)
return; // This has already been handled by inverting the cell colors
auto cursor_color = terminal_color_to_rgb(cursor_line.attribute_at(m_terminal.cursor_column()).effective_foreground_color());
auto cell_rect = glyph_rect(row_with_cursor, m_terminal.cursor_column()).inflated(0, m_line_spacing);
- if (m_cursor_style == VT::CursorStyle::BlinkingUnderline || m_cursor_style == VT::CursorStyle::SteadyUnderline) {
+ if (m_cursor_shape == VT::CursorShape::Underline) {
auto x1 = cell_rect.bottom_left().x();
auto x2 = cell_rect.bottom_right().x();
auto y = cell_rect.bottom_left().y();
for (auto x = x1; x <= x2; ++x)
painter.set_pixel({ x, y }, cursor_color);
- } else if (m_cursor_style == VT::CursorStyle::BlinkingBar || m_cursor_style == VT::CursorStyle::SteadyBar) {
+ } else if (m_cursor_shape == VT::CursorShape::Bar) {
auto x = cell_rect.bottom_left().x();
auto y1 = cell_rect.top_left().y();
auto y2 = cell_rect.bottom_left().y();
@@ -1037,32 +1041,28 @@ void TerminalWidget::emit(u8 const* data, size_t size)
}
}
-void TerminalWidget::set_cursor_style(CursorStyle style)
+void TerminalWidget::set_cursor_blinking(bool blinking)
{
- switch (style) {
- case None:
- m_cursor_blink_timer->stop();
- m_cursor_blink_state = false;
- break;
- case SteadyBlock:
- case SteadyUnderline:
- case SteadyBar:
+ if (blinking) {
m_cursor_blink_timer->stop();
m_cursor_blink_state = true;
- break;
- case BlinkingBlock:
- case BlinkingUnderline:
- case BlinkingBar:
+ m_cursor_blink_timer->start();
+ m_cursor_is_blinking_set = true;
+ } else {
+ m_cursor_blink_timer->stop();
m_cursor_blink_state = true;
- m_cursor_blink_timer->restart();
- break;
- default:
- dbgln("Cursor style not implemented");
+ m_cursor_is_blinking_set = false;
}
- m_cursor_style = style;
invalidate_cursor();
}
+void TerminalWidget::set_cursor_shape(CursorShape shape)
+{
+ m_cursor_shape = shape;
+ invalidate_cursor();
+ update();
+}
+
void TerminalWidget::context_menu_event(GUI::ContextMenuEvent& event)
{
if (m_hovered_href_id.is_null()) {
@@ -1301,4 +1301,33 @@ void TerminalWidget::set_auto_scroll_direction(AutoScrollDirection direction)
m_auto_scroll_timer->set_active(direction != AutoScrollDirection::None);
}
+Optional<VT::CursorShape> TerminalWidget::parse_cursor_shape(StringView cursor_shape_string)
+{
+ if (cursor_shape_string == "Block"sv)
+ return VT::CursorShape::Block;
+
+ if (cursor_shape_string == "Underline"sv)
+ return VT::CursorShape::Underline;
+
+ if (cursor_shape_string == "Bar"sv)
+ return VT::CursorShape::Bar;
+
+ return {};
+}
+
+String TerminalWidget::stringify_cursor_shape(VT::CursorShape cursor_shape)
+{
+ switch (cursor_shape) {
+ case VT::CursorShape::Block:
+ return "Block";
+ case VT::CursorShape::Underline:
+ return "Underline";
+ case VT::CursorShape::Bar:
+ return "Bar";
+ case VT::CursorShape::None:
+ return "None";
+ }
+ VERIFY_NOT_REACHED();
+}
+
}
diff --git a/Userland/Libraries/LibVT/TerminalWidget.h b/Userland/Libraries/LibVT/TerminalWidget.h
index 99f3a85226..63de6617f6 100644
--- a/Userland/Libraries/LibVT/TerminalWidget.h
+++ b/Userland/Libraries/LibVT/TerminalWidget.h
@@ -96,6 +96,13 @@ public:
void set_color_scheme(StringView);
+ VT::CursorShape cursor_shape() { return m_cursor_shape; }
+ virtual void set_cursor_blinking(bool) override;
+ virtual void set_cursor_shape(CursorShape) override;
+
+ static Optional<VT::CursorShape> parse_cursor_shape(StringView);
+ static String stringify_cursor_shape(VT::CursorShape);
+
private:
TerminalWidget(int ptm_fd, bool automatic_size_policy);
@@ -124,7 +131,6 @@ private:
virtual void terminal_did_resize(u16 columns, u16 rows) override;
virtual void terminal_history_changed(int delta) override;
virtual void emit(u8 const*, size_t) override;
- virtual void set_cursor_style(CursorStyle) override;
// ^GUI::Clipboard::ClipboardClient
virtual void clipboard_content_did_change(String const&) override { update_paste_action(); }
@@ -196,7 +202,8 @@ private:
bool m_cursor_blink_state { true };
bool m_automatic_size_policy { false };
- VT::CursorStyle m_cursor_style { BlinkingBlock };
+ VT::CursorShape m_cursor_shape { VT::CursorShape::Block };
+ bool m_cursor_is_blinking_set { true };
enum class AutoScrollDirection {
None,