diff --git a/src/controllers/controllermanager.cpp b/src/controllers/controllermanager.cpp index 0aee05c07f9..088eb93ae20 100644 --- a/src/controllers/controllermanager.cpp +++ b/src/controllers/controllermanager.cpp @@ -178,6 +178,9 @@ void ControllerManager::slotShutdown() { } void ControllerManager::updateControllerList() { + // NOTE: Currently this function is only called on startup. If hotplug is added, changes to the + // controller list must be synchronized with dlgprefcontrollers to avoid dangling connections + // and possible crashes. auto locker = lockMutex(&m_mutex); if (m_enumerators.isEmpty()) { qWarning() << "updateControllerList called but no enumerators have been added!"; diff --git a/src/controllers/dlgprefcontrollers.cpp b/src/controllers/dlgprefcontrollers.cpp index 87671a5a87d..94d9454e238 100644 --- a/src/controllers/dlgprefcontrollers.cpp +++ b/src/controllers/dlgprefcontrollers.cpp @@ -130,6 +130,14 @@ void DlgPrefControllers::rescanControllers() { } void DlgPrefControllers::destroyControllerWidgets() { + // NOTE: this assumes that the list of controllers does not change during the lifetime of Mixxx. + // This is currently true, but once we support hotplug, we will need better lifecycle management + // to keep this dialog and the controllermanager consistent. + QList controllerList = + m_pControllerManager->getControllerList(false, true); + for (auto controller : controllerList) { + controller->disconnect(this); + } while (!m_controllerPages.isEmpty()) { DlgPrefController* pControllerDlg = m_controllerPages.takeLast(); m_pDlgPreferences->removePageWidget(pControllerDlg); @@ -173,6 +181,7 @@ void DlgPrefControllers::setupControllerWidgets() { connect(pController, &Controller::openChanged, + this, [this, pControllerDlg](bool bOpen) { slotHighlightDevice(pControllerDlg, bOpen); });