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:
parent
cff3685a4c
commit
6614746ca8
Notes:
sideshowbarker
2024-07-19 14:34:01 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/6614746ca8a
3 changed files with 39 additions and 11 deletions
|
@ -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&)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue