diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-18 00:39:11 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-18 00:39:11 +0200 |
commit | c931eaa22c0890539867399f161c64abdb85a4b8 (patch) | |
tree | 1c5edf3aa8042b12ee810e6d4e63414eeb4d2854 | |
parent | c4c7f224d55f3c97b7385f2ce505c9a3d1d02183 (diff) | |
download | serenity-c931eaa22c0890539867399f161c64abdb85a4b8.zip |
WindowServer: Generate a separate WM event for window icon changes.
-rw-r--r-- | Applications/Taskbar/TaskbarWindow.cpp | 31 | ||||
-rw-r--r-- | Applications/Taskbar/WindowList.cpp | 8 | ||||
-rw-r--r-- | Applications/Taskbar/WindowList.h | 1 | ||||
-rw-r--r-- | LibGUI/GEvent.h | 20 | ||||
-rw-r--r-- | LibGUI/GEventLoop.cpp | 5 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 3 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.cpp | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSEvent.h | 20 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.cpp | 14 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 11 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.h | 1 |
12 files changed, 95 insertions, 23 deletions
diff --git a/Applications/Taskbar/TaskbarWindow.cpp b/Applications/Taskbar/TaskbarWindow.cpp index ebb7699d9d..deaae2d789 100644 --- a/Applications/Taskbar/TaskbarWindow.cpp +++ b/Applications/Taskbar/TaskbarWindow.cpp @@ -8,6 +8,8 @@ #include <WindowServer/WSAPITypes.h> #include <stdio.h> +//#define EVENT_DEBUG + TaskbarWindow::TaskbarWindow() { set_window_type(GWindowType::Taskbar); @@ -63,26 +65,45 @@ void TaskbarWindow::wm_event(GWMEvent& event) WindowIdentifier identifier { event.client_id(), event.window_id() }; switch (event.type()) { case GEvent::WM_WindowRemoved: { +#ifdef EVENT_DEBUG auto& removed_event = static_cast<GWMWindowRemovedEvent&>(event); - printf("WM_WindowRemoved: client_id=%d, window_id=%d\n", + dbgprintf("WM_WindowRemoved: client_id=%d, window_id=%d\n", removed_event.client_id(), removed_event.window_id() ); +#endif m_window_list.remove_window(identifier); update(); break; } + case GEvent::WM_WindowIconChanged: { + auto& changed_event = static_cast<GWMWindowIconChangedEvent&>(event); +#ifdef EVENT_DEBUG + dbgprintf("WM_WindowIconChanged: client_id=%d, window_id=%d, icon_path=%s\n", + changed_event.client_id(), + changed_event.window_id(), + changed_event.icon_path().characters() + ); +#endif + if (auto* window = m_window_list.window(identifier)) { + window->set_icon_path(changed_event.icon_path()); + window->button()->set_icon(window->icon()); + } + break; + } + case GEvent::WM_WindowStateChanged: { auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event); - printf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s, is_active=%u, is_minimized=%u, icon_path=%s\n", +#ifdef EVENT_DEBUG + dbgprintf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s, is_active=%u, is_minimized=%u\n", changed_event.client_id(), changed_event.window_id(), changed_event.title().characters(), changed_event.rect().to_string().characters(), changed_event.is_active(), - changed_event.is_minimized(), - changed_event.icon_path().characters() + changed_event.is_minimized() ); +#endif if (!should_include_window(changed_event.window_type())) break; auto& window = m_window_list.ensure_window(identifier); @@ -90,7 +111,6 @@ void TaskbarWindow::wm_event(GWMEvent& event) window.set_rect(changed_event.rect()); window.set_active(changed_event.is_active()); window.set_minimized(changed_event.is_minimized()); - window.set_icon_path(changed_event.icon_path()); if (window.is_minimized()) { window.button()->set_foreground_color(Color::DarkGray); window.button()->set_caption(String::format("[%s]", changed_event.title().characters())); @@ -98,7 +118,6 @@ void TaskbarWindow::wm_event(GWMEvent& event) window.button()->set_foreground_color(Color::Black); window.button()->set_caption(changed_event.title()); } - window.button()->set_icon(window.icon()); window.button()->set_checked(changed_event.is_active()); break; } diff --git a/Applications/Taskbar/WindowList.cpp b/Applications/Taskbar/WindowList.cpp index 2c8be5806f..c149853ea3 100644 --- a/Applications/Taskbar/WindowList.cpp +++ b/Applications/Taskbar/WindowList.cpp @@ -2,6 +2,14 @@ #include <WindowServer/WSAPITypes.h> #include <LibGUI/GEventLoop.h> +Window* WindowList::window(const WindowIdentifier& identifier) +{ + auto it = m_windows.find(identifier); + if (it != m_windows.end()) + return it->value; + return nullptr; +} + Window& WindowList::ensure_window(const WindowIdentifier& identifier) { auto it = m_windows.find(identifier); diff --git a/Applications/Taskbar/WindowList.h b/Applications/Taskbar/WindowList.h index 3b5b0d9d41..458222c5b8 100644 --- a/Applications/Taskbar/WindowList.h +++ b/Applications/Taskbar/WindowList.h @@ -96,6 +96,7 @@ public: callback(*it.value); } + Window* window(const WindowIdentifier&); Window& ensure_window(const WindowIdentifier&); void remove_window(const WindowIdentifier&); diff --git a/LibGUI/GEvent.h b/LibGUI/GEvent.h index 1a95331aab..cc0cd8aee2 100644 --- a/LibGUI/GEvent.h +++ b/LibGUI/GEvent.h @@ -31,6 +31,7 @@ public: WindowCloseRequest, WM_WindowRemoved, WM_WindowStateChanged, + WM_WindowIconChanged, }; GEvent() { } @@ -69,10 +70,9 @@ public: class GWMWindowStateChangedEvent : public GWMEvent { public: - GWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active, GWindowType window_type, bool is_minimized, const String& icon_path) + GWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active, GWindowType window_type, bool is_minimized) : GWMEvent(GEvent::Type::WM_WindowStateChanged, client_id, window_id) , m_title(title) - , m_icon_path(icon_path) , m_rect(rect) , m_window_type(window_type) , m_active(is_active) @@ -85,17 +85,29 @@ public: bool is_active() const { return m_active; } GWindowType window_type() const { return m_window_type; } bool is_minimized() const { return m_minimized; } - String icon_path() const { return m_icon_path; } private: String m_title; - String m_icon_path; Rect m_rect; GWindowType m_window_type; bool m_active; bool m_minimized; }; +class GWMWindowIconChangedEvent : public GWMEvent { +public: + GWMWindowIconChangedEvent(int client_id, int window_id, const String& icon_path) + : GWMEvent(GEvent::Type::WM_WindowIconChanged, client_id, window_id) + , m_icon_path(icon_path) + { + } + + String icon_path() const { return m_icon_path; } + +private: + String m_icon_path; +}; + class GPaintEvent final : public GEvent { public: explicit GPaintEvent(const Rect& rect, const Size& window_size = Size()) diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp index 895bf0a77c..b14c621e91 100644 --- a/LibGUI/GEventLoop.cpp +++ b/LibGUI/GEventLoop.cpp @@ -174,7 +174,9 @@ void GEventLoop::handle_wm_event(const WSAPI_ServerMessage& event, GWindow& wind dbgprintf("GEventLoop: handle_wm_event: %d\n", (int)event.type); #endif if (event.type == WSAPI_ServerMessage::WM_WindowStateChanged) - return post_event(window, make<GWMWindowStateChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect, event.wm.is_active, (GWindowType)event.wm.window_type, event.wm.is_minimized, String(event.wm.icon_path, event.wm.icon_path_length))); + return post_event(window, make<GWMWindowStateChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect, event.wm.is_active, (GWindowType)event.wm.window_type, event.wm.is_minimized)); + if (event.type == WSAPI_ServerMessage::WM_WindowIconChanged) + return post_event(window, make<GWMWindowIconChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length))); if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) return post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id)); ASSERT_NOT_REACHED(); @@ -277,6 +279,7 @@ void GEventLoop::process_unprocessed_messages() 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: diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index 5e294ffc25..31f9c33e8f 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -277,7 +277,7 @@ void GWindow::event(CEvent& event) return; } - if (event.type() == GEvent::WM_WindowRemoved || event.type() == GEvent::WM_WindowStateChanged) + if (event.type() == GEvent::WM_WindowRemoved || event.type() == GEvent::WM_WindowStateChanged || event.type() == GEvent::WM_WindowIconChanged) return wm_event(static_cast<GWMEvent&>(event)); CObject::event(event); diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index c7c7dc6345..c7377d3e00 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -97,6 +97,7 @@ struct WSAPI_ServerMessage { ScreenRectChanged, WM_WindowRemoved, WM_WindowStateChanged, + WM_WindowIconChanged, }; Type type { Invalid }; int window_id { -1 }; @@ -116,8 +117,6 @@ struct WSAPI_ServerMessage { bool is_active; bool is_minimized; WSAPI_WindowType window_type; - int icon_path_length; - char icon_path[256]; } wm; struct { WSAPI_Rect rect; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index e2bf5d3816..c081765fde 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -370,7 +370,7 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request } window.frame().invalidate_title_bar(); - WSWindowManager::the().tell_wm_listeners_window_state_changed(window); + WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); } void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request) diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 3d635bdadc..4c9d85f5bf 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -29,6 +29,7 @@ public: WM_WindowRemoved, WM_WindowStateChanged, + WM_WindowIconChanged, __Begin_API_Client_Requests, APICreateMenubarRequest, @@ -712,10 +713,9 @@ public: class WSWMWindowStateChangedEvent : public WSWMEvent { public: - WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active, WSWindowType window_type, bool is_minimized, const String& icon_path) + WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect, bool is_active, WSWindowType window_type, bool is_minimized) : WSWMEvent(WSEvent::WM_WindowStateChanged, client_id, window_id) , m_title(title) - , m_icon_path(icon_path) , m_rect(rect) , m_active(is_active) , m_window_type(window_type) @@ -724,7 +724,6 @@ public: } String title() const { return m_title; } - String icon_path() const { return m_icon_path; } Rect rect() const { return m_rect; } bool is_active() const { return m_active; } WSWindowType window_type() const { return m_window_type; } @@ -732,9 +731,22 @@ public: private: String m_title; - String m_icon_path; Rect m_rect; bool m_active; WSWindowType m_window_type; bool m_minimized; }; + +class WSWMWindowIconChangedEvent : public WSWMEvent { +public: + WSWMWindowIconChangedEvent(int client_id, int window_id, const String& icon_path) + : WSWMEvent(WSEvent::WM_WindowIconChanged, client_id, window_id) + , m_icon_path(icon_path) + { + } + + String icon_path() const { return m_icon_path; } + +private: + String m_icon_path; +}; diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index b608b64d00..b8f3df4ca8 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -196,9 +196,17 @@ void WSWindow::event(CEvent& event) memcpy(server_message.text, changed_event.title().characters(), changed_event.title().length()); server_message.text_length = changed_event.title().length(); server_message.wm.rect = changed_event.rect(); - ASSERT(changed_event.icon_path().length() < sizeof(server_message.wm.icon_path)); - memcpy(server_message.wm.icon_path, changed_event.icon_path().characters(), changed_event.icon_path().length()); - server_message.wm.icon_path_length = changed_event.icon_path().length(); + break; + } + + case WSEvent::WM_WindowIconChanged: { + auto& changed_event = static_cast<const WSWMWindowIconChangedEvent&>(event); + server_message.type = WSAPI_ServerMessage::Type::WM_WindowIconChanged; + server_message.wm.client_id = changed_event.client_id(); + server_message.wm.window_id = changed_event.window_id(); + ASSERT(changed_event.icon_path().length() < sizeof(server_message.text)); + memcpy(server_message.text, changed_event.icon_path().characters(), changed_event.icon_path().length()); + server_message.text_length = changed_event.icon_path().length(); break; } diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 8824d3c295..83dda7889e 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -318,7 +318,7 @@ void WSWindowManager::remove_window(WSWindow& window) void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow& window) { if (window.client()) - WSEventLoop::the().post_event(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active(), window.type(), window.is_minimized(), window.icon_path())); + WSEventLoop::the().post_event(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active(), window.type(), window.is_minimized())); } void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window) @@ -329,6 +329,15 @@ void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window) }); } +void WSWindowManager::tell_wm_listeners_window_icon_changed(WSWindow& window) +{ + for_each_window_listening_to_wm_events([&] (WSWindow& listener) { + if (window.client()) + WSEventLoop::the().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); + return IterationDecision::Continue; + }); +} + void WSWindowManager::notify_title_changed(WSWindow& window) { dbgprintf("[WM] WSWindow{%p} title set to '%s'\n", &window, window.title().characters()); diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index c2d875637b..27c044abf6 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -111,6 +111,7 @@ public: bool any_opaque_window_above_this_one_contains_rect(const WSWindow&, const Rect&); void tell_wm_listeners_window_state_changed(WSWindow&); + void tell_wm_listeners_window_icon_changed(WSWindow&); private: void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window); |