mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
LibVT+Kernel: Separate the caret shapes and its steadiness
Currently CursorStyle enum handles both the styles and the steadiness or blinking of the terminal caret, which doubles the amount of its entries. This commit changes CursorStyle to CursorShape and moves the blinking option to a seperate boolean value.
This commit is contained in:
parent
1950e79d48
commit
e2b0f6795f
Notes:
sideshowbarker
2024-07-17 10:02:18 +09:00
Author: https://github.com/cocateh Commit: https://github.com/SerenityOS/serenity/commit/e2b0f6795f Pull-request: https://github.com/SerenityOS/serenity/pull/14012 Reviewed-by: https://github.com/AtkinsSJ ✅ Reviewed-by: https://github.com/BertalanD
6 changed files with 101 additions and 81 deletions
|
@ -358,7 +358,12 @@ void VirtualConsole::emit(u8 const* data, size_t size)
|
|||
TTY::emit(data[i], true);
|
||||
}
|
||||
|
||||
void VirtualConsole::set_cursor_style(VT::CursorStyle)
|
||||
void VirtualConsole::set_cursor_shape(VT::CursorShape)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void VirtualConsole::set_cursor_blinking(bool)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
|
|
@ -101,7 +101,8 @@ private:
|
|||
virtual void terminal_did_resize(u16 columns, u16 rows) override;
|
||||
virtual void terminal_history_changed(int) override;
|
||||
virtual void emit(u8 const*, size_t) override;
|
||||
virtual void set_cursor_style(VT::CursorStyle) override;
|
||||
virtual void set_cursor_shape(VT::CursorShape) override;
|
||||
virtual void set_cursor_blinking(bool) override;
|
||||
|
||||
// ^CharacterDevice
|
||||
virtual StringView class_name() const override { return "VirtualConsole"sv; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue