summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-05-27 19:18:40 +0200
committerAndreas Kling <kling@serenityos.org>2020-05-27 19:52:18 +0200
commita8f0e4d56e70013803c09943ffb33e4d86c768fa (patch)
treef7ad9e34d2ac1892d9015eb81200918dda11010e
parent30edd198eceee089d53ab40a7d97f607924b5640 (diff)
downloadserenity-a8f0e4d56e70013803c09943ffb33e4d86c768fa.zip
LibGUI: Defer line reflow during text insertion
Add a deferral counter and defer reflowing the visual lines until the counter is at zero. Use this to defer reflow when inserting text. This fixes glacial slowdown while paste large amounts of text.
-rw-r--r--Libraries/LibGUI/TextEditor.cpp21
-rw-r--r--Libraries/LibGUI/TextEditor.h21
2 files changed, 42 insertions, 0 deletions
diff --git a/Libraries/LibGUI/TextEditor.cpp b/Libraries/LibGUI/TextEditor.cpp
index 85f166d35b..5de7dab05a 100644
--- a/Libraries/LibGUI/TextEditor.cpp
+++ b/Libraries/LibGUI/TextEditor.cpp
@@ -1197,6 +1197,7 @@ void TextEditor::delete_selection()
void TextEditor::insert_at_cursor_or_replace_selection(const StringView& text)
{
+ ReflowDeferrer defer(*this);
ASSERT(!is_readonly());
if (has_selection())
delete_selection();
@@ -1224,6 +1225,7 @@ void TextEditor::paste()
{
if (is_readonly())
return;
+
auto paste_text = Clipboard::the().data();
printf("Paste: \"%s\"\n", paste_text.characters());
@@ -1231,6 +1233,20 @@ void TextEditor::paste()
insert_at_cursor_or_replace_selection(paste_text);
}
+void TextEditor::defer_reflow()
+{
+ ++m_reflow_deferred;
+}
+
+void TextEditor::undefer_reflow()
+{
+ ASSERT(m_reflow_deferred);
+ if (!--m_reflow_deferred) {
+ if (m_reflow_requested)
+ recompute_all_visual_lines();
+ }
+}
+
void TextEditor::enter_event(Core::Event&)
{
ASSERT(window());
@@ -1359,6 +1375,11 @@ void TextEditor::clear_selection()
void TextEditor::recompute_all_visual_lines()
{
+ if (m_reflow_deferred) {
+ m_reflow_requested = true;
+ return;
+ }
+
int y_offset = 0;
for (size_t line_index = 0; line_index < line_count(); ++line_index) {
recompute_visual_lines(line_index);
diff --git a/Libraries/LibGUI/TextEditor.h b/Libraries/LibGUI/TextEditor.h
index f5fa134b4c..a6138ecde9 100644
--- a/Libraries/LibGUI/TextEditor.h
+++ b/Libraries/LibGUI/TextEditor.h
@@ -172,6 +172,24 @@ private:
void did_change();
int fixed_glyph_width() const;
+ void defer_reflow();
+ void undefer_reflow();
+
+ class ReflowDeferrer {
+ public:
+ ReflowDeferrer(TextEditor& editor)
+ : m_editor(editor)
+ {
+ m_editor.defer_reflow();
+ }
+ ~ReflowDeferrer()
+ {
+ m_editor.undefer_reflow();
+ }
+ private:
+ TextEditor& m_editor;
+ };
+
Gfx::Rect line_content_rect(size_t item_index) const;
Gfx::Rect line_widget_rect(size_t line_index) const;
Gfx::Rect cursor_content_rect() const;
@@ -238,6 +256,9 @@ private:
Core::ElapsedTimer m_triple_click_timer;
NonnullRefPtrVector<Action> m_custom_context_menu_actions;
+ size_t m_reflow_deferred { 0 };
+ size_t m_reflow_requested { 0 };
+
RefPtr<TextDocument> m_document;
template<typename Callback>