MCPcopy Create free account
hub / github.com/aethersdr/AetherSDR / prepareShutdown

Method prepareShutdown

src/gui/PanadapterStack.cpp:837–886  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

835}
836
837void PanadapterStack::prepareShutdown()
838{
839 if (m_shutdownPrepared) {
840 return;
841 }
842 m_shutdownPrepared = true;
843
844 setShuttingDown(true);
845 saveFloatingState();
846
847 // Explicitly delete floating windows rather than calling close().
848 // close() without WA_DeleteOnClose only hides the window, leaving it alive
849 // as a Qt::Window child of MainWindow. When MainWindow's QWidget::~QWidget()
850 // later tears down its QRhi, Qt fires the QRhiWidgetPrivate cleanup callbacks
851 // for those still-parented-but-hidden floating windows in an order that can
852 // invalidate QRhiWidgetPrivate before the callback returns → crash at 0x1e2.
853 // Deleting fw explicitly runs QRhiWidget::~QRhiWidget() → removeCleanupCallback
854 // while the QRhi is still valid, so no stale callbacks remain when MainWindow
855 // tears down (#2495 exit crash on macOS).
856 const QList<QString> floatingIds = m_floatingWindows.keys();
857 for (const QString& panId : floatingIds) {
858 PanFloatingWindow* fw = m_floatingWindows.take(panId);
859 if (!fw) continue;
860 fw->saveWindowGeometry();
861 if (PanadapterApplet* applet = fw->applet()) {
862 if (SpectrumWidget* sw = applet->spectrumWidget()) {
863 sw->prepareForShutdown();
864 }
865 }
866 m_pans.remove(panId);
867 delete fw;
868 }
869
870 // Explicitly delete docked applets so ~QRhiWidget() runs (and calls
871 // removeCleanupCallback) while MainWindow's QRhi is still alive.
872 // If we leave applets alive, Qt's destructor chain for QWidget destroys
873 // the QRhi *before* ~QObject()::deleteChildren() deletes the child
874 // SpectrumWidgets — QRhi::runCleanup() then fires against QRhiWidgetPrivate
875 // objects that are still live but have internal Qt fields in a stale state
876 // → crash at $0_cleanup +24 on exit (#2495 macOS).
877 const QList<QString> dockedIds = m_pans.keys();
878 for (const QString& panId : dockedIds) {
879 PanadapterApplet* applet = m_pans.take(panId);
880 if (!applet) continue;
881 if (SpectrumWidget* sw = applet->spectrumWidget()) {
882 sw->prepareForShutdown();
883 }
884 delete applet;
885 }
886}
887
888void PanadapterStack::saveFloatingState() const
889{

Callers 1

Calls 5

saveWindowGeometryMethod · 0.80
appletMethod · 0.80
spectrumWidgetMethod · 0.80
prepareForShutdownMethod · 0.80
removeMethod · 0.45

Tested by

no test coverage detected