Follow-up to #3764 (which landed the #3746 idle-pause work).
SpectrumWidget::m_flagTimerFilteredWindow is a raw QWidget* pointing at the watched top-level window. It's safe on today's teardown paths — prepareForTopLevelChange() detaches the event filter and nulls the pointer, and Qt auto-removes the filter when either object is destroyed — but the removeEventFilter() calls in attachFlagTimerWindowWatcher() and prepareForTopLevelChange() would be UB if a future code path ever destroyed the watched window without first routing through prepareForTopLevelChange() (the raw pointer would dangle, non-null).
Fix
Change m_flagTimerFilteredWindow to QPointer<QWidget>. A destroyed window then reads back as null, so the guarded removeEventFilter() calls become no-ops automatically — bulletproof for ~zero cost. Verify the == window() / != this comparisons and the installEventFilter/removeEventFilter sites still read correctly (QPointer converts implicitly to the raw pointer for these).
Scope
src/gui/SpectrumWidget.h — member type + #include <QPointer> if not already present
src/gui/SpectrumWidget.cpp — no logic change expected; the guarded derefs already null-check
Defensive hardening only; no behavior change. Raised in the #3764 review.
Follow-up to #3764 (which landed the #3746 idle-pause work).
SpectrumWidget::m_flagTimerFilteredWindowis a rawQWidget*pointing at the watched top-level window. It's safe on today's teardown paths —prepareForTopLevelChange()detaches the event filter and nulls the pointer, and Qt auto-removes the filter when either object is destroyed — but theremoveEventFilter()calls inattachFlagTimerWindowWatcher()andprepareForTopLevelChange()would be UB if a future code path ever destroyed the watched window without first routing throughprepareForTopLevelChange()(the raw pointer would dangle, non-null).Fix
Change
m_flagTimerFilteredWindowtoQPointer<QWidget>. A destroyed window then reads back as null, so the guardedremoveEventFilter()calls become no-ops automatically — bulletproof for ~zero cost. Verify the== window()/!= thiscomparisons and theinstallEventFilter/removeEventFiltersites still read correctly (QPointer converts implicitly to the raw pointer for these).Scope
src/gui/SpectrumWidget.h— member type +#include <QPointer>if not already presentsrc/gui/SpectrumWidget.cpp— no logic change expected; the guarded derefs already null-checkDefensive hardening only; no behavior change. Raised in the #3764 review.