summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-06-29 11:22:57 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-29 11:22:57 +0200
commitbec2b3086c195e50f233e01f7ab935ba15ac843e (patch)
tree35e2ea129d26f75b6862e7be1ba04603dd3ce0ed /Userland
parent114e8fffcd233abeaa0be9cdbdbebfde2d8fdb15 (diff)
downloadserenity-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.cpp27
-rw-r--r--Userland/Libraries/LibGUI/TextEditor.h3
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 };