summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-18 00:39:11 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-18 00:39:11 +0200
commitc931eaa22c0890539867399f161c64abdb85a4b8 (patch)
tree1c5edf3aa8042b12ee810e6d4e63414eeb4d2854
parentc4c7f224d55f3c97b7385f2ce505c9a3d1d02183 (diff)
downloadserenity-c931eaa22c0890539867399f161c64abdb85a4b8.zip
WindowServer: Generate a separate WM event for window icon changes.
-rw-r--r--Applications/Taskbar/TaskbarWindow.cpp31
-rw-r--r--Applications/Taskbar/WindowList.cpp8
-rw-r--r--Applications/Taskbar/WindowList.h1
-rw-r--r--LibGUI/GEvent.h20
-rw-r--r--LibGUI/GEventLoop.cpp5
-rw-r--r--LibGUI/GWindow.cpp2
-rw-r--r--Servers/WindowServer/WSAPITypes.h3
-rw-r--r--Servers/WindowServer/WSClientConnection.cpp2
-rw-r--r--Servers/WindowServer/WSEvent.h20
-rw-r--r--Servers/WindowServer/WSWindow.cpp14
-rw-r--r--Servers/WindowServer/WSWindowManager.cpp11
-rw-r--r--Servers/WindowServer/WSWindowManager.h1
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);