WindowServer: Spawn a secondary thread to decode wallpapers.

The threading API's are not very mature, so this code looks a bit crufty
but it does take the load off the WindowServer main thread when changing
wallpapers. :^)
This commit is contained in:
Andreas Kling 2019-05-01 16:07:47 +02:00
parent cff3685a4c
commit 6614746ca8
Notes: sideshowbarker 2024-07-19 14:34:01 +09:00
3 changed files with 39 additions and 11 deletions

View file

@ -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&)

View file

@ -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<void(bool)>&& callback)
{
auto bitmap = load_png(path);
if (!bitmap)
return false;
struct Context {
String path;
RetainPtr<GraphicsBitmap> bitmap;
Function<void(bool)> callback;
};
auto context = make<Context>();
context->path = path;
context->callback = move(callback);
int rc = create_thread([] (void* ctx) -> int {
OwnPtr<Context> 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<GraphicsBitmap>&& bitmap)
{
m_wallpaper_path = path;
m_wallpaper = move(bitmap);
invalidate();
return true;
}
void WSWindowManager::set_resolution(int width, int height)

View file

@ -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<void(bool)>&& 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<GraphicsBitmap>&&);
WSScreen& m_screen;
Rect m_screen_rect;