Userland: Improve support for vector desktop wallpapers

When loading or setting a wallpaper pass the desktop size as the "ideal
size". This allows the loader to appropriately scale vector wallpapers
to match the desktop size.
This commit is contained in:
MacDue authored and Nico Weber committed 2025-07-06 08:27:03 +02:00
1 parent 84bffa3a91
commit ecec1ab62a
7 files changed
+38 -28

No files matched your search

@@ -248,7 +248,7 @@ void BackgroundSettingsWidget::apply_settings()
{
// We need to provide an empty path (not OptionalNone) to set_wallpaper to save a solid color wallpaper.
auto wallpaper_path = m_monitor_widget->wallpaper().value_or(""sv);
if (!GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper_bitmap(), wallpaper_path)) {
if (!GUI::Desktop::the().set_wallpaper(wallpaper_path)) {
if (!wallpaper_path.is_empty())
GUI::MessageBox::show_error(window(), MUST(String::formatted("Unable to load file {} as wallpaper", wallpaper_path)));
else
@@ -11,6 +11,7 @@
#include <LibGUI/Button.h>
#include <LibGUI/ComboBox.h>
#include <LibGUI/ConnectionToWindowServer.h>
#include <LibGUI/Desktop.h>
#include <LibGUI/ItemListModel.h>
#include <LibGUI/Label.h>
#include <LibGUI/MessageBox.h>
@@ -30,8 +30,9 @@ ErrorOr<NonnullRefPtr<MonitorWidget>> MonitorWidget::try_create()
void MonitorWidget::load_wallpaper(String path)
{
(void)Threading::BackgroundAction<NonnullRefPtr<Gfx::Bitmap>>::construct(
[path](auto&) -> ErrorOr<NonnullRefPtr<Gfx::Bitmap>> {
return Gfx::Bitmap::load_from_file(path);
[path, this](auto&) -> ErrorOr<NonnullRefPtr<Gfx::Bitmap>> {
constexpr auto scale_factor = 1;
return Gfx::Bitmap::load_from_file(path, scale_factor, m_monitor_rect.size());
},
[this, path](NonnullRefPtr<Gfx::Bitmap> bitmap) -> ErrorOr<void> {
+5 -19
View File
@@ -279,7 +279,8 @@ void do_set_wallpaper(ByteString const& file_path, GUI::Window* window)
GUI::MessageBox::show(window, ByteString::formatted("Failed to set {} as wallpaper.", file_path), "Failed to set wallpaper"sv, GUI::MessageBox::Type::Error);
};
auto bitmap_or_error = Gfx::Bitmap::load_from_file(file_path);
constexpr auto scale_factor = 1;
auto bitmap_or_error = Gfx::Bitmap::load_from_file(file_path, scale_factor, GUI::Desktop::the().rect().size());
if (bitmap_or_error.is_error()) {
show_error();
return;
@@ -572,33 +573,18 @@ ErrorOr<int> run_in_desktop_mode()
desktop_view_context_menu->popup(event.screen_position());
}
};
struct BackgroundWallpaperListener : Config::Listener {
virtual void config_string_did_change(StringView domain, StringView group, StringView key, StringView value) override
{
if (domain == "WindowManager" && group == "Background" && key == "Wallpaper") {
if (value.is_empty()) {
GUI::Desktop::the().set_wallpaper(nullptr, {});
return;
}
auto wallpaper_bitmap_or_error = Gfx::Bitmap::load_from_file(value);
if (wallpaper_bitmap_or_error.is_error())
dbgln("Failed to load wallpaper bitmap from path: {}", wallpaper_bitmap_or_error.error());
else
GUI::Desktop::the().set_wallpaper(wallpaper_bitmap_or_error.release_value(), {});
}
if (domain == "WindowManager" && group == "Background" && key == "Wallpaper")
GUI::Desktop::the().apply_wallpaper(nullptr, value);
}
} wallpaper_listener;
auto selected_wallpaper = Config::read_string("WindowManager"sv, "Background"sv, "Wallpaper"sv, ""sv);
RefPtr<Gfx::Bitmap> wallpaper_bitmap {};
if (!selected_wallpaper.is_empty()) {
wallpaper_bitmap = TRY(Gfx::Bitmap::load_from_file(selected_wallpaper));
}
// This sets the wallpaper at startup, even if there is no wallpaper, the
// desktop should still show the background color. It's fine to pass a
// nullptr to Desktop::set_wallpaper.
GUI::Desktop::the().set_wallpaper(wallpaper_bitmap, {});
GUI::Desktop::the().load_current_wallpaper();
window->show();
return GUI::Application::the()->exec();
+23 -2
View File
@@ -59,13 +59,28 @@ RefPtr<Gfx::Bitmap> Desktop::wallpaper_bitmap() const
return ConnectionToWindowServer::the().get_wallpaper().bitmap();
}
bool Desktop::set_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional<StringView> path)
bool Desktop::apply_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional<StringView> path)
{
if (m_is_setting_desktop_wallpaper)
return false;
if (!wallpaper_bitmap && path.has_value() && !path->is_empty()) {
constexpr auto scale_factor = 1;
auto maybe_wallpaper_bitmap = Gfx::Bitmap::load_from_file(*path, scale_factor, rect().size());
if (maybe_wallpaper_bitmap.is_error()) {
dbgln("Failed to load wallpaper bitmap from path: {}", maybe_wallpaper_bitmap.error());
return false;
}
wallpaper_bitmap = maybe_wallpaper_bitmap.release_value();
}
TemporaryChange is_setting_desktop_wallpaper_change(m_is_setting_desktop_wallpaper, true);
auto result = ConnectionToWindowServer::the().set_wallpaper(wallpaper_bitmap ? wallpaper_bitmap->to_shareable_bitmap() : Gfx::ShareableBitmap {});
return ConnectionToWindowServer::the().set_wallpaper(wallpaper_bitmap ? wallpaper_bitmap->to_shareable_bitmap() : Gfx::ShareableBitmap {});
}
bool Desktop::set_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional<StringView> path)
{
bool result = apply_wallpaper(wallpaper_bitmap, path);
if (result && path.has_value()) {
dbgln("Saving wallpaper path '{}' to ConfigServer", *path);
@@ -75,4 +90,10 @@ bool Desktop::set_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional
return result;
}
bool Desktop::load_current_wallpaper()
{
auto current_wallpaper = Config::read_string("WindowManager"sv, "Background"sv, "Wallpaper"sv, ""sv);
return apply_wallpaper({}, current_wallpaper);
}
}
+3
View File
@@ -34,6 +34,9 @@ public:
ByteString wallpaper_path() const;
RefPtr<Gfx::Bitmap> wallpaper_bitmap() const;
bool set_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional<StringView> path);
bool apply_wallpaper(RefPtr<Gfx::Bitmap const> wallpaper_bitmap, Optional<StringView> path);
bool set_wallpaper(StringView path) { return set_wallpaper({}, path); }
bool load_current_wallpaper();
void set_system_effects(Vector<bool> effects) { m_system_effects = { effects }; }
SystemEffects const& system_effects() const { return m_system_effects; }
+2 -4
View File
@@ -65,8 +65,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return Error::from_string_literal("No wallpapers found");
auto& chosen_wallpaper_path = wallpaper_paths.at(get_random_uniform(wallpaper_paths.size()));
auto chosen_wallpaper_bitmap = TRY(Gfx::Bitmap::load_from_file(chosen_wallpaper_path));
if (!GUI::Desktop::the().set_wallpaper(chosen_wallpaper_bitmap, chosen_wallpaper_path))
if (!GUI::Desktop::the().set_wallpaper(chosen_wallpaper_path))
return Error::from_string_literal("Failed to set wallpaper");
outln("Set wallpaper to {}", chosen_wallpaper_path);
@@ -74,8 +73,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (path.is_null())
return Error::from_string_literal("Must provide a path to a wallpaper");
auto wallpaper_bitmap = TRY(Gfx::Bitmap::load_from_file(path));
if (!GUI::Desktop::the().set_wallpaper(wallpaper_bitmap, path))
if (!GUI::Desktop::the().set_wallpaper(path))
return Error::from_string_literal("Failed to set wallpaper");
}
return 0;