mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-11 10:18:15 +09:00
WindowServer+Userland: Pass wallpapers as Gfx::Bitmap
instead of path
The WindowServer _really_ does not need to know the filesystem path to it's wallpaper, and allows setting arbitrary wallpapers (those outside of `/res/wallpapers`). The GUI::Desktop will keep track of the path to the wallpaper (if any), and save it to config if desired (to be persisted). This avoids the need to `unveil` paths to the wallpaper, fixing #11158
This commit is contained in:
parent
f538545987
commit
a0e7a4b9a8
Notes:
sideshowbarker
2024-07-17 18:49:39 +09:00
Author: https://github.com/drunderscore
Commit: a0e7a4b9a8
Pull-request: https://github.com/SerenityOS/serenity/pull/11523
Reviewed-by: https://github.com/awesomekling
Reviewed-by: https://github.com/creator1creeper1
Reviewed-by: https://github.com/kleinesfilmroellchen ✅
13 changed files with 61 additions and 58 deletions
|
@ -140,9 +140,7 @@ void BackgroundSettingsWidget::load_current_settings()
|
||||||
|
|
||||||
void BackgroundSettingsWidget::apply_settings()
|
void BackgroundSettingsWidget::apply_settings()
|
||||||
{
|
{
|
||||||
if (GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper()))
|
if (!GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper_bitmap(), m_monitor_widget->wallpaper()))
|
||||||
Config::write_string("WindowManager", "Background", "Wallpaper", m_monitor_widget->wallpaper());
|
|
||||||
else
|
|
||||||
GUI::MessageBox::show_error(window(), String::formatted("Unable to load file {} as wallpaper", m_monitor_widget->wallpaper()));
|
GUI::MessageBox::show_error(window(), String::formatted("Unable to load file {} as wallpaper", m_monitor_widget->wallpaper()));
|
||||||
|
|
||||||
GUI::Desktop::the().set_background_color(m_color_input->text());
|
GUI::Desktop::the().set_background_color(m_color_input->text());
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool MonitorWidget::set_wallpaper(String path)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String MonitorWidget::wallpaper()
|
StringView MonitorWidget::wallpaper() const
|
||||||
{
|
{
|
||||||
return m_desktop_wallpaper_path;
|
return m_desktop_wallpaper_path;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ void MonitorWidget::set_wallpaper_mode(String mode)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
String MonitorWidget::wallpaper_mode()
|
StringView MonitorWidget::wallpaper_mode() const
|
||||||
{
|
{
|
||||||
return m_desktop_wallpaper_mode;
|
return m_desktop_wallpaper_mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@ class MonitorWidget final : public GUI::Widget {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool set_wallpaper(String path);
|
bool set_wallpaper(String path);
|
||||||
String wallpaper();
|
StringView wallpaper() const;
|
||||||
|
|
||||||
void set_wallpaper_mode(String mode);
|
void set_wallpaper_mode(String mode);
|
||||||
String wallpaper_mode();
|
StringView wallpaper_mode() const;
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap> wallpaper_bitmap() const { return m_wallpaper_bitmap; }
|
||||||
|
|
||||||
void set_desktop_resolution(Gfx::IntSize resolution);
|
void set_desktop_resolution(Gfx::IntSize resolution);
|
||||||
Gfx::IntSize desktop_resolution();
|
Gfx::IntSize desktop_resolution();
|
||||||
|
|
|
@ -506,14 +506,20 @@ ErrorOr<int> run_in_desktop_mode()
|
||||||
struct BackgroundWallpaperListener : Config::Listener {
|
struct BackgroundWallpaperListener : Config::Listener {
|
||||||
virtual void config_string_did_change(String const& domain, String const& group, String const& key, String const& value) override
|
virtual void config_string_did_change(String const& domain, String const& group, String const& key, String const& value) override
|
||||||
{
|
{
|
||||||
if (domain == "WindowManager" && group == "Background" && key == "Wallpaper")
|
if (domain == "WindowManager" && group == "Background" && key == "Wallpaper") {
|
||||||
GUI::Desktop::the().set_wallpaper(value, false);
|
auto wallpaper_bitmap_or_error = Gfx::Bitmap::try_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(), {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} wallpaper_listener;
|
} wallpaper_listener;
|
||||||
|
|
||||||
auto selected_wallpaper = Config::read_string("WindowManager", "Background", "Wallpaper", "");
|
auto selected_wallpaper = Config::read_string("WindowManager", "Background", "Wallpaper", "");
|
||||||
if (!selected_wallpaper.is_empty()) {
|
if (!selected_wallpaper.is_empty()) {
|
||||||
GUI::Desktop::the().set_wallpaper(selected_wallpaper, false);
|
auto wallpaper_bitmap = TRY(Gfx::Bitmap::try_load_from_file(selected_wallpaper));
|
||||||
|
GUI::Desktop::the().set_wallpaper(wallpaper_bitmap, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
|
@ -169,8 +169,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
auto desktop_wallpaper_action = GUI::Action::create("Set as Desktop &Wallpaper", TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-display-settings.png")),
|
auto desktop_wallpaper_action = GUI::Action::create("Set as Desktop &Wallpaper", TRY(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-display-settings.png")),
|
||||||
[&](auto&) {
|
[&](auto&) {
|
||||||
auto could_set_wallpaper = GUI::Desktop::the().set_wallpaper(widget->path());
|
if (!GUI::Desktop::the().set_wallpaper(widget->bitmap(), widget->path())) {
|
||||||
if (!could_set_wallpaper) {
|
|
||||||
GUI::MessageBox::show(window,
|
GUI::MessageBox::show(window,
|
||||||
String::formatted("set_wallpaper({}) failed", widget->path()),
|
String::formatted("set_wallpaper({}) failed", widget->path()),
|
||||||
"Could not set wallpaper",
|
"Could not set wallpaper",
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Badge.h>
|
#include <AK/Badge.h>
|
||||||
|
#include <AK/TemporaryChange.h>
|
||||||
#include <LibGUI/Desktop.h>
|
#include <LibGUI/Desktop.h>
|
||||||
#include <LibGUI/WindowServerConnection.h>
|
#include <LibGUI/WindowServerConnection.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -53,22 +54,30 @@ void Desktop::set_wallpaper_mode(StringView mode)
|
||||||
WindowServerConnection::the().async_set_wallpaper_mode(mode);
|
WindowServerConnection::the().async_set_wallpaper_mode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Desktop::set_wallpaper(StringView path, bool save_config)
|
String Desktop::wallpaper_path() const
|
||||||
{
|
{
|
||||||
WindowServerConnection::the().async_set_wallpaper(path);
|
return Config::read_string("WindowManager", "Background", "Wallpaper");
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<Gfx::Bitmap> Desktop::wallpaper_bitmap() const
|
||||||
|
{
|
||||||
|
return WindowServerConnection::the().get_wallpaper().bitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Desktop::set_wallpaper(RefPtr<Gfx::Bitmap> wallpaper_bitmap, Optional<String> path)
|
||||||
|
{
|
||||||
|
if (m_is_setting_desktop_wallpaper)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TemporaryChange is_setting_desktop_wallpaper_change(m_is_setting_desktop_wallpaper, true);
|
||||||
|
WindowServerConnection::the().async_set_wallpaper(wallpaper_bitmap ? wallpaper_bitmap->to_shareable_bitmap() : Gfx::ShareableBitmap {});
|
||||||
auto ret_val = WindowServerConnection::the().wait_for_specific_message<Messages::WindowClient::SetWallpaperFinished>()->success();
|
auto ret_val = WindowServerConnection::the().wait_for_specific_message<Messages::WindowClient::SetWallpaperFinished>()->success();
|
||||||
|
|
||||||
if (ret_val && save_config) {
|
if (ret_val && path.has_value()) {
|
||||||
dbgln("Saving wallpaper path '{}' to ConfigServer", path);
|
dbgln("Saving wallpaper path '{}' to ConfigServer", *path);
|
||||||
Config::write_string("WindowManager", "Background", "Wallpaper", path);
|
Config::write_string("WindowManager", "Background", "Wallpaper", *path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
String Desktop::wallpaper() const
|
|
||||||
{
|
|
||||||
return WindowServerConnection::the().get_wallpaper();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,9 @@ public:
|
||||||
|
|
||||||
void set_wallpaper_mode(StringView mode);
|
void set_wallpaper_mode(StringView mode);
|
||||||
|
|
||||||
String wallpaper() const;
|
String wallpaper_path() const;
|
||||||
bool set_wallpaper(StringView path, bool save_config = true);
|
RefPtr<Gfx::Bitmap> wallpaper_bitmap() const;
|
||||||
|
bool set_wallpaper(RefPtr<Gfx::Bitmap> wallpaper_bitmap, Optional<String> path);
|
||||||
|
|
||||||
Gfx::IntRect rect() const { return m_bounding_rect; }
|
Gfx::IntRect rect() const { return m_bounding_rect; }
|
||||||
const Vector<Gfx::IntRect, 4>& rects() const { return m_rects; }
|
const Vector<Gfx::IntRect, 4>& rects() const { return m_rects; }
|
||||||
|
@ -56,6 +57,7 @@ private:
|
||||||
unsigned m_workspace_rows { 1 };
|
unsigned m_workspace_rows { 1 };
|
||||||
unsigned m_workspace_columns { 1 };
|
unsigned m_workspace_columns { 1 };
|
||||||
Vector<Function<void(Desktop&)>> m_receive_rects_callbacks;
|
Vector<Function<void(Desktop&)>> m_receive_rects_callbacks;
|
||||||
|
bool m_is_setting_desktop_wallpaper { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,11 +292,10 @@ void ClientConnection::set_window_opacity(i32 window_id, float opacity)
|
||||||
it->value->set_opacity(opacity);
|
it->value->set_opacity(opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::set_wallpaper(String const& path)
|
void ClientConnection::set_wallpaper(Gfx::ShareableBitmap const& bitmap)
|
||||||
{
|
{
|
||||||
Compositor::the().set_wallpaper(path, [&](bool success) {
|
Compositor::the().set_wallpaper(bitmap.bitmap());
|
||||||
async_set_wallpaper_finished(success);
|
async_set_wallpaper_finished(true);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::set_background_color(String const& background_color)
|
void ClientConnection::set_background_color(String const& background_color)
|
||||||
|
@ -311,7 +310,7 @@ void ClientConnection::set_wallpaper_mode(String const& mode)
|
||||||
|
|
||||||
Messages::WindowServer::GetWallpaperResponse ClientConnection::get_wallpaper()
|
Messages::WindowServer::GetWallpaperResponse ClientConnection::get_wallpaper()
|
||||||
{
|
{
|
||||||
return Compositor::the().wallpaper_path();
|
return Compositor::the().wallpaper_bitmap()->to_shareable_bitmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WindowServer::SetScreenLayoutResponse ClientConnection::set_screen_layout(ScreenLayout const& screen_layout, bool save)
|
Messages::WindowServer::SetScreenLayoutResponse ClientConnection::set_screen_layout(ScreenLayout const& screen_layout, bool save)
|
||||||
|
|
|
@ -123,7 +123,7 @@ private:
|
||||||
virtual void set_fullscreen(i32, bool) override;
|
virtual void set_fullscreen(i32, bool) override;
|
||||||
virtual void set_frameless(i32, bool) override;
|
virtual void set_frameless(i32, bool) override;
|
||||||
virtual void set_forced_shadow(i32, bool) override;
|
virtual void set_forced_shadow(i32, bool) override;
|
||||||
virtual void set_wallpaper(String const&) override;
|
virtual void set_wallpaper(Gfx::ShareableBitmap const&) override;
|
||||||
virtual void set_background_color(String const&) override;
|
virtual void set_background_color(String const&) override;
|
||||||
virtual void set_wallpaper_mode(String const&) override;
|
virtual void set_wallpaper_mode(String const&) override;
|
||||||
virtual Messages::WindowServer::GetWallpaperResponse get_wallpaper() override;
|
virtual Messages::WindowServer::GetWallpaperResponse get_wallpaper() override;
|
||||||
|
|
|
@ -805,26 +805,14 @@ bool Compositor::set_wallpaper_mode(const String& mode)
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compositor::set_wallpaper(const String& path, Function<void(bool)>&& callback)
|
bool Compositor::set_wallpaper(RefPtr<Gfx::Bitmap> bitmap)
|
||||||
{
|
{
|
||||||
(void)Threading::BackgroundAction<ErrorOr<NonnullRefPtr<Gfx::Bitmap>>>::construct(
|
if (!bitmap)
|
||||||
[path](auto&) {
|
m_wallpaper = nullptr;
|
||||||
return Gfx::Bitmap::try_load_from_file(path);
|
else
|
||||||
},
|
m_wallpaper = bitmap;
|
||||||
|
invalidate_screen();
|
||||||
|
|
||||||
[this, path, callback = move(callback)](ErrorOr<NonnullRefPtr<Gfx::Bitmap>> bitmap) {
|
|
||||||
if (bitmap.is_error() && !path.is_empty()) {
|
|
||||||
callback(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_wallpaper_path = path;
|
|
||||||
if (bitmap.is_error())
|
|
||||||
m_wallpaper = nullptr;
|
|
||||||
else
|
|
||||||
m_wallpaper = bitmap.release_value();
|
|
||||||
invalidate_screen();
|
|
||||||
callback(true);
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,8 @@ public:
|
||||||
|
|
||||||
bool set_wallpaper_mode(const String& mode);
|
bool set_wallpaper_mode(const String& mode);
|
||||||
|
|
||||||
bool set_wallpaper(const String& path, Function<void(bool)>&& callback);
|
bool set_wallpaper(RefPtr<Gfx::Bitmap>);
|
||||||
String wallpaper_path() const { return m_wallpaper_path; }
|
RefPtr<Gfx::Bitmap> wallpaper_bitmap() const { return m_wallpaper; }
|
||||||
|
|
||||||
void invalidate_cursor(bool = false);
|
void invalidate_cursor(bool = false);
|
||||||
Gfx::IntRect current_cursor_rect() const;
|
Gfx::IntRect current_cursor_rect() const;
|
||||||
|
@ -227,7 +227,6 @@ private:
|
||||||
Gfx::DisjointRectSet m_opaque_wallpaper_rects;
|
Gfx::DisjointRectSet m_opaque_wallpaper_rects;
|
||||||
Gfx::DisjointRectSet m_transparent_wallpaper_rects;
|
Gfx::DisjointRectSet m_transparent_wallpaper_rects;
|
||||||
|
|
||||||
String m_wallpaper_path { "" };
|
|
||||||
WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked };
|
WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked };
|
||||||
RefPtr<Gfx::Bitmap> m_wallpaper;
|
RefPtr<Gfx::Bitmap> m_wallpaper;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ endpoint WindowServer
|
||||||
popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =|
|
popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =|
|
||||||
dismiss_menu(i32 menu_id) =|
|
dismiss_menu(i32 menu_id) =|
|
||||||
|
|
||||||
set_wallpaper(String path) =|
|
set_wallpaper(Gfx::ShareableBitmap wallpaper_bitmap) =|
|
||||||
|
|
||||||
set_background_color(String background_color) =|
|
set_background_color(String background_color) =|
|
||||||
set_wallpaper_mode(String mode) =|
|
set_wallpaper_mode(String mode) =|
|
||||||
|
@ -106,7 +106,7 @@ endpoint WindowServer
|
||||||
|
|
||||||
set_window_icon_bitmap(i32 window_id, Gfx::ShareableBitmap icon) =|
|
set_window_icon_bitmap(i32 window_id, Gfx::ShareableBitmap icon) =|
|
||||||
|
|
||||||
get_wallpaper() => (String path)
|
get_wallpaper() => (Gfx::ShareableBitmap wallpaper_bitmap)
|
||||||
set_window_cursor(i32 window_id, i32 cursor_type) =|
|
set_window_cursor(i32 window_id, i32 cursor_type) =|
|
||||||
set_window_custom_cursor(i32 window_id, Gfx::ShareableBitmap cursor) =|
|
set_window_custom_cursor(i32 window_id, Gfx::ShareableBitmap cursor) =|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2022, James Puleo <james@jame.xyz>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +31,7 @@ static int handle_show_all()
|
||||||
|
|
||||||
static int handle_show_current()
|
static int handle_show_current()
|
||||||
{
|
{
|
||||||
outln("{}", GUI::Desktop::the().wallpaper());
|
outln("{}", GUI::Desktop::the().wallpaper_path());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ static int handle_set_pape(const String& name)
|
||||||
builder.append("/res/wallpapers/");
|
builder.append("/res/wallpapers/");
|
||||||
builder.append(name);
|
builder.append(name);
|
||||||
String path = builder.to_string();
|
String path = builder.to_string();
|
||||||
if (!GUI::Desktop::the().set_wallpaper(path)) {
|
if (!GUI::Desktop::the().set_wallpaper(MUST(Gfx::Bitmap::try_load_from_file(path)), path)) {
|
||||||
warnln("pape: Failed to set wallpaper {}", path);
|
warnln("pape: Failed to set wallpaper {}", path);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -58,13 +59,13 @@ static int handle_set_random()
|
||||||
while (di.has_next()) {
|
while (di.has_next()) {
|
||||||
wallpapers.append(di.next_full_path());
|
wallpapers.append(di.next_full_path());
|
||||||
}
|
}
|
||||||
wallpapers.remove_all_matching([](const String& wallpaper) { return wallpaper == GUI::Desktop::the().wallpaper(); });
|
wallpapers.remove_all_matching([](const String& wallpaper) { return wallpaper == GUI::Desktop::the().wallpaper_path(); });
|
||||||
if (wallpapers.is_empty()) {
|
if (wallpapers.is_empty()) {
|
||||||
warnln("pape: No wallpapers found");
|
warnln("pape: No wallpapers found");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
auto& wallpaper = wallpapers.at(get_random_uniform(wallpapers.size()));
|
auto& wallpaper = wallpapers.at(get_random_uniform(wallpapers.size()));
|
||||||
if (!GUI::Desktop::the().set_wallpaper(wallpaper)) {
|
if (!GUI::Desktop::the().set_wallpaper(MUST(Gfx::Bitmap::try_load_from_file(wallpaper)), wallpaper)) {
|
||||||
warnln("pape: Failed to set wallpaper {}", wallpaper);
|
warnln("pape: Failed to set wallpaper {}", wallpaper);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue