mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 19:32: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() | ||||
| { | ||||
|     if (GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper())) | ||||
|         Config::write_string("WindowManager", "Background", "Wallpaper", m_monitor_widget->wallpaper()); | ||||
|     else | ||||
|     if (!GUI::Desktop::the().set_wallpaper(m_monitor_widget->wallpaper_bitmap(), 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()); | ||||
|  |  | |||
|  | @ -58,7 +58,7 @@ bool MonitorWidget::set_wallpaper(String path) | |||
|     return true; | ||||
| } | ||||
| 
 | ||||
| String MonitorWidget::wallpaper() | ||||
| StringView MonitorWidget::wallpaper() const | ||||
| { | ||||
|     return m_desktop_wallpaper_path; | ||||
| } | ||||
|  | @ -72,7 +72,7 @@ void MonitorWidget::set_wallpaper_mode(String mode) | |||
|     update(); | ||||
| } | ||||
| 
 | ||||
| String MonitorWidget::wallpaper_mode() | ||||
| StringView MonitorWidget::wallpaper_mode() const | ||||
| { | ||||
|     return m_desktop_wallpaper_mode; | ||||
| } | ||||
|  |  | |||
|  | @ -15,10 +15,12 @@ class MonitorWidget final : public GUI::Widget { | |||
| 
 | ||||
| public: | ||||
|     bool set_wallpaper(String path); | ||||
|     String wallpaper(); | ||||
|     StringView wallpaper() const; | ||||
| 
 | ||||
|     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); | ||||
|     Gfx::IntSize desktop_resolution(); | ||||
|  |  | |||
|  | @ -506,14 +506,20 @@ ErrorOr<int> run_in_desktop_mode() | |||
|     struct BackgroundWallpaperListener : Config::Listener { | ||||
|         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") | ||||
|                 GUI::Desktop::the().set_wallpaper(value, false); | ||||
|             if (domain == "WindowManager" && group == "Background" && key == "Wallpaper") { | ||||
|                 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; | ||||
| 
 | ||||
|     auto selected_wallpaper = Config::read_string("WindowManager", "Background", "Wallpaper", ""); | ||||
|     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(); | ||||
|  |  | |||
|  | @ -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&) { | ||||
|             auto could_set_wallpaper = GUI::Desktop::the().set_wallpaper(widget->path()); | ||||
|             if (!could_set_wallpaper) { | ||||
|             if (!GUI::Desktop::the().set_wallpaper(widget->bitmap(), widget->path())) { | ||||
|                 GUI::MessageBox::show(window, | ||||
|                     String::formatted("set_wallpaper({}) failed", widget->path()), | ||||
|                     "Could not set wallpaper", | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include <AK/Badge.h> | ||||
| #include <AK/TemporaryChange.h> | ||||
| #include <LibGUI/Desktop.h> | ||||
| #include <LibGUI/WindowServerConnection.h> | ||||
| #include <string.h> | ||||
|  | @ -53,22 +54,30 @@ void Desktop::set_wallpaper_mode(StringView 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(); | ||||
| 
 | ||||
|     if (ret_val && save_config) { | ||||
|         dbgln("Saving wallpaper path '{}' to ConfigServer", path); | ||||
|         Config::write_string("WindowManager", "Background", "Wallpaper", path); | ||||
|     if (ret_val && path.has_value()) { | ||||
|         dbgln("Saving wallpaper path '{}' to ConfigServer", *path); | ||||
|         Config::write_string("WindowManager", "Background", "Wallpaper", *path); | ||||
|     } | ||||
| 
 | ||||
|     return ret_val; | ||||
| } | ||||
| 
 | ||||
| String Desktop::wallpaper() const | ||||
| { | ||||
|     return WindowServerConnection::the().get_wallpaper(); | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -29,8 +29,9 @@ public: | |||
| 
 | ||||
|     void set_wallpaper_mode(StringView mode); | ||||
| 
 | ||||
|     String wallpaper() const; | ||||
|     bool set_wallpaper(StringView path, bool save_config = true); | ||||
|     String wallpaper_path() const; | ||||
|     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; } | ||||
|     const Vector<Gfx::IntRect, 4>& rects() const { return m_rects; } | ||||
|  | @ -56,6 +57,7 @@ private: | |||
|     unsigned m_workspace_rows { 1 }; | ||||
|     unsigned m_workspace_columns { 1 }; | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| void ClientConnection::set_wallpaper(String const& path) | ||||
| void ClientConnection::set_wallpaper(Gfx::ShareableBitmap const& bitmap) | ||||
| { | ||||
|     Compositor::the().set_wallpaper(path, [&](bool success) { | ||||
|         async_set_wallpaper_finished(success); | ||||
|     }); | ||||
|     Compositor::the().set_wallpaper(bitmap.bitmap()); | ||||
|     async_set_wallpaper_finished(true); | ||||
| } | ||||
| 
 | ||||
| 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() | ||||
| { | ||||
|     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) | ||||
|  |  | |||
|  | @ -123,7 +123,7 @@ private: | |||
|     virtual void set_fullscreen(i32, bool) override; | ||||
|     virtual void set_frameless(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_wallpaper_mode(String const&) override; | ||||
|     virtual Messages::WindowServer::GetWallpaperResponse get_wallpaper() override; | ||||
|  |  | |||
|  | @ -805,26 +805,14 @@ bool Compositor::set_wallpaper_mode(const String& mode) | |||
|     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( | ||||
|         [path](auto&) { | ||||
|             return Gfx::Bitmap::try_load_from_file(path); | ||||
|         }, | ||||
|     if (!bitmap) | ||||
|         m_wallpaper = nullptr; | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -105,8 +105,8 @@ public: | |||
| 
 | ||||
|     bool set_wallpaper_mode(const String& mode); | ||||
| 
 | ||||
|     bool set_wallpaper(const String& path, Function<void(bool)>&& callback); | ||||
|     String wallpaper_path() const { return m_wallpaper_path; } | ||||
|     bool set_wallpaper(RefPtr<Gfx::Bitmap>); | ||||
|     RefPtr<Gfx::Bitmap> wallpaper_bitmap() const { return m_wallpaper; } | ||||
| 
 | ||||
|     void invalidate_cursor(bool = false); | ||||
|     Gfx::IntRect current_cursor_rect() const; | ||||
|  | @ -227,7 +227,6 @@ private: | |||
|     Gfx::DisjointRectSet m_opaque_wallpaper_rects; | ||||
|     Gfx::DisjointRectSet m_transparent_wallpaper_rects; | ||||
| 
 | ||||
|     String m_wallpaper_path { "" }; | ||||
|     WallpaperMode m_wallpaper_mode { WallpaperMode::Unchecked }; | ||||
|     RefPtr<Gfx::Bitmap> m_wallpaper; | ||||
| 
 | ||||
|  |  | |||
|  | @ -91,7 +91,7 @@ endpoint WindowServer | |||
|     popup_menu(i32 menu_id, Gfx::IntPoint screen_position) =| | ||||
|     dismiss_menu(i32 menu_id) =| | ||||
| 
 | ||||
|     set_wallpaper(String path) =| | ||||
|     set_wallpaper(Gfx::ShareableBitmap wallpaper_bitmap) =| | ||||
| 
 | ||||
|     set_background_color(String background_color) =| | ||||
|     set_wallpaper_mode(String mode) =| | ||||
|  | @ -106,7 +106,7 @@ endpoint WindowServer | |||
| 
 | ||||
|     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_custom_cursor(i32 window_id, Gfx::ShareableBitmap cursor) =| | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * Copyright (c) 2022, James Puleo <james@jame.xyz> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
|  | @ -30,7 +31,7 @@ static int handle_show_all() | |||
| 
 | ||||
| static int handle_show_current() | ||||
| { | ||||
|     outln("{}", GUI::Desktop::the().wallpaper()); | ||||
|     outln("{}", GUI::Desktop::the().wallpaper_path()); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -40,7 +41,7 @@ static int handle_set_pape(const String& name) | |||
|     builder.append("/res/wallpapers/"); | ||||
|     builder.append(name); | ||||
|     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); | ||||
|         return 1; | ||||
|     } | ||||
|  | @ -58,13 +59,13 @@ static int handle_set_random() | |||
|     while (di.has_next()) { | ||||
|         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()) { | ||||
|         warnln("pape: No wallpapers found"); | ||||
|         return 1; | ||||
|     } | ||||
|     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); | ||||
|         return 1; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 James Puleo
						James Puleo