Просмотр исходного кода

LibGUI: Don't update cursor, if visual data out-of-date

This fixes https://github.com/SerenityOS/serenity/issues/2498
A nullptr dereference was caused by the visual data beeing out of sync
with the line data, due to a deferred recompute.
Kevin Meyer 5 лет назад
Родитель
Сommit
17aa917073
2 измененных файлов с 9 добавлено и 2 удалено
  1. 6 1
      Libraries/LibGUI/TextEditor.cpp
  2. 3 1
      Libraries/LibGUI/TextEditor.h

+ 6 - 1
Libraries/LibGUI/TextEditor.cpp

@@ -1075,7 +1075,7 @@ void TextEditor::set_cursor(const TextPosition& a_position)
     if (position.column() > lines()[position.line()].length())
         position.set_column(lines()[position.line()].length());
 
-    if (m_cursor != position) {
+    if (m_cursor != position && is_visual_data_up_to_date()) {
         // NOTE: If the old cursor is no longer valid, repaint everything just in case.
         auto old_cursor_line_rect = m_cursor.line() < line_count()
             ? line_widget_rect(m_cursor.line())
@@ -1085,6 +1085,9 @@ void TextEditor::set_cursor(const TextPosition& a_position)
         scroll_cursor_into_view();
         update(old_cursor_line_rect);
         update_cursor();
+    } else if (m_cursor != position) {
+        m_cursor = position;
+        m_cursor_state = true;
     }
     cursor_did_change();
     if (on_cursor_change)
@@ -1387,6 +1390,8 @@ void TextEditor::recompute_all_visual_lines()
         return;
     }
 
+    m_reflow_requested = false;
+
     int y_offset = 0;
     for (size_t line_index = 0; line_index < line_count(); ++line_index) {
         recompute_visual_lines(line_index);

+ 3 - 1
Libraries/LibGUI/TextEditor.h

@@ -259,7 +259,9 @@ private:
     NonnullRefPtrVector<Action> m_custom_context_menu_actions;
 
     size_t m_reflow_deferred { 0 };
-    size_t m_reflow_requested { 0 };
+    bool m_reflow_requested { false };
+
+    bool is_visual_data_up_to_date() const { return !m_reflow_requested; }
 
     RefPtr<TextDocument> m_document;