From 841b2e5d1367b1b5638d13dbed155ec53914e015 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 28 Jul 2019 10:18:49 +0200 Subject: [PATCH] WindowServer+LibGUI: Pass window icons as shared buffers rather than paths. Now that we support more than 2 clients per shared buffer, we can use them for window icons. I didn't do that previously since it would have made the Taskbar process unable to access the icons. This opens up some nice possibilities for programmatically generated icons. --- Applications/FileManager/main.cpp | 3 +- Applications/FontEditor/main.cpp | 3 +- Applications/Piano/main.cpp | 3 +- Applications/ProcessManager/main.cpp | 3 +- Applications/Taskbar/TaskbarWindow.cpp | 17 +++++++++ Applications/Terminal/main.cpp | 3 +- Applications/TextEditor/main.cpp | 3 +- Demos/Fire/Fire.cpp | 3 +- Games/Minesweeper/main.cpp | 3 +- Games/Snake/main.cpp | 3 +- Libraries/LibGUI/GEvent.h | 18 ++++++++++ Libraries/LibGUI/GEventLoop.cpp | 9 +++-- Libraries/LibGUI/GWindow.cpp | 31 ++++++++++++++-- Libraries/LibGUI/GWindow.h | 5 +++ Servers/WindowServer/WSAPITypes.h | 9 +++++ Servers/WindowServer/WSClientConnection.cpp | 32 +++++++++++++++-- Servers/WindowServer/WSClientConnection.h | 1 + Servers/WindowServer/WSEvent.h | 39 +++++++++++++++++++++ Servers/WindowServer/WSWindow.cpp | 17 +++++++++ Servers/WindowServer/WSWindow.h | 2 ++ Servers/WindowServer/WSWindowManager.cpp | 5 ++- 21 files changed, 193 insertions(+), 19 deletions(-) diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index f8403c7e68..8849e6a140 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -1,6 +1,7 @@ #include "DirectoryView.h" #include #include +#include #include #include #include @@ -227,7 +228,7 @@ int main(int argc, char** argv) window->set_main_widget(widget); window->show(); - window->set_icon_path("/res/icons/16x16/filetype-folder.png"); + window->set_icon(load_png("/res/icons/16x16/filetype-folder.png")); return app.exec(); } diff --git a/Applications/FontEditor/main.cpp b/Applications/FontEditor/main.cpp index 58ba0ba563..93f74eee70 100644 --- a/Applications/FontEditor/main.cpp +++ b/Applications/FontEditor/main.cpp @@ -1,4 +1,5 @@ #include "FontEditor.h" +#include #include #include #include @@ -30,6 +31,6 @@ int main(int argc, char** argv) auto* font_editor = new FontEditorWidget(path, move(edited_font)); window->set_main_widget(font_editor); window->show(); - window->set_icon_path("/res/icons/16x16/app-font-editor.png"); + window->set_icon(load_png("/res/icons/16x16/app-font-editor.png")); return app.exec(); } diff --git a/Applications/Piano/main.cpp b/Applications/Piano/main.cpp index 3f20b1a2dc..64790e5421 100644 --- a/Applications/Piano/main.cpp +++ b/Applications/Piano/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ int main(int argc, char** argv) auto* piano_widget = new PianoWidget; window->set_main_widget(piano_widget); window->show(); - window->set_icon_path("/res/icons/16x16/app-piano.png"); + window->set_icon(load_png("/res/icons/16x16/app-piano.png")); CThread sound_thread([](void* context) -> int { auto* piano_widget = (PianoWidget*)context; diff --git a/Applications/ProcessManager/main.cpp b/Applications/ProcessManager/main.cpp index 24c2987d18..895482ad35 100644 --- a/Applications/ProcessManager/main.cpp +++ b/Applications/ProcessManager/main.cpp @@ -3,6 +3,7 @@ #include "ProcessStacksWidget.h" #include "ProcessTableView.h" #include +#include #include #include #include @@ -168,7 +169,7 @@ int main(int argc, char** argv) window->show(); - window->set_icon_path("/res/icons/16x16/app-process-manager.png"); + window->set_icon(load_png("/res/icons/16x16/app-process-manager.png")); return app.exec(); } diff --git a/Applications/Taskbar/TaskbarWindow.cpp b/Applications/Taskbar/TaskbarWindow.cpp index ff1a054d23..5623c7badf 100644 --- a/Applications/Taskbar/TaskbarWindow.cpp +++ b/Applications/Taskbar/TaskbarWindow.cpp @@ -1,5 +1,6 @@ #include "TaskbarWindow.h" #include "TaskbarButton.h" +#include #include #include #include @@ -100,6 +101,22 @@ void TaskbarWindow::wm_event(GWMEvent& event) break; } + case GEvent::WM_WindowIconBitmapChanged: { + auto& changed_event = static_cast(event); +#ifdef EVENT_DEBUG + dbgprintf("WM_WindowIconChanged: client_id=%d, window_id=%d, icon_buffer_id=%d\n", + changed_event.client_id(), + changed_event.window_id(), + changed_event.icon_buffer_id()); +#endif + if (auto* window = WindowList::the().window(identifier)) { + auto buffer = SharedBuffer::create_from_shared_buffer_id(changed_event.icon_buffer_id()); + ASSERT(buffer); + window->button()->set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *buffer, changed_event.icon_size())); + } + break; + } + case GEvent::WM_WindowStateChanged: { auto& changed_event = static_cast(event); #ifdef EVENT_DEBUG diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 3d35caeee6..926a6c2a82 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -1,6 +1,7 @@ #include "Terminal.h" #include #include +#include #include #include #include @@ -154,7 +155,7 @@ int main(int argc, char** argv) window->move_to(300, 300); terminal.apply_size_increments_to_window(*window); window->show(); - window->set_icon_path("/res/icons/16x16/app-terminal.png"); + window->set_icon(load_png("/res/icons/16x16/app-terminal.png")); terminal.set_should_beep(config->read_bool_entry("Window", "AudibleBeep", false)); WeakPtr settings_window; diff --git a/Applications/TextEditor/main.cpp b/Applications/TextEditor/main.cpp index 680399603b..9564b7ca01 100644 --- a/Applications/TextEditor/main.cpp +++ b/Applications/TextEditor/main.cpp @@ -1,4 +1,5 @@ #include "TextEditorWidget.h" +#include int main(int argc, char** argv) { @@ -15,7 +16,7 @@ int main(int argc, char** argv) text_widget->open_sesame(argv[1]); window->show(); - window->set_icon_path("/res/icons/TextEditor16.png"); + window->set_icon(load_png("/res/icons/TextEditor16.png")); return app.exec(); } diff --git a/Demos/Fire/Fire.cpp b/Demos/Fire/Fire.cpp index 13b28ebf1f..92202d75a4 100644 --- a/Demos/Fire/Fire.cpp +++ b/Demos/Fire/Fire.cpp @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -229,7 +230,7 @@ int main(int argc, char** argv) fire->set_stat_label(time); window->show(); - window->set_icon_path("/res/icons/16x16/app-demo.png"); + window->set_icon(load_png("/res/icons/16x16/app-demo.png")); return app.exec(); } diff --git a/Games/Minesweeper/main.cpp b/Games/Minesweeper/main.cpp index a66f53c06d..9ae7c9ca21 100644 --- a/Games/Minesweeper/main.cpp +++ b/Games/Minesweeper/main.cpp @@ -1,5 +1,6 @@ #include "Field.h" #include +#include #include #include #include @@ -93,7 +94,7 @@ int main(int argc, char** argv) window->show(); - window->set_icon_path("/res/icons/minesweeper/mine.png"); + window->set_icon(load_png("/res/icons/minesweeper/mine.png")); return app.exec(); } diff --git a/Games/Snake/main.cpp b/Games/Snake/main.cpp index 0514cf92d7..b4c55f7268 100644 --- a/Games/Snake/main.cpp +++ b/Games/Snake/main.cpp @@ -1,4 +1,5 @@ #include "SnakeGame.h" +#include #include #include #include @@ -45,7 +46,7 @@ int main(int argc, char** argv) window->show(); - window->set_icon_path("/res/icons/16x16/app-snake.png"); + window->set_icon(load_png("/res/icons/16x16/app-snake.png")); return app.exec(); } diff --git a/Libraries/LibGUI/GEvent.h b/Libraries/LibGUI/GEvent.h index 980fb54296..ade04d08a2 100644 --- a/Libraries/LibGUI/GEvent.h +++ b/Libraries/LibGUI/GEvent.h @@ -40,6 +40,7 @@ public: WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconChanged, + WM_WindowIconBitmapChanged, __End_WM_Events, }; @@ -133,6 +134,23 @@ private: String m_icon_path; }; +class GWMWindowIconBitmapChangedEvent : public GWMEvent { +public: + GWMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Size& icon_size) + : GWMEvent(GEvent::Type::WM_WindowIconBitmapChanged, client_id, window_id) + , m_icon_buffer_id(icon_buffer_id) + , m_icon_size(icon_size) + { + } + + int icon_buffer_id() const { return m_icon_buffer_id; } + const Size& icon_size() const { return m_icon_size; } + +private: + int m_icon_buffer_id; + Size m_icon_size; +}; + class GMultiPaintEvent final : public GEvent { public: explicit GMultiPaintEvent(const Vector& rects, const Size& window_size) diff --git a/Libraries/LibGUI/GEventLoop.cpp b/Libraries/LibGUI/GEventLoop.cpp index 97668053f1..458f1ec708 100644 --- a/Libraries/LibGUI/GEventLoop.cpp +++ b/Libraries/LibGUI/GEventLoop.cpp @@ -194,6 +194,8 @@ void GWindowServerConnection::handle_wm_event(const WSAPI_ServerMessage& event, CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, event.wm.rect)); else if (event.type == WSAPI_ServerMessage::WM_WindowIconChanged) CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length))); + else if (event.type == WSAPI_ServerMessage::WM_WindowIconBitmapChanged) + CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, event.wm.icon_buffer_id, event.wm.icon_size)); else if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id)); else @@ -301,12 +303,9 @@ void GWindowServerConnection::postprocess_bundles(Vector& } handle_resize_event(event, *window); break; - case WSAPI_ServerMessage::Type::WM_WindowRemoved: - case WSAPI_ServerMessage::Type::WM_WindowStateChanged: - case WSAPI_ServerMessage::Type::WM_WindowIconChanged: - handle_wm_event(event, *window); - break; default: + if (event.type > WSAPI_ServerMessage::__Begin_WM_Events__ && event.type < WSAPI_ServerMessage::Type::__End_WM_Events__) + handle_wm_event(event, *window); break; } } diff --git a/Libraries/LibGUI/GWindow.cpp b/Libraries/LibGUI/GWindow.cpp index 070fc5d42f..1c36ea90dc 100644 --- a/Libraries/LibGUI/GWindow.cpp +++ b/Libraries/LibGUI/GWindow.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -593,7 +594,7 @@ void GWindow::flip(const Vector& dirty_rects) painter.blit(dirty_rect.location(), *m_front_bitmap, dirty_rect); } -NonnullRefPtr GWindow::create_backing_bitmap(const Size& size) +NonnullRefPtr GWindow::create_shared_bitmap(GraphicsBitmap::Format format, const Size& size) { ASSERT(GWindowServerConnection::the().server_pid()); ASSERT(!size.is_empty()); @@ -602,10 +603,15 @@ NonnullRefPtr GWindow::create_backing_bitmap(const Size& size) auto shared_buffer = SharedBuffer::create_with_size(size_in_bytes); ASSERT(shared_buffer); shared_buffer->share_with(GWindowServerConnection::the().server_pid()); - auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32; return GraphicsBitmap::create_with_shared_buffer(format, *shared_buffer, size); } +NonnullRefPtr GWindow::create_backing_bitmap(const Size& size) +{ + auto format = m_has_alpha_channel ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32; + return create_shared_bitmap(format, size); +} + void GWindow::set_modal(bool modal) { ASSERT(!m_window_id); @@ -616,6 +622,27 @@ void GWindow::wm_event(GWMEvent&) { } +void GWindow::set_icon(const GraphicsBitmap* icon) +{ + if (m_icon == icon) + return; + if (!m_window_id) + return; + + m_icon = create_shared_bitmap(GraphicsBitmap::Format::RGBA32, icon->size()); + { + GPainter painter(*m_icon); + painter.blit({ 0, 0 }, *icon, icon->rect()); + } + + WSAPI_ClientMessage message; + message.type = WSAPI_ClientMessage::Type::SetWindowIconBitmap; + message.window_id = m_window_id; + message.window.icon_buffer_id = m_icon->shared_buffer_id(); + message.window.icon_size = icon->size(); + GWindowServerConnection::the().post_message_to_server(message); +} + void GWindow::set_icon_path(const StringView& path) { if (m_icon_path == path) diff --git a/Libraries/LibGUI/GWindow.h b/Libraries/LibGUI/GWindow.h index a0ec5f8542..827e664011 100644 --- a/Libraries/LibGUI/GWindow.h +++ b/Libraries/LibGUI/GWindow.h @@ -122,6 +122,9 @@ public: String icon_path() const { return m_icon_path; } void set_icon_path(const StringView&); + void set_icon(const GraphicsBitmap*); + const GraphicsBitmap* icon() const { return m_icon.ptr(); } + Vector focusable_widgets() const; protected: @@ -135,11 +138,13 @@ private: void collect_keyboard_activation_targets(); NonnullRefPtr create_backing_bitmap(const Size&); + NonnullRefPtr create_shared_bitmap(GraphicsBitmap::Format, const Size&); void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false); void flip(const Vector& dirty_rects); RefPtr m_front_bitmap; RefPtr m_back_bitmap; + RefPtr m_icon; int m_window_id { 0 }; float m_opacity_when_windowless { 1.0f }; GWidget* m_main_widget { nullptr }; diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 28fe734d6e..526aecadd0 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -111,10 +111,14 @@ struct WSAPI_ServerMessage { DidGetWallpaper, DidSetWindowHasAlphaChannel, ScreenRectChanged, + + __Begin_WM_Events__, WM_WindowRemoved, WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconChanged, + WM_WindowIconBitmapChanged, + __End_WM_Events__, }; Type type { Invalid }; int window_id { -1 }; @@ -145,6 +149,8 @@ struct WSAPI_ServerMessage { bool is_active; bool is_minimized; WSAPI_WindowType window_type; + int icon_buffer_id; + WSAPI_Size icon_size; } wm; struct { WSAPI_Rect rect; @@ -229,6 +235,7 @@ struct WSAPI_ClientMessage { SetWindowIcon, SetWindowHasAlphaChannel, MoveWindowToFront, + SetWindowIconBitmap, }; Type type { Invalid }; int window_id { -1 }; @@ -278,6 +285,8 @@ struct WSAPI_ClientMessage { WSAPI_Size base_size; WSAPI_Size size_increment; WSAPI_Color background_color; + int icon_buffer_id; + WSAPI_Size icon_size; } window; struct { WSAPI_Size size; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 08bce8656a..325cc311c4 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -13,8 +14,8 @@ #include #include #include -#include #include +#include #include #include @@ -145,6 +146,9 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, cons } CEventLoop::current().post_event(*this, make(client_id(), message.window_id, String(message.text, message.text_length))); break; + case WSAPI_ClientMessage::Type::SetWindowIconBitmap: + CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.window.icon_buffer_id, message.window.icon_size)); + break; case WSAPI_ClientMessage::Type::DestroyMenu: CEventLoop::current().post_event(*this, make(client_id(), message.menu.menu_id)); break; @@ -538,7 +542,7 @@ void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&) WSAPI_ServerMessage response; response.type = WSAPI_ServerMessage::Type::DidGetWallpaper; ASSERT(path.length() < (int)sizeof(response.text)); - strncpy(response.text, path.characters(), path.length()); + memcpy(response.text, path.characters(), path.length() + 1); response.text_length = path.length(); post_message(response); } @@ -595,6 +599,28 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); } +void WSClientConnection::handle_request(const WSAPISetWindowIconBitmapRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("WSAPISetWindowIconBitmapRequest: Bad window ID"); + return; + } + auto& window = *(*it).value; + + auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(request.icon_buffer_id()); + + if (!icon_buffer) { + window.set_default_icon(); + } else { + window.set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *icon_buffer, request.icon_size())); + } + + window.frame().invalidate_title_bar(); + WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); +} + void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request) { int window_id = request.window_id(); @@ -946,6 +972,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast(request)); case WSEvent::APISetWindowIconRequest: return handle_request(static_cast(request)); + case WSEvent::APISetWindowIconBitmapRequest: + return handle_request(static_cast(request)); case WSEvent::APISetClipboardContentsRequest: return handle_request(static_cast(request)); case WSEvent::APIGetClipboardContentsRequest: diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index 8038ffe2e4..bf883f7c39 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -55,6 +55,7 @@ private: void handle_request(const WSAPISetWindowRectRequest&); void handle_request(const WSAPIGetWindowRectRequest&); void handle_request(const WSAPISetWindowIconRequest&); + void handle_request(const WSAPISetWindowIconBitmapRequest&); void handle_request(const WSAPISetClipboardContentsRequest&); void handle_request(const WSAPIGetClipboardContentsRequest&); void handle_request(const WSAPICreateWindowRequest&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 4339be917b..6e4a7c1cd2 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -32,6 +32,7 @@ public: WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconChanged, + WM_WindowIconBitmapChanged, __Begin_API_Client_Requests, APICreateMenubarRequest, @@ -50,6 +51,7 @@ public: APISetWindowRectRequest, APIGetWindowRectRequest, APISetWindowIconRequest, + APISetWindowIconBitmapRequest, APIInvalidateRectRequest, APIDidFinishPaintingNotification, APIGetWindowBackingStoreRequest, @@ -588,6 +590,26 @@ private: String m_icon_path; }; +class WSAPISetWindowIconBitmapRequest final : public WSAPIClientRequest { +public: + explicit WSAPISetWindowIconBitmapRequest(int client_id, int window_id, int icon_buffer_id, const Size& icon_size) + : WSAPIClientRequest(WSEvent::APISetWindowIconBitmapRequest, client_id) + , m_window_id(window_id) + , m_icon_buffer_id(icon_buffer_id) + , m_icon_size(icon_size) + { + } + + int window_id() const { return m_window_id; } + int icon_buffer_id() const { return m_icon_buffer_id; } + const Size& icon_size() const { return m_icon_size; } + +private: + int m_window_id { 0 }; + int m_icon_buffer_id { 0 }; + Size m_icon_size; +}; + class WSAPIGetWindowRectRequest final : public WSAPIClientRequest { public: explicit WSAPIGetWindowRectRequest(int client_id, int window_id) @@ -856,6 +878,23 @@ private: String m_icon_path; }; +class WSWMWindowIconBitmapChangedEvent : public WSWMEvent { +public: + WSWMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Size& icon_size) + : WSWMEvent(WSEvent::WM_WindowIconBitmapChanged, client_id, window_id) + , m_icon_buffer_id(icon_buffer_id) + , m_icon_size(icon_size) + { + } + + int icon_buffer_id() const { return m_icon_buffer_id; } + const Size icon_size() const { return m_icon_size; } + +private: + int m_icon_buffer_id; + Size m_icon_size; +}; + class WSWMWindowRectChangedEvent : public WSWMEvent { public: WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 13b4b49b64..50599820b7 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -254,6 +254,23 @@ void WSWindow::event(CEvent& event) break; } + case WSEvent::WM_WindowIconBitmapChanged: { + auto& changed_event = static_cast(event); + server_message.type = WSAPI_ServerMessage::Type::WM_WindowIconBitmapChanged; + server_message.wm.client_id = changed_event.client_id(); + server_message.wm.window_id = changed_event.window_id(); + server_message.wm.icon_buffer_id = changed_event.icon_buffer_id(); + server_message.wm.icon_size = changed_event.icon_size(); + + // FIXME: Perhaps we should update the bitmap sharing list somewhere else instead? + ASSERT(client()); + dbg() << "WindowServer: Sharing icon buffer " << changed_event.icon_buffer_id() << " with PID " << client()->client_pid(); + if (share_buffer_with(changed_event.icon_buffer_id(), client()->client_pid()) < 0) { + ASSERT_NOT_REACHED(); + } + break; + } + case WSEvent::WM_WindowRectChanged: { auto& changed_event = static_cast(event); server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index b8c29aa573..e9ed0c82b9 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -129,6 +129,8 @@ public: void set_base_size(const Size& size) { m_base_size = size; } const GraphicsBitmap& icon() const { return *m_icon; } + void set_icon(NonnullRefPtr&& icon) { m_icon = move(icon); } + String icon_path() const { return m_icon_path; } void set_icon(const String& path, NonnullRefPtr&& icon) { diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index a9abf88c87..b64721da8d 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -319,8 +319,11 @@ void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSW { if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) return; - if (window.client()) + if (window.client()) { CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id(), window.icon_path())); + if (window.icon().shared_buffer_id() != -1) + CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id(), window.icon().shared_buffer_id(), window.icon().size())); + } } void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window)