[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());