diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 78826f0fa6..76a953b435 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -332,11 +332,12 @@ void WSClientConnection::handle_request(const WSAPISetWindowOpacityRequest& requ void WSClientConnection::handle_request(const WSAPISetWallpaperRequest& request) { - bool success = WSWindowManager::the().set_wallpaper(request.wallpaper()); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetWallpaper; - response.value = success; - post_message(response); + WSWindowManager::the().set_wallpaper(request.wallpaper(), [&] (bool success) { + WSAPI_ServerMessage response; + response.type = WSAPI_ServerMessage::Type::DidSetWallpaper; + response.value = success; + post_message(response); + }); } void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&) diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 4cd1c47c76..630290efb4 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -188,16 +188,42 @@ void WSWindowManager::tick_clock() invalidate(menubar_rect()); } -bool WSWindowManager::set_wallpaper(const String& path) +bool WSWindowManager::set_wallpaper(const String& path, Function&& callback) { - auto bitmap = load_png(path); - if (!bitmap) - return false; + struct Context { + String path; + RetainPtr bitmap; + Function callback; + }; + auto context = make(); + context->path = path; + context->callback = move(callback); + int rc = create_thread([] (void* ctx) -> int { + OwnPtr context((Context*)ctx); + context->bitmap = load_png(context->path); + if (!context->bitmap) { + context->callback(false); + exit_thread(0); + return 0; + } + the().deferred_invoke([context = move(context)] (auto&) { + the().finish_setting_wallpaper(context->path, *context->bitmap); + context->callback(true); + }); + exit_thread(0); + return 0; + }, context.leak_ptr()); + ASSERT(rc == 0); + + return true; +} + +void WSWindowManager::finish_setting_wallpaper(const String& path, Retained&& bitmap) +{ m_wallpaper_path = path; m_wallpaper = move(bitmap); invalidate(); - return true; } void WSWindowManager::set_resolution(int width, int height) diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 304d902c6b..b3bdd3178f 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -85,7 +85,7 @@ public: void set_resolution(int width, int height); - bool set_wallpaper(const String& path); + bool set_wallpaper(const String& path, Function&& callback); String wallpaper_path() const { return m_wallpaper_path; } const WSCursor& active_cursor() const; @@ -144,6 +144,7 @@ private: void tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow&); void tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow&); void pick_new_active_window(); + void finish_setting_wallpaper(const String& path, Retained&&); WSScreen& m_screen; Rect m_screen_rect;