From 1474a537b630ef1b6b638164bca9043f0622d617 Mon Sep 17 00:00:00 2001 From: Andrew January Date: Tue, 17 Aug 2021 13:02:29 +0100 Subject: DisplaySettings: Lazily load wallpapers Load the wallpaper in a background action instead of on the main thread. This reduces the time to first paint, and makes the UI feel more responsive when clicking on wallpaper thumbnails. The behavior of the method is changed slightly to return true if it succesfully "loads" the empty path. This makes the API a little more consistent, where "true" means "I made changes" and "false" means "I did not make changes". No call sites currently use the return value, so no changes are needed to those. --- .../Applications/DisplaySettings/MonitorWidget.cpp | 39 ++++++++++++++-------- .../Applications/DisplaySettings/MonitorWidget.h | 5 +++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Userland/Applications/DisplaySettings/MonitorWidget.cpp b/Userland/Applications/DisplaySettings/MonitorWidget.cpp index db25078f95..506caf0b6c 100644 --- a/Userland/Applications/DisplaySettings/MonitorWidget.cpp +++ b/Userland/Applications/DisplaySettings/MonitorWidget.cpp @@ -10,6 +10,7 @@ #include #include #include +#include REGISTER_WIDGET(DisplaySettings, MonitorWidget) @@ -26,23 +27,35 @@ MonitorWidget::MonitorWidget() bool MonitorWidget::set_wallpaper(String path) { - if (path == m_desktop_wallpaper_path) + if (!is_different_to_current_wallpaper_path(path)) return false; - if (path.is_empty()) { - m_wallpaper_bitmap = nullptr; + Threading::BackgroundAction>::create( + [path](auto&) { + RefPtr bmp; + if (!path.is_empty()) + bmp = Gfx::Bitmap::try_load_from_file(path); + return bmp; + }, + + [this, path](RefPtr bitmap) { + // If we've been requested to change while we were loading the bitmap, don't bother spending the cost to + // move and render the now stale bitmap. + if (is_different_to_current_wallpaper_path(path)) + return; + if (!bitmap.is_null()) + m_wallpaper_bitmap = move(bitmap); + else + m_wallpaper_bitmap = nullptr; + m_desktop_dirty = true; + update(); + }); + + if (path.is_empty()) m_desktop_wallpaper_path = nullptr; - m_desktop_dirty = true; - update(); - return false; - } + else + m_desktop_wallpaper_path = move(path); - auto bitmap = Gfx::Bitmap::try_load_from_file(path); - if (bitmap) - m_wallpaper_bitmap = move(bitmap); - m_desktop_wallpaper_path = move(path); - m_desktop_dirty = true; - update(); return true; } diff --git a/Userland/Applications/DisplaySettings/MonitorWidget.h b/Userland/Applications/DisplaySettings/MonitorWidget.h index 272eaa5156..154e87d8b6 100644 --- a/Userland/Applications/DisplaySettings/MonitorWidget.h +++ b/Userland/Applications/DisplaySettings/MonitorWidget.h @@ -47,6 +47,11 @@ private: Gfx::IntSize m_desktop_resolution; int m_desktop_scale_factor { 1 }; Gfx::Color m_desktop_color; + + bool is_different_to_current_wallpaper_path(String const& path) + { + return (!path.is_empty() && path != m_desktop_wallpaper_path) || (path.is_empty() && m_desktop_wallpaper_path != nullptr); + } }; } -- cgit v1.2.3