mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 16:52:43 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									63619b9f7c
								
							
						
					
					
						commit
						841b2e5d13
					
				
					 21 changed files with 193 additions and 19 deletions
				
			
		|  | @ -1,6 +1,7 @@ | |||
| #include "DirectoryView.h" | ||||
| #include <AK/FileSystemPath.h> | ||||
| #include <LibCore/CUserInfo.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GActionGroup.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "FontEditor.h" | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GWindow.h> | ||||
| #include <stdio.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include <LibAudio/AClientConnection.h> | ||||
| #include <LibCore/CFile.h> | ||||
| #include <LibCore/CThread.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GEventLoop.h> | ||||
|  | @ -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; | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include "ProcessStacksWidget.h" | ||||
| #include "ProcessTableView.h" | ||||
| #include <LibCore/CTimer.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include "TaskbarWindow.h" | ||||
| #include "TaskbarButton.h" | ||||
| #include <LibC/SharedBuffer.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
| #include <LibGUI/GButton.h> | ||||
| #include <LibGUI/GDesktop.h> | ||||
|  | @ -100,6 +101,22 @@ void TaskbarWindow::wm_event(GWMEvent& event) | |||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     case GEvent::WM_WindowIconBitmapChanged: { | ||||
|         auto& changed_event = static_cast<GWMWindowIconBitmapChangedEvent&>(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<GWMWindowStateChangedEvent&>(event); | ||||
| #ifdef EVENT_DEBUG | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include "Terminal.h" | ||||
| #include <Kernel/KeyCode.h> | ||||
| #include <LibCore/CUserInfo.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
|  | @ -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<GWindow> settings_window; | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "TextEditorWidget.h" | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| 
 | ||||
| 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(); | ||||
| } | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| */ | ||||
| 
 | ||||
| #include <LibDraw/GraphicsBitmap.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GLabel.h> | ||||
| #include <LibGUI/GPainter.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include "Field.h" | ||||
| #include <LibCore/CConfigFile.h> | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| #include "SnakeGame.h" | ||||
| #include <LibDraw/PNGLoader.h> | ||||
| #include <LibGUI/GAction.h> | ||||
| #include <LibGUI/GApplication.h> | ||||
| #include <LibGUI/GBoxLayout.h> | ||||
|  | @ -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(); | ||||
| } | ||||
|  |  | |||
|  | @ -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<Rect, 32>& rects, const Size& window_size) | ||||
|  |  | |||
|  | @ -194,6 +194,8 @@ void GWindowServerConnection::handle_wm_event(const WSAPI_ServerMessage& event, | |||
|         CEventLoop::current().post_event(window, make<GWMWindowRectChangedEvent>(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<GWMWindowIconChangedEvent>(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<GWMWindowIconBitmapChangedEvent>(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<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id)); | ||||
|     else | ||||
|  | @ -301,12 +303,9 @@ void GWindowServerConnection::postprocess_bundles(Vector<IncomingMessageBundle>& | |||
|             } | ||||
|             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; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <AK/HashMap.h> | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <LibC/SharedBuffer.h> | ||||
| #include <LibC/stdio.h> | ||||
| #include <LibC/stdlib.h> | ||||
| #include <LibC/unistd.h> | ||||
|  | @ -593,7 +594,7 @@ void GWindow::flip(const Vector<Rect, 32>& dirty_rects) | |||
|         painter.blit(dirty_rect.location(), *m_front_bitmap, dirty_rect); | ||||
| } | ||||
| 
 | ||||
| NonnullRefPtr<GraphicsBitmap> GWindow::create_backing_bitmap(const Size& size) | ||||
| NonnullRefPtr<GraphicsBitmap> GWindow::create_shared_bitmap(GraphicsBitmap::Format format, const Size& size) | ||||
| { | ||||
|     ASSERT(GWindowServerConnection::the().server_pid()); | ||||
|     ASSERT(!size.is_empty()); | ||||
|  | @ -602,10 +603,15 @@ NonnullRefPtr<GraphicsBitmap> 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<GraphicsBitmap> 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) | ||||
|  |  | |||
|  | @ -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<GWidget*> focusable_widgets() const; | ||||
| 
 | ||||
| protected: | ||||
|  | @ -135,11 +138,13 @@ private: | |||
|     void collect_keyboard_activation_targets(); | ||||
| 
 | ||||
|     NonnullRefPtr<GraphicsBitmap> create_backing_bitmap(const Size&); | ||||
|     NonnullRefPtr<GraphicsBitmap> create_shared_bitmap(GraphicsBitmap::Format, const Size&); | ||||
|     void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false); | ||||
|     void flip(const Vector<Rect, 32>& dirty_rects); | ||||
| 
 | ||||
|     RefPtr<GraphicsBitmap> m_front_bitmap; | ||||
|     RefPtr<GraphicsBitmap> m_back_bitmap; | ||||
|     RefPtr<GraphicsBitmap> m_icon; | ||||
|     int m_window_id { 0 }; | ||||
|     float m_opacity_when_windowless { 1.0f }; | ||||
|     GWidget* m_main_widget { nullptr }; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #include <LibC/SharedBuffer.h> | ||||
| #include <SharedBuffer.h> | ||||
| #include <WindowServer/WSAPITypes.h> | ||||
| #include <WindowServer/WSClientConnection.h> | ||||
|  | @ -13,8 +14,8 @@ | |||
| #include <WindowServer/WSWindowSwitcher.h> | ||||
| #include <errno.h> | ||||
| #include <stdio.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/uio.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
|  | @ -145,6 +146,9 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, cons | |||
|         } | ||||
|         CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length))); | ||||
|         break; | ||||
|     case WSAPI_ClientMessage::Type::SetWindowIconBitmap: | ||||
|         CEventLoop::current().post_event(*this, make<WSAPISetWindowIconBitmapRequest>(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<WSAPIDestroyMenuRequest>(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<const WSAPIGetWindowRectRequest&>(request)); | ||||
|     case WSEvent::APISetWindowIconRequest: | ||||
|         return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request)); | ||||
|     case WSEvent::APISetWindowIconBitmapRequest: | ||||
|         return handle_request(static_cast<const WSAPISetWindowIconBitmapRequest&>(request)); | ||||
|     case WSEvent::APISetClipboardContentsRequest: | ||||
|         return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request)); | ||||
|     case WSEvent::APIGetClipboardContentsRequest: | ||||
|  |  | |||
|  | @ -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&); | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -254,6 +254,23 @@ void WSWindow::event(CEvent& event) | |||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     case WSEvent::WM_WindowIconBitmapChanged: { | ||||
|         auto& changed_event = static_cast<const WSWMWindowIconBitmapChangedEvent&>(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<const WSWMWindowRectChangedEvent&>(event); | ||||
|         server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; | ||||
|  |  | |||
|  | @ -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<GraphicsBitmap>&& icon) { m_icon = move(icon); } | ||||
| 
 | ||||
|     String icon_path() const { return m_icon_path; } | ||||
|     void set_icon(const String& path, NonnullRefPtr<GraphicsBitmap>&& icon) | ||||
|     { | ||||
|  |  | |||
|  | @ -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<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); | ||||
|         if (window.icon().shared_buffer_id() != -1) | ||||
|             CEventLoop::current().post_event(listener, make<WSWMWindowIconBitmapChangedEvent>(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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling