From d6cb9cf854e2f9e6f715c6f1e715a579cdda8066 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 3 Apr 2024 22:22:19 +0200 Subject: [PATCH] menu_view: make font-style updates more robust The font pointers cached in labels can become dangling when the style database is updated, as happens when changing the font size dynamically. This patch orderly updates the cached pointers before removing out-of-date font entries from the style database. Related to issue #5170 --- repos/gems/src/app/menu_view/label_widget.h | 8 ++++---- repos/gems/src/app/menu_view/main.cc | 16 ++++++++++++++-- repos/gems/src/app/menu_view/style_database.h | 10 ++++++++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/repos/gems/src/app/menu_view/label_widget.h b/repos/gems/src/app/menu_view/label_widget.h index cbbd34230d..3731c5b638 100644 --- a/repos/gems/src/app/menu_view/label_widget.h +++ b/repos/gems/src/app/menu_view/label_widget.h @@ -94,12 +94,12 @@ struct Menu_view::Label_widget : Widget, Cursor::Glyph_position if (node.has_attribute("text")) { _text = node.attribute_value("text", _text); _text = Xml_unquoted(_text); - _min_height = _font->height(); + _min_height = _font ? _font->height() : 0; } unsigned const min_ex = node.attribute_value("min_ex", 0U); if (min_ex) { - Glyph_painter::Fixpoint_number min_w_px = _font->string_width("x"); + Glyph_painter::Fixpoint_number min_w_px = _font ? _font->string_width("x") : 0; min_w_px.value *= min_ex; _min_width = min_w_px.decimal(); } @@ -154,12 +154,12 @@ struct Menu_view::Label_widget : Widget, Cursor::Glyph_position */ int xpos_of_glyph(unsigned at) const override { - return _font->string_width(_text.string(), at).decimal(); + return _font ? _font->string_width(_text.string(), at).decimal() : 0; } unsigned _char_index_at_xpos(unsigned xpos) const { - return _font->index_at_xpos(_text.string(), xpos); + return _font ? _font->index_at_xpos(_text.string(), xpos) : 0; } Hovered hovered(Point at) const override diff --git a/repos/gems/src/app/menu_view/main.cc b/repos/gems/src/app/menu_view/main.cc index f2f96a1a8b..e220ad1cc8 100644 --- a/repos/gems/src/app/menu_view/main.cc +++ b/repos/gems/src/app/menu_view/main.cc @@ -214,8 +214,6 @@ void Menu_view::Main::_handle_config() { _config.update(); - _styles.flush_outdated_styles(); - Xml_node const config = _config.xml(); config.with_optional_sub_node("report", [&] (Xml_node const &report) { @@ -237,6 +235,20 @@ void Menu_view::Main::_handle_config() /* update */ [&] (Dialog &d, Xml_node const &node) { d.update(node); } ); + + /* re-assign font pointers in labels (needed due to font style change) */ + if (!_styles.up_to_date()) { + _dialogs.for_each([&] (Dialog &dialog) { + dialog._handle_dialog(); + + /* fast-forward geometry animation on font changes */ + while (dialog.animation_in_progress()) + dialog.animate(); + }); + + _styles.flush_outdated_styles(); + } + trigger_redraw(); } diff --git a/repos/gems/src/app/menu_view/style_database.h b/repos/gems/src/app/menu_view/style_database.h index d828721b85..b0114655a5 100644 --- a/repos/gems/src/app/menu_view/style_database.h +++ b/repos/gems/src/app/menu_view/style_database.h @@ -65,6 +65,8 @@ class Menu_view::Style_database Path const path; /* needed for lookup */ Label_style const style; + bool const out_of_date = false; + static Label_style _init_style(Allocator &alloc, Directory const &styles_dir, Path const &path) @@ -96,6 +98,8 @@ class Menu_view::Style_database Png_image png_image; Texture &texture; + bool const out_of_date = false; + void const *_png_data() { void const *result = nullptr; @@ -183,10 +187,10 @@ class Menu_view::Style_database T const *_lookup(List &list, char const *path) const { for (T const *e = list.first(); e; e = e->next()) - if (Genode::strcmp(e->path.string(), path) == 0) + if ((Genode::strcmp(e->path.string(), path) == 0) && !e->out_of_date) return e; - return 0; + return nullptr; } /* @@ -313,6 +317,8 @@ class Menu_view::Style_database } _out_of_date = false; } + + bool up_to_date() const { return !_out_of_date; } }; #endif /* _STYLE_DATABASE_H_ */