diff options
author | Andreas Kling <kling@serenityos.org> | 2021-06-29 11:22:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-29 11:22:57 +0200 |
commit | bec2b3086c195e50f233e01f7ab935ba15ac843e (patch) | |
tree | 35e2ea129d26f75b6862e7be1ba04603dd3ce0ed /Userland | |
parent | 114e8fffcd233abeaa0be9cdbdbebfde2d8fdb15 (diff) | |
download | serenity-bec2b3086c195e50f233e01f7ab935ba15ac843e.zip |
LibGUI: Don't fire on_change hook at start of TextEditor::paint_event()
If something happens in response to on_change that causes the widget
to get unparented, creating a GUI::Painter will fail since it can't
find the window to paint into.
Since painting only cares about the syntax highlighting spans, what we
really want is to ensure that spans are up-to-date before we start
painting.
The problem was that rehighlighting and the on_change hook were bundled
together in an awkward lazy update mechanism. This patch fixes that by
decoupling rehighlighting and on_change. Rehighlighting is now lazy
and only happens when we handle either paint or mouse events. :^)
Fixes #8302.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGUI/TextEditor.cpp | 27 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/TextEditor.h | 3 |
2 files changed, 12 insertions, 18 deletions
diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 5801d9185a..0dee5cd8e8 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -211,8 +211,7 @@ void TextEditor::doubleclick_event(MouseEvent& event) if (!current_line().can_select()) return; - // NOTE: This ensures that spans are updated before we look at them. - flush_pending_change_notification_if_needed(); + rehighlight_if_needed(); m_triple_click_timer.start(); m_in_drag_select = false; @@ -397,8 +396,8 @@ Gfx::IntRect TextEditor::visible_text_rect_in_inner_coordinates() const void TextEditor::paint_event(PaintEvent& event) { Color widget_background_color = palette().color(is_enabled() ? background_role() : Gfx::ColorRole::Window); - // NOTE: This ensures that spans are updated before we look at them. - flush_pending_change_notification_if_needed(); + + rehighlight_if_needed(); Frame::paint_event(event); @@ -1404,16 +1403,13 @@ void TextEditor::did_change() if (m_autocomplete_timer) m_autocomplete_timer->stop(); } + m_needs_rehighlight = true; if (!m_has_pending_change_notification) { m_has_pending_change_notification = true; deferred_invoke([this](auto&) { - if (!m_has_pending_change_notification) - return; + m_has_pending_change_notification = false; if (on_change) on_change(); - if (m_highlighter) - m_highlighter->rehighlight(palette()); - m_has_pending_change_notification = false; }); } } @@ -1506,8 +1502,7 @@ void TextEditor::resize_event(ResizeEvent& event) void TextEditor::theme_change_event(ThemeChangeEvent& event) { AbstractScrollableWidget::theme_change_event(event); - if (m_highlighter) - m_highlighter->rehighlight(palette()); + m_needs_rehighlight = true; } void TextEditor::set_selection(const TextRange& selection) @@ -1765,15 +1760,13 @@ void TextEditor::set_document(TextDocument& document) m_document->register_client(*this); } -void TextEditor::flush_pending_change_notification_if_needed() +void TextEditor::rehighlight_if_needed() { - if (!m_has_pending_change_notification) + if (!m_needs_rehighlight) return; - if (on_change) - on_change(); if (m_highlighter) m_highlighter->rehighlight(palette()); - m_has_pending_change_notification = false; + m_needs_rehighlight = false; } const Syntax::Highlighter* TextEditor::syntax_highlighter() const @@ -1788,7 +1781,7 @@ void TextEditor::set_syntax_highlighter(OwnPtr<Syntax::Highlighter> highlighter) m_highlighter = move(highlighter); if (m_highlighter) { m_highlighter->attach(*this); - m_highlighter->rehighlight(palette()); + m_needs_rehighlight = true; } else document().set_spans({}); } diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h index c1760caba3..d73e220c43 100644 --- a/Userland/Libraries/LibGUI/TextEditor.h +++ b/Userland/Libraries/LibGUI/TextEditor.h @@ -283,7 +283,7 @@ private: Gfx::IntRect visible_text_rect_in_inner_coordinates() const; void recompute_all_visual_lines(); void ensure_cursor_is_valid(); - void flush_pending_change_notification_if_needed(); + void rehighlight_if_needed(); size_t visual_line_containing(size_t line_index, size_t column) const; void recompute_visual_lines(size_t line_index); @@ -311,6 +311,7 @@ private: bool m_in_drag_select { false }; bool m_ruler_visible { false }; bool m_gutter_visible { false }; + bool m_needs_rehighlight { false }; bool m_has_pending_change_notification { false }; bool m_automatic_indentation_enabled { false }; WrappingMode m_wrapping_mode { WrappingMode::NoWrap }; |