From 35b74ebbfcfda4a8e1855538f77422f868ed5123 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Wed, 14 Sep 2022 15:08:38 -0400 Subject: [PATCH] LibGUI: Defer loading emoji icons until their first paint event The EmojiInputDialog re-uses emoji buttons to help with performance as filters are applied / removed. The downside of pre-creating the buttons is that it currently takes upwards of 600ms (on my machine) to load all emoji icons from disk at once. This will only become worse over time as more emoji are added. To alleviate this, defer loading the icons until they are needed for painting (i.e. come into view). --- .../Libraries/LibGUI/EmojiInputDialog.cpp | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp index 7b8e06ff52..2e1f5d06c0 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp @@ -59,6 +59,34 @@ static void resize_bitmap_if_needed(NonnullRefPtr& bitmap) } } +class EmojiButton final : public Button { + C_OBJECT(EmojiButton); + +private: + explicit EmojiButton(String emoji_icon_path) + : Button() + , m_emoji_icon_path(move(emoji_icon_path)) + { + } + + virtual void paint_event(PaintEvent& event) override + { + if (m_first_paint_event) { + m_first_paint_event = false; + + auto bitmap = Gfx::Bitmap::try_load_from_file(m_emoji_icon_path).release_value_but_fixme_should_propagate_errors(); + resize_bitmap_if_needed(bitmap); + + set_icon(move(bitmap)); + } + + Button::paint_event(event); + } + + bool m_first_paint_event { true }; + String m_emoji_icon_path; +}; + EmojiInputDialog::EmojiInputDialog(Window* parent_window) : Dialog(parent_window) , m_category_action_group(make()) @@ -158,11 +186,7 @@ auto EmojiInputDialog::supported_emoji() -> Vector emoji->display_order = NumericLimits::max(); } - auto bitmap = Gfx::Bitmap::try_load_from_file(filename).release_value_but_fixme_should_propagate_errors(); - resize_bitmap_if_needed(bitmap); - - auto button = Button::construct(); - button->set_icon(bitmap); + auto button = EmojiButton::construct(move(filename)); button->set_fixed_size(button_size, button_size); button->set_button_style(Gfx::ButtonStyle::Coolbar); button->on_click = [this, text = builder.to_string()](auto) {