From 82d2107e1d5e97b69eadae379a4e023d52924f48 Mon Sep 17 00:00:00 2001 From: CuriousJ Date: Fri, 2 Oct 2026 09:17:16 -0400 Subject: [PATCH] Screens: take a screen's overlays from one copy in the catcher While a button pressed on a screen is held, UpdateCatcher checks every tick whether the laser is still on one of the screen's overlays. It built that list from s.All().begin() and s.All().end(), but All() returns a std::array by value: iterators into two different temporaries, which is undefined behaviour. A clang build of ft-screens got a garbage length, threw std::length_error, and aborted on the first click, taking KWin and the desktop with it. --- screens/vr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/screens/vr.cpp b/screens/vr.cpp index 90624fa..065a869 100644 --- a/screens/vr.cpp +++ b/screens/vr.cpp @@ -1330,7 +1330,8 @@ void UpdateCatcher() { for (int k = 0; k < 3; ++k) params.vSource.v[k] = l.m[k][3], params.vDirection.v[k] = -l.m[k][2]; for (auto &[i, s] : g_screens) { if (!s.visible) continue; - std::vector parts(s.All().begin(), s.All().end()); + const auto all = s.All(); // one copy: two calls give two temporaries, not one range + std::vector parts(all.begin(), all.end()); for (const auto &[k, sub] : s.subs) parts.push_back(sub.overlay); for (auto o : parts) { vr::VROverlayIntersectionResults_t hit;