diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-04-04 01:44:35 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-04-04 01:44:35 +0200 |
commit | 96104b55249ad0201b1be805e1874c759fdd0ac9 (patch) | |
tree | e56bc509d217f8e618a729b835ebd92b8bb6c16c /Servers | |
parent | ea801a99dcd2f00e048f107e89d29fd07d7f018b (diff) | |
download | serenity-96104b55249ad0201b1be805e1874c759fdd0ac9.zip |
Taskbar: More bringup work. We now see a basic window list.
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 8 | ||||
-rw-r--r-- | Servers/WindowServer/WSMessage.h | 63 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.cpp | 33 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 3 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 26 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.h | 12 |
6 files changed, 144 insertions, 1 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 06bbc56885..209b0f851c 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -91,6 +91,9 @@ struct WSAPI_ServerMessage { DidSetWallpaper, DidGetWallpaper, ScreenRectChanged, + WM_WindowAdded, + WM_WindowRemoved, + WM_WindowStateChanged, }; Type type { Invalid }; int window_id { -1 }; @@ -104,6 +107,11 @@ struct WSAPI_ServerMessage { WSAPI_Rect screen_rect; } greeting; struct { + int client_id; + int window_id; + WSAPI_Rect rect; + } wm; + struct { WSAPI_Rect rect; } screen; struct { diff --git a/Servers/WindowServer/WSMessage.h b/Servers/WindowServer/WSMessage.h index 6b7428169e..5d63a89359 100644 --- a/Servers/WindowServer/WSMessage.h +++ b/Servers/WindowServer/WSMessage.h @@ -26,6 +26,10 @@ public: WindowCloseRequest, WindowResized, + WM_WindowAdded, + WM_WindowRemoved, + WM_WindowStateChanged, + __Begin_API_Client_Requests, APICreateMenubarRequest, APIDestroyMenubarRequest, @@ -581,3 +585,62 @@ private: Rect m_old_rect; Rect m_rect; }; + +class WSWMEvent : public WSMessage { +public: + WSWMEvent(Type type, int client_id, int window_id) + : WSMessage(type) + , m_client_id(client_id) + , m_window_id(window_id) + { + } + + int client_id() const { return m_client_id; } + int window_id() const { return m_window_id; } + +private: + int m_client_id; + int m_window_id; +}; + +class WSWMWindowAddedEvent : public WSWMEvent { +public: + WSWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect) + : WSWMEvent(WSMessage::WM_WindowAdded, client_id, window_id) + , m_title(title) + , m_rect(rect) + { + } + + String title() const { return m_title; } + Rect rect() const { return m_rect; } + +private: + String m_title; + Rect m_rect; +}; + +class WSWMWindowRemovedEvent : public WSWMEvent { +public: + WSWMWindowRemovedEvent(int client_id, int window_id) + : WSWMEvent(WSMessage::WM_WindowRemoved, client_id, window_id) + { + } +}; + +class WSWMWindowStateChangedEvent : public WSWMEvent { +public: + WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect) + : WSWMEvent(WSMessage::WM_WindowStateChanged, client_id, window_id) + , m_title(title) + , m_rect(rect) + { + } + + String title() const { return m_title; } + Rect rect() const { return m_rect; } + +private: + String m_title; + Rect m_rect; +}; diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 778973ce80..b648b2503a 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -28,6 +28,9 @@ WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int win , m_window_id(window_id) , m_icon(default_window_icon()) { + // FIXME: This should not be hard-coded here. + if (m_type == WSWindowType::Taskbar) + m_listens_to_wm_events = true; WSWindowManager::the().add_window(*this); } @@ -138,6 +141,36 @@ void WSWindow::on_message(const WSMessage& message) server_message.window.old_rect = static_cast<const WSResizeEvent&>(message).old_rect(); server_message.window.rect = static_cast<const WSResizeEvent&>(message).rect(); break; + case WSMessage::WM_WindowAdded: { + auto& added_event = static_cast<const WSWMWindowAddedEvent&>(message); + server_message.type = WSAPI_ServerMessage::Type::WM_WindowAdded; + server_message.wm.client_id = added_event.client_id(); + server_message.wm.window_id = added_event.window_id(); + ASSERT(added_event.title().length() < sizeof(server_message.text)); + memcpy(server_message.text, added_event.title().characters(), added_event.title().length()); + server_message.text_length = added_event.title().length(); + server_message.wm.rect = added_event.rect(); + break; + } + case WSMessage::WM_WindowRemoved: { + auto& removed_event = static_cast<const WSWMWindowRemovedEvent&>(message); + server_message.type = WSAPI_ServerMessage::Type::WM_WindowRemoved; + server_message.wm.client_id = removed_event.client_id(); + server_message.wm.window_id = removed_event.window_id(); + break; + } + case WSMessage::WM_WindowStateChanged: { + auto& changed_event = static_cast<const WSWMWindowStateChangedEvent&>(message); + server_message.type = WSAPI_ServerMessage::Type::WM_WindowStateChanged; + server_message.wm.client_id = changed_event.client_id(); + server_message.wm.window_id = changed_event.window_id(); + ASSERT(changed_event.title().length() < sizeof(server_message.text)); + 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(); + break; + } + default: break; } diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index 19cb969992..165c32cef0 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -20,6 +20,8 @@ public: bool is_blocked_by_modal_window() const; + bool listens_to_wm_events() const { return m_listens_to_wm_events; } + WSClientConnection* client() { return m_client; } const WSClientConnection* client() const { return m_client; } @@ -124,6 +126,7 @@ private: bool m_has_painted_since_last_resize { false }; bool m_modal { false }; bool m_resizable { false }; + bool m_listens_to_wm_events { false }; RetainPtr<GraphicsBitmap> m_backing_store; RetainPtr<GraphicsBitmap> m_last_backing_store; int m_window_id { -1 }; diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index 3875e8d591..2400e854af 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -294,7 +294,7 @@ void get_cpu_usage(unsigned& busy, unsigned& idle) FILE* fp = fopen("/proc/all", "r"); if (!fp) { perror("failed to open /proc/all"); - exit(1); + ASSERT_NOT_REACHED(); } for (;;) { char buf[BUFSIZ]; @@ -507,6 +507,12 @@ void WSWindowManager::add_window(WSWindow& window) set_active_window(&window); if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) m_switcher.refresh(); + + for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { + if (window.client()) + WSMessageLoop::the().post_message(listener, make<WSWMWindowAddedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect())); + return IterationDecision::Continue; + }); } void WSWindowManager::move_to_front_and_make_active(WSWindow& window) @@ -534,6 +540,12 @@ void WSWindowManager::remove_window(WSWindow& window) set_active_window(*m_windows.begin()); if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) m_switcher.refresh(); + + for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { + if (window.client()) + WSMessageLoop::the().post_message(listener, make<WSWMWindowRemovedEvent>(window.client()->client_id(), window.window_id())); + return IterationDecision::Continue; + }); } void WSWindowManager::notify_title_changed(WSWindow& window) @@ -542,6 +554,12 @@ void WSWindowManager::notify_title_changed(WSWindow& window) invalidate(outer_window_rect(window)); if (m_switcher.is_visible()) m_switcher.refresh(); + + for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { + if (window.client()) + WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect())); + return IterationDecision::Continue; + }); } void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect, const Rect& new_rect) @@ -553,6 +571,12 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect invalidate(outer_window_rect(new_rect)); if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher) m_switcher.refresh(); + + for_each_window_listening_to_wm_events([&window] (WSWindow& listener) { + if (window.client()) + WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect())); + return IterationDecision::Continue; + }); } void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event) diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 328f2d7f6e..8cc58c7b09 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -112,6 +112,7 @@ private: template<typename Callback> IterationDecision for_each_visible_window_of_type_from_front_to_back(WSWindowType, Callback); template<typename Callback> IterationDecision for_each_visible_window_from_front_to_back(Callback); template<typename Callback> IterationDecision for_each_visible_window_from_back_to_front(Callback); + template<typename Callback> void for_each_window_listening_to_wm_events(Callback); template<typename Callback> void for_each_active_menubar_menu(Callback); void close_current_menu(); virtual void on_message(const WSMessage&) override; @@ -265,3 +266,14 @@ IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Ca return IterationDecision::Abort; return for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback); } + +template<typename Callback> +void WSWindowManager::for_each_window_listening_to_wm_events(Callback callback) +{ + for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) { + if (!window->listens_to_wm_events()) + continue; + if (callback(*window) == IterationDecision::Abort) + return; + } +} |