mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:22:45 +00: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
					
				
					 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
	
	 James Puleo
						James Puleo