[plasma/spectacle] src/Platforms: Fix crash when window is destroyed during window-under-pointer detection

Noah Davis <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 93944711441c5d478e278f60eff659172f94b287 by Noah Davis, on behalf of Pranav Kunjir.
Committed on 03/08/2026 at 15:48.
Pushed by ndavis into branch 'master'.

Fix crash when window is destroyed during window-under-pointer detection

xcb_get_property_reply(), xcb_query_tree_reply(), xcb_intern_atom_reply(), and xcb_query_pointer_reply() can all return null if the target window is destroyed between the request and the reply, or on connection error. This function dereferenced all of them unconditionally, causing a crash when a window (e.g. a short-lived popup or tooltip) closes mid-query.

Add null checks, falling back to the root window or skipping the affected branch of the tree walk as appropriate.

M  +6    -2    src/Platforms/ImagePlatformXcb.cpp

https://invent.kde.org/plasma/spectacle/-/commit/93944711441c5d478e278f60eff659172f94b287

diff --git a/src/Platforms/ImagePlatformXcb.cpp b/src/Platforms/ImagePlatformXcb.cpp
index 8da985265..179353f79 100644
--- a/src/Platforms/ImagePlatformXcb.cpp
+++ b/src/Platforms/ImagePlatformXcb.cpp
@@ -34,6 +34,7 @@
 #include <KWindowInfo>
 #include <KWindowSystem>
 #include <KX11Extras>
+#include <xcb/xproto.h>
 
 using namespace Qt::StringLiterals;
 
@@ -221,7 +222,7 @@ xcb_window_t ImagePlatformXcb::getWindowUnderCursor()
     XcbReplyPtr<xcb_intern_atom_reply_t> atomReply(xcb_intern_atom_reply(xcbConn, atomCookie, nullptr));
     XcbReplyPtr<xcb_query_pointer_reply_t> pointerReply(xcb_query_pointer_reply(xcbConn, pointerCookie, nullptr));
 
-    if (atomReply->atom == XCB_ATOM_NONE) {
+    if (!atomReply || !pointerReply || atomReply->atom == XCB_ATOM_NONE) {
         return QX11Info::appRootWindow();
     }
 
@@ -237,7 +238,7 @@ xcb_window_t ImagePlatformXcb::getWindowUnderCursor()
         auto propCookie = xcb_get_property_unchecked(xcbConn, 0, appWin, atomReply->atom, XCB_ATOM_ANY, 0, 0);
         XcbReplyPtr<xcb_get_property_reply_t> propReply(xcb_get_property_reply(xcbConn, propCookie, nullptr));
 
-        if (propReply->type != XCB_ATOM_NONE) {
+        if (propReply && propReply->type != XCB_ATOM_NONE) {
             return appWin;
         }
 
@@ -245,6 +246,9 @@ xcb_window_t ImagePlatformXcb::getWindowUnderCursor()
         // we should start looking at its children
         auto treeCookie = xcb_query_tree_unchecked(xcbConn, appWin);
         XcbReplyPtr<xcb_query_tree_reply_t> treeReply(xcb_query_tree_reply(xcbConn, treeCookie, nullptr));
+        if (!treeReply) {
+            continue;
+        }
         auto windowChildren = xcb_query_tree_children(treeReply.get());
         auto windowChildrenLength = xcb_query_tree_children_length(treeReply.get());
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.