From 4edd8e8c5e4c6da7f4e5525050a8cdd01e2b0035 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 27 Feb 2023 08:16:48 -0500 Subject: [PATCH] LibGUI: Ensure the "End" key sets the cursor to the visual line end We are currently setting the physical mouse position to the visual cursor content location. In a line containing only a multi-code point emoji, this would set the cursor to column 1 rather than however many code points there are. --- Userland/Libraries/LibGUI/EditingEngine.cpp | 8 +++----- Userland/Libraries/LibGUI/TextEditor.cpp | 13 +++++++++++++ Userland/Libraries/LibGUI/TextEditor.h | 1 + 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibGUI/EditingEngine.cpp b/Userland/Libraries/LibGUI/EditingEngine.cpp index 0ff7952a03d..984690e3ab1 100644 --- a/Userland/Libraries/LibGUI/EditingEngine.cpp +++ b/Userland/Libraries/LibGUI/EditingEngine.cpp @@ -271,12 +271,10 @@ void EditingEngine::move_to_line_beginning() void EditingEngine::move_to_line_end() { - if (m_editor->is_wrapping_enabled()) { - auto end_position = m_editor->cursor_content_rect().location().translated(m_editor->width(), 0); - m_editor->set_cursor(m_editor->text_position_at_content_position(end_position)); - } else { + if (m_editor->is_wrapping_enabled()) + m_editor->set_cursor_to_end_of_visual_line(); + else move_to_logical_line_end(); - } } void EditingEngine::move_to_logical_line_end() diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 9428a62191b..e3619f01c6e 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -1418,6 +1418,19 @@ void TextEditor::set_cursor_to_text_position(Gfx::IntPoint position) set_cursor({ visual_position.line(), physical_column }); } +void TextEditor::set_cursor_to_end_of_visual_line() +{ + for_each_visual_line(m_cursor.line(), [&](auto const&, auto& view, size_t start_of_visual_line, auto) { + if (m_cursor.column() < start_of_visual_line) + return IterationDecision::Continue; + if ((m_cursor.column() - start_of_visual_line) >= view.length()) + return IterationDecision::Continue; + + set_cursor(m_cursor.line(), start_of_visual_line + view.length()); + return IterationDecision::Break; + }); +} + void TextEditor::focusin_event(FocusEvent& event) { if (event.source() == FocusSource::Keyboard) diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h index 4892794f291..1146a0c1f78 100644 --- a/Userland/Libraries/LibGUI/TextEditor.h +++ b/Userland/Libraries/LibGUI/TextEditor.h @@ -191,6 +191,7 @@ public: void set_cursor(size_t line, size_t column); virtual void set_cursor(TextPosition const&); void set_cursor_to_text_position(Gfx::IntPoint); + void set_cursor_to_end_of_visual_line(); Syntax::Highlighter* syntax_highlighter(); Syntax::Highlighter const* syntax_highlighter() const;