diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp index 1e6ef0efd68..09007fe8b22 100644 --- a/src/plugins/projectexplorer/appoutputpane.cpp +++ b/src/plugins/projectexplorer/appoutputpane.cpp @@ -247,11 +247,6 @@ AppOutputPane::AppOutputPane() : connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, this, &AppOutputPane::updateFromSettings); -#ifdef Q_OS_WIN - connect(this, &AppOutputPane::allRunControlsFinished, - WinDebugInterface::instance(), &WinDebugInterface::stop); -#endif - QSettings *settings = Core::ICore::settings(); m_zoom = settings->value(QLatin1String(SETTINGS_KEY), 0).toFloat(); @@ -546,15 +541,10 @@ void AppOutputPane::stopRunControl() qDebug() << "OutputPane::stopRunControl " << rc; } -bool AppOutputPane::closeTabs(CloseTabMode mode) +void AppOutputPane::closeTabs(CloseTabMode mode) { - bool allClosed = true; for (int t = m_tabWidget->count() - 1; t >= 0; t--) - if (!closeTab(t, mode)) - allClosed = false; - if (debug) - qDebug() << "OutputPane::closeTabs() returns " << allClosed; - return allClosed; + closeTab(t, mode); } QList AppOutputPane::allRunControls() const @@ -564,48 +554,37 @@ QList AppOutputPane::allRunControls() const }); } -bool AppOutputPane::closeTab(int tabIndex, CloseTabMode closeTabMode) +void AppOutputPane::closeTab(int tabIndex, CloseTabMode closeTabMode) { int index = indexOf(m_tabWidget->widget(tabIndex)); - QTC_ASSERT(index != -1, return true); + QTC_ASSERT(index != -1, return); + RunControl *runControl = m_runControlTabs[index].runControl; + Core::OutputWindow *window = m_runControlTabs[index].window; if (debug) - qDebug() << "OutputPane::closeTab tab " << tabIndex << m_runControlTabs[index].runControl - << m_runControlTabs[index].window; + qDebug() << "OutputPane::closeTab tab " << tabIndex << runControl << window; // Prompt user to stop - if (m_runControlTabs[index].runControl->isRunning()) { - switch (closeTabMode) { - case CloseTabNoPrompt: - break; - case CloseTabWithPrompt: - QWidget *tabWidget = m_tabWidget->widget(tabIndex); - if (!m_runControlTabs[index].runControl->promptToStop()) - return false; - // The event loop has run, thus the ordering might have changed, a tab might - // have been closed, so do some strange things... - tabIndex = m_tabWidget->indexOf(tabWidget); - index = indexOf(tabWidget); - if (tabIndex == -1 || index == -1) - return false; - break; - } - if (m_runControlTabs[index].runControl->isRunning()) { // yes it might have stopped already, then just close - m_runControlTabs[index].runControl->initiateStop(); - return false; - } + if (closeTabMode == CloseTabWithPrompt) { + QWidget *tabWidget = m_tabWidget->widget(tabIndex); + if (!runControl->promptToStop()) + return; + // The event loop has run, thus the ordering might have changed, a tab might + // have been closed, so do some strange things... + tabIndex = m_tabWidget->indexOf(tabWidget); + index = indexOf(tabWidget); + if (tabIndex == -1 || index == -1) + return; } m_tabWidget->removeTab(tabIndex); - delete m_runControlTabs[index].window; - m_runControlTabs[index].runControl->initiateFinish(); // Will self-destruct. - m_runControlTabs[index].runControl = 0; + delete window; + + runControl->initiateFinish(); // Will self-destruct. m_runControlTabs.removeAt(index); updateCloseActions(); if (m_runControlTabs.isEmpty()) hide(); - - return true; } bool AppOutputPane::optionallyPromptToStop(RunControl *runControl) @@ -742,15 +721,14 @@ void AppOutputPane::slotRunControlFinished2(RunControl *sender) ProjectExplorerPlugin::instance()->updateRunActions(); - if (!isRunning()) - emit allRunControlsFinished(); -} - -bool AppOutputPane::isRunning() const -{ - return Utils::anyOf(m_runControlTabs, [](const RunControlTab &rt) { +#ifdef Q_OS_WIN + const bool isRunning = Utils::anyOf(m_runControlTabs, [](const RunControlTab &rt) { return rt.runControl->isRunning(); }); + if (!isRunning) + WinDebugInterface::instance()->stop(); +#endif + } bool AppOutputPane::canNext() const diff --git a/src/plugins/projectexplorer/appoutputpane.h b/src/plugins/projectexplorer/appoutputpane.h index b260447ba5a..fc7ac6e05eb 100644 --- a/src/plugins/projectexplorer/appoutputpane.h +++ b/src/plugins/projectexplorer/appoutputpane.h @@ -88,14 +88,10 @@ public: void setBehaviorOnOutput(RunControl *rc, BehaviorOnOutput mode); bool aboutToClose() const; - bool closeTabs(CloseTabMode mode); + void closeTabs(CloseTabMode mode); QList allRunControls() const; -signals: - void allRunControlsFinished(); - -public: // ApplicationOutput specifics void projectRemoved(); @@ -126,12 +122,11 @@ private: explicit RunControlTab(RunControl *runControl = nullptr, Core::OutputWindow *window = nullptr); QPointer runControl; - Core::OutputWindow *window; + QPointer window; BehaviorOnOutput behaviorOnOutput = Flash; }; - bool isRunning() const; - bool closeTab(int index, CloseTabMode cm = CloseTabWithPrompt); + void closeTab(int index, CloseTabMode cm = CloseTabWithPrompt); bool optionallyPromptToStop(RunControl *runControl); int indexOf(const RunControl *) const; @@ -148,6 +143,7 @@ private: QWidget *m_mainWidget; TabWidget *m_tabWidget; QVector m_runControlTabs; + int m_runControlCount = 0; QAction *m_stopAction; QAction *m_closeCurrentTabAction; QAction *m_closeAllTabsAction; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index b17ef07c9fe..7e979b56e30 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -343,6 +343,9 @@ public: void runConfigurationConfigurationFinished(); + void checkForShutdown(); + void timerEvent(QTimerEvent *) override; + QList > recentProjects() const; public: @@ -405,6 +408,8 @@ public: QStringList m_profileMimeTypes; AppOutputPane *m_outputPane = nullptr; + int m_activeRunControlCount = 0; + int m_shutdownWatchDogId = -1; QHash> m_projectCreators; QList > m_recentProjects; // pair of filename, displayname @@ -1632,10 +1637,12 @@ ExtensionSystem::IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown() removeObject(dd->m_welcomePage); delete dd->m_welcomePage; removeObject(this); - if (dd->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */)) + + if (dd->m_activeRunControlCount == 0) return SynchronousShutdown; - connect(dd->m_outputPane, &AppOutputPane::allRunControlsFinished, - this, &IPlugin::asynchronousShutdownFinished); + + dd->m_outputPane->closeTabs(AppOutputPane::CloseTabNoPrompt /* No prompt any more */); + dd->m_shutdownWatchDogId = dd->startTimer(10 * 1000); // Make sure we shutdown *somehow* return AsynchronousShutdown; } @@ -2032,10 +2039,27 @@ void ProjectExplorerPluginPrivate::startRunControl(RunControl *runControl) bool popup = (runMode == Constants::NORMAL_RUN_MODE && dd->m_projectExplorerSettings.showRunOutput) || (runMode == Constants::DEBUG_RUN_MODE && m_projectExplorerSettings.showDebugOutput); m_outputPane->setBehaviorOnOutput(runControl, popup ? AppOutputPane::Popup : AppOutputPane::Flash); + connect(runControl, &QObject::destroyed, this, &ProjectExplorerPluginPrivate::checkForShutdown, + Qt::QueuedConnection); + ++m_activeRunControlCount; runControl->initiateStart(); emit m_instance->updateRunActions(); } +void ProjectExplorerPluginPrivate::checkForShutdown() +{ + --m_activeRunControlCount; + QTC_ASSERT(m_activeRunControlCount >= 0, m_activeRunControlCount = 0); + if (m_shuttingDown && m_activeRunControlCount == 0) + m_instance->asynchronousShutdownFinished(); +} + +void ProjectExplorerPluginPrivate::timerEvent(QTimerEvent *ev) +{ + if (m_shutdownWatchDogId == ev->timerId()) + m_instance->asynchronousShutdownFinished(); +} + void ProjectExplorerPlugin::initiateInlineRenaming() { dd->handleRenameFile(); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 02a39f326a1..b0f06be3583 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -674,7 +674,6 @@ RunControl::~RunControl() #ifdef WITH_JOURNALD JournaldWatcher::instance()->unsubscribe(this); #endif - disconnect(); delete d; d = nullptr; } @@ -698,7 +697,7 @@ void RunControl::initiateStop() void RunControl::initiateFinish() { - d->initiateFinish(); + QTimer::singleShot(0, d, &RunControlPrivate::initiateFinish); } using WorkerCreators = QHash; @@ -1277,7 +1276,7 @@ void RunControlPrivate::setState(RunControlState newState) case RunControlState::Finished: emit q->finished(); debugMessage("All finished. Deleting myself"); - deleteLater(); + q->deleteLater(); break; default: break;