瀏覽代碼

WindowServer: Remove applets from AppletManager on client disconnection

Disconnecting from WindowServer without explicit calls to DestroyWindow
would leave nulled-out WeakPtr's in the AppletManager applet list.

This led to a null dereference when adding a new applet, since we were
assuming the list contained no nulled-out applets.

This patch fixes the issue by always unregistering applet windows from
the AppletManager in ~ClientConnection(). We also do an extra pass of
pruning any nulled-out WeakPtrs from the applet list when adding to it.

Fixes #1551.
Andreas Kling 5 年之前
父節點
當前提交
c56c8c8953
共有 2 個文件被更改,包括 9 次插入1 次删除
  1. 5 0
      Servers/WindowServer/AppletManager.cpp
  2. 4 1
      Servers/WindowServer/ClientConnection.cpp

+ 5 - 0
Servers/WindowServer/AppletManager.cpp

@@ -71,6 +71,11 @@ void AppletManager::add_applet(Window& applet)
 {
     m_applets.append(applet.make_weak_ptr());
 
+    // Prune any dead weak pointers from the applet list.
+    m_applets.remove_all_matching([](auto& entry) {
+        return entry.is_null();
+    });
+
     quick_sort(m_applets, [](auto& a, auto& b) {
         auto index_a = order_vector.find_first_index(a->title());
         auto index_b = order_vector.find_first_index(b->title());

+ 4 - 1
Servers/WindowServer/ClientConnection.cpp

@@ -81,8 +81,11 @@ ClientConnection::~ClientConnection()
 {
     MenuManager::the().close_all_menus_from_client({}, *this);
     auto windows = move(m_windows);
-    for (auto& window : windows)
+    for (auto& window : windows) {
         window.value->detach_client({});
+        if (window.value->type() == WindowType::MenuApplet)
+            AppletManager::the().remove_applet(window.value);
+    }
 }
 
 void ClientConnection::die()