mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 11:22:45 +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 "DirectoryView.h" | ||||||
| #include <AK/FileSystemPath.h> | #include <AK/FileSystemPath.h> | ||||||
| #include <LibCore/CUserInfo.h> | #include <LibCore/CUserInfo.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GActionGroup.h> | #include <LibGUI/GActionGroup.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
|  | @ -227,7 +228,7 @@ int main(int argc, char** argv) | ||||||
|     window->set_main_widget(widget); |     window->set_main_widget(widget); | ||||||
|     window->show(); |     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(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include "FontEditor.h" | #include "FontEditor.h" | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GWindow.h> | #include <LibGUI/GWindow.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | @ -30,6 +31,6 @@ int main(int argc, char** argv) | ||||||
|     auto* font_editor = new FontEditorWidget(path, move(edited_font)); |     auto* font_editor = new FontEditorWidget(path, move(edited_font)); | ||||||
|     window->set_main_widget(font_editor); |     window->set_main_widget(font_editor); | ||||||
|     window->show(); |     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(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include <LibAudio/AClientConnection.h> | #include <LibAudio/AClientConnection.h> | ||||||
| #include <LibCore/CFile.h> | #include <LibCore/CFile.h> | ||||||
| #include <LibCore/CThread.h> | #include <LibCore/CThread.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GEventLoop.h> | #include <LibGUI/GEventLoop.h> | ||||||
|  | @ -23,7 +24,7 @@ int main(int argc, char** argv) | ||||||
|     auto* piano_widget = new PianoWidget; |     auto* piano_widget = new PianoWidget; | ||||||
|     window->set_main_widget(piano_widget); |     window->set_main_widget(piano_widget); | ||||||
|     window->show(); |     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 { |     CThread sound_thread([](void* context) -> int { | ||||||
|         auto* piano_widget = (PianoWidget*)context; |         auto* piano_widget = (PianoWidget*)context; | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| #include "ProcessStacksWidget.h" | #include "ProcessStacksWidget.h" | ||||||
| #include "ProcessTableView.h" | #include "ProcessTableView.h" | ||||||
| #include <LibCore/CTimer.h> | #include <LibCore/CTimer.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GBoxLayout.h> | #include <LibGUI/GBoxLayout.h> | ||||||
|  | @ -168,7 +169,7 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
|     window->show(); |     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(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include "TaskbarWindow.h" | #include "TaskbarWindow.h" | ||||||
| #include "TaskbarButton.h" | #include "TaskbarButton.h" | ||||||
|  | #include <LibC/SharedBuffer.h> | ||||||
| #include <LibGUI/GBoxLayout.h> | #include <LibGUI/GBoxLayout.h> | ||||||
| #include <LibGUI/GButton.h> | #include <LibGUI/GButton.h> | ||||||
| #include <LibGUI/GDesktop.h> | #include <LibGUI/GDesktop.h> | ||||||
|  | @ -100,6 +101,22 @@ void TaskbarWindow::wm_event(GWMEvent& event) | ||||||
|         break; |         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: { |     case GEvent::WM_WindowStateChanged: { | ||||||
|         auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event); |         auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event); | ||||||
| #ifdef EVENT_DEBUG | #ifdef EVENT_DEBUG | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| #include "Terminal.h" | #include "Terminal.h" | ||||||
| #include <Kernel/KeyCode.h> | #include <Kernel/KeyCode.h> | ||||||
| #include <LibCore/CUserInfo.h> | #include <LibCore/CUserInfo.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GBoxLayout.h> | #include <LibGUI/GBoxLayout.h> | ||||||
|  | @ -154,7 +155,7 @@ int main(int argc, char** argv) | ||||||
|     window->move_to(300, 300); |     window->move_to(300, 300); | ||||||
|     terminal.apply_size_increments_to_window(*window); |     terminal.apply_size_increments_to_window(*window); | ||||||
|     window->show(); |     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)); |     terminal.set_should_beep(config->read_bool_entry("Window", "AudibleBeep", false)); | ||||||
| 
 | 
 | ||||||
|     WeakPtr<GWindow> settings_window; |     WeakPtr<GWindow> settings_window; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include "TextEditorWidget.h" | #include "TextEditorWidget.h" | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| 
 | 
 | ||||||
| int main(int argc, char** argv) | int main(int argc, char** argv) | ||||||
| { | { | ||||||
|  | @ -15,7 +16,7 @@ int main(int argc, char** argv) | ||||||
|         text_widget->open_sesame(argv[1]); |         text_widget->open_sesame(argv[1]); | ||||||
| 
 | 
 | ||||||
|     window->show(); |     window->show(); | ||||||
|     window->set_icon_path("/res/icons/TextEditor16.png"); |     window->set_icon(load_png("/res/icons/TextEditor16.png")); | ||||||
| 
 | 
 | ||||||
|     return app.exec(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #include <LibDraw/GraphicsBitmap.h> | #include <LibDraw/GraphicsBitmap.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GLabel.h> | #include <LibGUI/GLabel.h> | ||||||
| #include <LibGUI/GPainter.h> | #include <LibGUI/GPainter.h> | ||||||
|  | @ -229,7 +230,7 @@ int main(int argc, char** argv) | ||||||
|     fire->set_stat_label(time); |     fire->set_stat_label(time); | ||||||
| 
 | 
 | ||||||
|     window->show(); |     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(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include "Field.h" | #include "Field.h" | ||||||
| #include <LibCore/CConfigFile.h> | #include <LibCore/CConfigFile.h> | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GBoxLayout.h> | #include <LibGUI/GBoxLayout.h> | ||||||
|  | @ -93,7 +94,7 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
|     window->show(); |     window->show(); | ||||||
| 
 | 
 | ||||||
|     window->set_icon_path("/res/icons/minesweeper/mine.png"); |     window->set_icon(load_png("/res/icons/minesweeper/mine.png")); | ||||||
| 
 | 
 | ||||||
|     return app.exec(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #include "SnakeGame.h" | #include "SnakeGame.h" | ||||||
|  | #include <LibDraw/PNGLoader.h> | ||||||
| #include <LibGUI/GAction.h> | #include <LibGUI/GAction.h> | ||||||
| #include <LibGUI/GApplication.h> | #include <LibGUI/GApplication.h> | ||||||
| #include <LibGUI/GBoxLayout.h> | #include <LibGUI/GBoxLayout.h> | ||||||
|  | @ -45,7 +46,7 @@ int main(int argc, char** argv) | ||||||
| 
 | 
 | ||||||
|     window->show(); |     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(); |     return app.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -40,6 +40,7 @@ public: | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|         WM_WindowRectChanged, |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
|  |         WM_WindowIconBitmapChanged, | ||||||
|         __End_WM_Events, |         __End_WM_Events, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -133,6 +134,23 @@ private: | ||||||
|     String m_icon_path; |     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 { | class GMultiPaintEvent final : public GEvent { | ||||||
| public: | public: | ||||||
|     explicit GMultiPaintEvent(const Vector<Rect, 32>& rects, const Size& window_size) |     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)); |         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) |     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))); |         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) |     else if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) | ||||||
|         CEventLoop::current().post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id)); |         CEventLoop::current().post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id)); | ||||||
|     else |     else | ||||||
|  | @ -301,12 +303,9 @@ void GWindowServerConnection::postprocess_bundles(Vector<IncomingMessageBundle>& | ||||||
|             } |             } | ||||||
|             handle_resize_event(event, *window); |             handle_resize_event(event, *window); | ||||||
|             break; |             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: |         default: | ||||||
|  |             if (event.type > WSAPI_ServerMessage::__Begin_WM_Events__ && event.type < WSAPI_ServerMessage::Type::__End_WM_Events__) | ||||||
|  |                 handle_wm_event(event, *window); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <AK/HashMap.h> | #include <AK/HashMap.h> | ||||||
| #include <AK/StringBuilder.h> | #include <AK/StringBuilder.h> | ||||||
|  | #include <LibC/SharedBuffer.h> | ||||||
| #include <LibC/stdio.h> | #include <LibC/stdio.h> | ||||||
| #include <LibC/stdlib.h> | #include <LibC/stdlib.h> | ||||||
| #include <LibC/unistd.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); |         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(GWindowServerConnection::the().server_pid()); | ||||||
|     ASSERT(!size.is_empty()); |     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); |     auto shared_buffer = SharedBuffer::create_with_size(size_in_bytes); | ||||||
|     ASSERT(shared_buffer); |     ASSERT(shared_buffer); | ||||||
|     shared_buffer->share_with(GWindowServerConnection::the().server_pid()); |     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); |     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) | void GWindow::set_modal(bool modal) | ||||||
| { | { | ||||||
|     ASSERT(!m_window_id); |     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) | void GWindow::set_icon_path(const StringView& path) | ||||||
| { | { | ||||||
|     if (m_icon_path == path) |     if (m_icon_path == path) | ||||||
|  |  | ||||||
|  | @ -122,6 +122,9 @@ public: | ||||||
|     String icon_path() const { return m_icon_path; } |     String icon_path() const { return m_icon_path; } | ||||||
|     void set_icon_path(const StringView&); |     void set_icon_path(const StringView&); | ||||||
| 
 | 
 | ||||||
|  |     void set_icon(const GraphicsBitmap*); | ||||||
|  |     const GraphicsBitmap* icon() const { return m_icon.ptr(); } | ||||||
|  | 
 | ||||||
|     Vector<GWidget*> focusable_widgets() const; |     Vector<GWidget*> focusable_widgets() const; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  | @ -135,11 +138,13 @@ private: | ||||||
|     void collect_keyboard_activation_targets(); |     void collect_keyboard_activation_targets(); | ||||||
| 
 | 
 | ||||||
|     NonnullRefPtr<GraphicsBitmap> create_backing_bitmap(const Size&); |     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 set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false); | ||||||
|     void flip(const Vector<Rect, 32>& dirty_rects); |     void flip(const Vector<Rect, 32>& dirty_rects); | ||||||
| 
 | 
 | ||||||
|     RefPtr<GraphicsBitmap> m_front_bitmap; |     RefPtr<GraphicsBitmap> m_front_bitmap; | ||||||
|     RefPtr<GraphicsBitmap> m_back_bitmap; |     RefPtr<GraphicsBitmap> m_back_bitmap; | ||||||
|  |     RefPtr<GraphicsBitmap> m_icon; | ||||||
|     int m_window_id { 0 }; |     int m_window_id { 0 }; | ||||||
|     float m_opacity_when_windowless { 1.0f }; |     float m_opacity_when_windowless { 1.0f }; | ||||||
|     GWidget* m_main_widget { nullptr }; |     GWidget* m_main_widget { nullptr }; | ||||||
|  |  | ||||||
|  | @ -111,10 +111,14 @@ struct WSAPI_ServerMessage { | ||||||
|         DidGetWallpaper, |         DidGetWallpaper, | ||||||
|         DidSetWindowHasAlphaChannel, |         DidSetWindowHasAlphaChannel, | ||||||
|         ScreenRectChanged, |         ScreenRectChanged, | ||||||
|  | 
 | ||||||
|  |         __Begin_WM_Events__, | ||||||
|         WM_WindowRemoved, |         WM_WindowRemoved, | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|         WM_WindowRectChanged, |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
|  |         WM_WindowIconBitmapChanged, | ||||||
|  |         __End_WM_Events__, | ||||||
|     }; |     }; | ||||||
|     Type type { Invalid }; |     Type type { Invalid }; | ||||||
|     int window_id { -1 }; |     int window_id { -1 }; | ||||||
|  | @ -145,6 +149,8 @@ struct WSAPI_ServerMessage { | ||||||
|             bool is_active; |             bool is_active; | ||||||
|             bool is_minimized; |             bool is_minimized; | ||||||
|             WSAPI_WindowType window_type; |             WSAPI_WindowType window_type; | ||||||
|  |             int icon_buffer_id; | ||||||
|  |             WSAPI_Size icon_size; | ||||||
|         } wm; |         } wm; | ||||||
|         struct { |         struct { | ||||||
|             WSAPI_Rect rect; |             WSAPI_Rect rect; | ||||||
|  | @ -229,6 +235,7 @@ struct WSAPI_ClientMessage { | ||||||
|         SetWindowIcon, |         SetWindowIcon, | ||||||
|         SetWindowHasAlphaChannel, |         SetWindowHasAlphaChannel, | ||||||
|         MoveWindowToFront, |         MoveWindowToFront, | ||||||
|  |         SetWindowIconBitmap, | ||||||
|     }; |     }; | ||||||
|     Type type { Invalid }; |     Type type { Invalid }; | ||||||
|     int window_id { -1 }; |     int window_id { -1 }; | ||||||
|  | @ -278,6 +285,8 @@ struct WSAPI_ClientMessage { | ||||||
|             WSAPI_Size base_size; |             WSAPI_Size base_size; | ||||||
|             WSAPI_Size size_increment; |             WSAPI_Size size_increment; | ||||||
|             WSAPI_Color background_color; |             WSAPI_Color background_color; | ||||||
|  |             int icon_buffer_id; | ||||||
|  |             WSAPI_Size icon_size; | ||||||
|         } window; |         } window; | ||||||
|         struct { |         struct { | ||||||
|             WSAPI_Size size; |             WSAPI_Size size; | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | #include <LibC/SharedBuffer.h> | ||||||
| #include <SharedBuffer.h> | #include <SharedBuffer.h> | ||||||
| #include <WindowServer/WSAPITypes.h> | #include <WindowServer/WSAPITypes.h> | ||||||
| #include <WindowServer/WSClientConnection.h> | #include <WindowServer/WSClientConnection.h> | ||||||
|  | @ -13,8 +14,8 @@ | ||||||
| #include <WindowServer/WSWindowSwitcher.h> | #include <WindowServer/WSWindowSwitcher.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <sys/socket.h> |  | ||||||
| #include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||||
|  | #include <sys/socket.h> | ||||||
| #include <sys/uio.h> | #include <sys/uio.h> | ||||||
| #include <unistd.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))); |         CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length))); | ||||||
|         break; |         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: |     case WSAPI_ClientMessage::Type::DestroyMenu: | ||||||
|         CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id)); |         CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id)); | ||||||
|         break; |         break; | ||||||
|  | @ -538,7 +542,7 @@ void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&) | ||||||
|     WSAPI_ServerMessage response; |     WSAPI_ServerMessage response; | ||||||
|     response.type = WSAPI_ServerMessage::Type::DidGetWallpaper; |     response.type = WSAPI_ServerMessage::Type::DidGetWallpaper; | ||||||
|     ASSERT(path.length() < (int)sizeof(response.text)); |     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(); |     response.text_length = path.length(); | ||||||
|     post_message(response); |     post_message(response); | ||||||
| } | } | ||||||
|  | @ -595,6 +599,28 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request | ||||||
|     WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); |     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) | void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request) | ||||||
| { | { | ||||||
|     int window_id = request.window_id(); |     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)); |         return handle_request(static_cast<const WSAPIGetWindowRectRequest&>(request)); | ||||||
|     case WSEvent::APISetWindowIconRequest: |     case WSEvent::APISetWindowIconRequest: | ||||||
|         return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request)); |         return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request)); | ||||||
|  |     case WSEvent::APISetWindowIconBitmapRequest: | ||||||
|  |         return handle_request(static_cast<const WSAPISetWindowIconBitmapRequest&>(request)); | ||||||
|     case WSEvent::APISetClipboardContentsRequest: |     case WSEvent::APISetClipboardContentsRequest: | ||||||
|         return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request)); |         return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request)); | ||||||
|     case WSEvent::APIGetClipboardContentsRequest: |     case WSEvent::APIGetClipboardContentsRequest: | ||||||
|  |  | ||||||
|  | @ -55,6 +55,7 @@ private: | ||||||
|     void handle_request(const WSAPISetWindowRectRequest&); |     void handle_request(const WSAPISetWindowRectRequest&); | ||||||
|     void handle_request(const WSAPIGetWindowRectRequest&); |     void handle_request(const WSAPIGetWindowRectRequest&); | ||||||
|     void handle_request(const WSAPISetWindowIconRequest&); |     void handle_request(const WSAPISetWindowIconRequest&); | ||||||
|  |     void handle_request(const WSAPISetWindowIconBitmapRequest&); | ||||||
|     void handle_request(const WSAPISetClipboardContentsRequest&); |     void handle_request(const WSAPISetClipboardContentsRequest&); | ||||||
|     void handle_request(const WSAPIGetClipboardContentsRequest&); |     void handle_request(const WSAPIGetClipboardContentsRequest&); | ||||||
|     void handle_request(const WSAPICreateWindowRequest&); |     void handle_request(const WSAPICreateWindowRequest&); | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ public: | ||||||
|         WM_WindowStateChanged, |         WM_WindowStateChanged, | ||||||
|         WM_WindowRectChanged, |         WM_WindowRectChanged, | ||||||
|         WM_WindowIconChanged, |         WM_WindowIconChanged, | ||||||
|  |         WM_WindowIconBitmapChanged, | ||||||
| 
 | 
 | ||||||
|         __Begin_API_Client_Requests, |         __Begin_API_Client_Requests, | ||||||
|         APICreateMenubarRequest, |         APICreateMenubarRequest, | ||||||
|  | @ -50,6 +51,7 @@ public: | ||||||
|         APISetWindowRectRequest, |         APISetWindowRectRequest, | ||||||
|         APIGetWindowRectRequest, |         APIGetWindowRectRequest, | ||||||
|         APISetWindowIconRequest, |         APISetWindowIconRequest, | ||||||
|  |         APISetWindowIconBitmapRequest, | ||||||
|         APIInvalidateRectRequest, |         APIInvalidateRectRequest, | ||||||
|         APIDidFinishPaintingNotification, |         APIDidFinishPaintingNotification, | ||||||
|         APIGetWindowBackingStoreRequest, |         APIGetWindowBackingStoreRequest, | ||||||
|  | @ -588,6 +590,26 @@ private: | ||||||
|     String m_icon_path; |     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 { | class WSAPIGetWindowRectRequest final : public WSAPIClientRequest { | ||||||
| public: | public: | ||||||
|     explicit WSAPIGetWindowRectRequest(int client_id, int window_id) |     explicit WSAPIGetWindowRectRequest(int client_id, int window_id) | ||||||
|  | @ -856,6 +878,23 @@ private: | ||||||
|     String m_icon_path; |     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 { | class WSWMWindowRectChangedEvent : public WSWMEvent { | ||||||
| public: | public: | ||||||
|     WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) |     WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) | ||||||
|  |  | ||||||
|  | @ -254,6 +254,23 @@ void WSWindow::event(CEvent& event) | ||||||
|         break; |         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: { |     case WSEvent::WM_WindowRectChanged: { | ||||||
|         auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event); |         auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event); | ||||||
|         server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; |         server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; | ||||||
|  |  | ||||||
|  | @ -129,6 +129,8 @@ public: | ||||||
|     void set_base_size(const Size& size) { m_base_size = size; } |     void set_base_size(const Size& size) { m_base_size = size; } | ||||||
| 
 | 
 | ||||||
|     const GraphicsBitmap& icon() const { return *m_icon; } |     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; } |     String icon_path() const { return m_icon_path; } | ||||||
|     void set_icon(const String& path, NonnullRefPtr<GraphicsBitmap>&& icon) |     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)) |     if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) | ||||||
|         return; |         return; | ||||||
|     if (window.client()) |     if (window.client()) { | ||||||
|         CEventLoop::current().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); |         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) | 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