summaryrefslogtreecommitdiff
path: root/Servers
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-04 01:44:35 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-04 01:44:35 +0200
commit96104b55249ad0201b1be805e1874c759fdd0ac9 (patch)
treee56bc509d217f8e618a729b835ebd92b8bb6c16c /Servers
parentea801a99dcd2f00e048f107e89d29fd07d7f018b (diff)
downloadserenity-96104b55249ad0201b1be805e1874c759fdd0ac9.zip
Taskbar: More bringup work. We now see a basic window list.
Diffstat (limited to 'Servers')
-rw-r--r--Servers/WindowServer/WSAPITypes.h8
-rw-r--r--Servers/WindowServer/WSMessage.h63
-rw-r--r--Servers/WindowServer/WSWindow.cpp33
-rw-r--r--Servers/WindowServer/WSWindow.h3
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp26
-rw-r--r--Servers/WindowServer/WSWindowManager.h12
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;
+ }
+}