Преглед на файлове

WindowServer: Generate a separate WM event for window icon changes.

Andreas Kling преди 6 години
родител
ревизия
c931eaa22c

+ 25 - 6
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;
     }

+ 8 - 0
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);

+ 1 - 0
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&);
 

+ 16 - 4
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())

+ 4 - 1
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:

+ 1 - 1
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);

+ 1 - 2
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;

+ 1 - 1
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)

+ 16 - 4
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;
+};

+ 11 - 3
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;
     }
 

+ 10 - 1
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());

+ 1 - 0
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);