forked from qt-creator/qt-creator
Debugger: Re-organize dock widget persisting
Looks like the mainwindow cannot be convinced to handle multiple sets of dockwidgets. So switch back to a single set containing everything and keep track of non-default visibility in the perspectives, and persist these sets. The following pass: 1. Start Creator with new settings Goto Debug Mode Move Break dock widget to right, switch on Global log widget Leave Creator Start Creator Goto Debug Mode Check: Debugger Selected, Break on right, Global log visible 2. Start Creator with new settings Goto Debug Mode Move Break dock widget to right, switch on Global log widget Switch to QmlProfiler sub-perspective Leave Creator Start Creator Goto Debug Mode Check QmlProfiler selected Switch to Debugger sub-perspective Check: Debugger Selected, Break on right, Global log visible 3. Start Creator with new settings Use any C++ test project Start debugging / stop at main() (F10) Wait for stop Switch to Edit mode Switch back to Debug mode Check: Only "running" debugger dock widget layout present (not the normal + preset at the same time) Quit Qt Creator while this debugger is running Check: Shuts down without crash 4. Use any C++ test project Start debugging Switch to Debugger Preset perspective Start a second debugger Kill either instance Check: Application dies, Debugger Preset perspective gets displayed Switch to perspective of second instance Check: Perspective looks ok (docks visible as before) Task-number: QTCREATORBUG-21083 Task-number: QTCREATORBUG-21669 Task-number: QTCREATORBUG-21668 Task-number: QTCREATORBUG-21813 Task-number: QTCREATORBUG-21851 Task-number: QTCREATORBUG-22110 Task-number: QTCREATORBUG-22169 Task-number: QTCREATORBUG-22189 Change-Id: Ic9eb41ff7699ac0f48a85e68376daa80b2b6847e Reviewed-by: Robert Loehning <robert.loehning@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -61,6 +61,7 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
#include <coreplugin/progressmanager/futureprogress.h>
|
||||
|
||||
@@ -280,12 +281,16 @@ public:
|
||||
m_disassemblerAgent(engine),
|
||||
m_toolTipManager(engine)
|
||||
{
|
||||
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
||||
m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
|
||||
m_debuggerName = DebuggerEngine::tr("Debugger");
|
||||
|
||||
connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
|
||||
this, [this] { updateState(true); });
|
||||
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
||||
m_logWindow->setObjectName("Debugger.Dock.Output");
|
||||
|
||||
connect(action(EnableReverseDebugging), &SavedAction::valueChanged, this, [this] {
|
||||
updateState();
|
||||
if (m_companionEngine)
|
||||
m_companionEngine->d->updateState();
|
||||
});
|
||||
static int contextCount = 0;
|
||||
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
||||
|
||||
@@ -370,17 +375,15 @@ public:
|
||||
if (!m_perspective)
|
||||
return;
|
||||
|
||||
delete m_perspective;
|
||||
Perspective *perspective = m_perspective;
|
||||
m_perspective = nullptr;
|
||||
|
||||
EngineManager::unregisterEngine(m_engine);
|
||||
|
||||
// Give up ownership on claimed breakpoints.
|
||||
m_breakHandler.releaseAllBreakpoints();
|
||||
m_toolTipManager.deregisterEngine();
|
||||
m_memoryAgents.handleDebuggerFinished();
|
||||
|
||||
setBusyCursor(false);
|
||||
// This triggers activity in the EngineManager which
|
||||
// recognizes the rampdown by the m_perpective == nullptr above.
|
||||
perspective->destroy();
|
||||
delete perspective;
|
||||
}
|
||||
|
||||
void updateReturnViewHeader(int section, int, int newSize)
|
||||
@@ -446,14 +449,14 @@ public:
|
||||
void setInitialActionStates();
|
||||
void setBusyCursor(bool on);
|
||||
void cleanupViews();
|
||||
void updateState(bool alsoUpdateCompanion);
|
||||
void updateState();
|
||||
void updateReverseActions();
|
||||
|
||||
DebuggerEngine *m_engine = nullptr; // Not owned.
|
||||
QString m_runId;
|
||||
QPointer<RunConfiguration> m_runConfiguration; // Not owned.
|
||||
QString m_debuggerName;
|
||||
Perspective *m_perspective = nullptr;
|
||||
QPointer<Perspective> m_perspective;
|
||||
DebuggerRunParameters m_runParameters;
|
||||
IDevice::ConstPtr m_device;
|
||||
|
||||
@@ -551,16 +554,17 @@ public:
|
||||
void DebuggerEnginePrivate::setupViews()
|
||||
{
|
||||
const DebuggerRunParameters &rp = m_runParameters;
|
||||
const QString engineId = EngineManager::registerEngine(m_engine);
|
||||
|
||||
QTC_CHECK(!m_perspective);
|
||||
|
||||
m_perspective = new Perspective("Debugger.Perspective." + m_runId + '.' + m_debuggerName,
|
||||
const QString perspectiveId = "Debugger.Perspective." + m_runId + '.' + m_debuggerName;
|
||||
const QString settingsId = "Debugger.Perspective." + m_debuggerName;
|
||||
|
||||
m_perspective = new Perspective(perspectiveId,
|
||||
m_engine->displayName(),
|
||||
Debugger::Constants::PRESET_PERSPECTIVE_ID,
|
||||
m_debuggerName);
|
||||
m_perspective->setShouldPersistChecker([this] {
|
||||
return EngineManager::isLastOf(m_debuggerName);
|
||||
});
|
||||
settingsId);
|
||||
|
||||
m_progress.setProgressRange(0, 1000);
|
||||
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
|
||||
@@ -628,7 +632,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_engine, &DebuggerEngine::reloadModules,
|
||||
Qt::QueuedConnection);
|
||||
m_modulesWindow = addSearch(m_modulesView);
|
||||
m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
|
||||
m_modulesWindow->setObjectName("Debugger.Dock.Modules." + engineId);
|
||||
m_modulesWindow->setWindowTitle(tr("&Modules"));
|
||||
|
||||
m_registerView = new BaseTreeView;
|
||||
@@ -639,7 +643,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_engine, &DebuggerEngine::reloadRegisters,
|
||||
Qt::QueuedConnection);
|
||||
m_registerWindow = addSearch(m_registerView);
|
||||
m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
|
||||
m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId);
|
||||
m_registerWindow->setWindowTitle(tr("Reg&isters"));
|
||||
|
||||
m_stackView = new StackTreeView;
|
||||
@@ -647,7 +651,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_stackView->setSettings(settings, "Debugger.StackView");
|
||||
m_stackView->setIconSize(QSize(10, 10));
|
||||
m_stackWindow = addSearch(m_stackView);
|
||||
m_stackWindow->setObjectName(DOCKWIDGET_STACK);
|
||||
m_stackWindow->setObjectName("Debugger.Dock.Stack." + engineId);
|
||||
m_stackWindow->setWindowTitle(tr("&Stack"));
|
||||
|
||||
m_sourceFilesView = new BaseTreeView;
|
||||
@@ -658,7 +662,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_engine, &DebuggerEngine::reloadSourceFiles,
|
||||
Qt::QueuedConnection);
|
||||
m_sourceFilesWindow = addSearch(m_sourceFilesView);
|
||||
m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
|
||||
m_sourceFilesWindow->setObjectName("Debugger.Dock.SourceFiles." + engineId);
|
||||
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
|
||||
|
||||
m_threadsView = new BaseTreeView;
|
||||
@@ -668,7 +672,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_threadsView->setIconSize(QSize(10, 10));
|
||||
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
|
||||
m_threadsWindow = addSearch(m_threadsView);
|
||||
m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
|
||||
m_threadsWindow->setObjectName("Debugger.Dock.Threads." + engineId);
|
||||
m_threadsWindow->setWindowTitle(tr("&Threads"));
|
||||
|
||||
m_returnView = new WatchTreeView{ReturnType};
|
||||
@@ -682,26 +686,26 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_localsView->setModel(m_watchHandler.model());
|
||||
m_localsView->setSettings(settings, "Debugger.LocalsView");
|
||||
m_localsWindow = addSearch(m_localsView);
|
||||
m_localsWindow->setObjectName("CppDebugLocals");
|
||||
m_localsWindow->setObjectName("Debugger.Dock.Locals." + engineId);
|
||||
m_localsWindow->setWindowTitle(tr("Locals"));
|
||||
|
||||
m_inspectorView = new WatchTreeView{InspectType};
|
||||
m_inspectorView->setModel(m_watchHandler.model());
|
||||
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
|
||||
m_inspectorWindow = addSearch(m_inspectorView);
|
||||
m_inspectorWindow->setObjectName("Inspector");
|
||||
m_inspectorWindow->setObjectName("Debugger.Dock.Inspector." + engineId);
|
||||
m_inspectorWindow->setWindowTitle(tr("Locals"));
|
||||
|
||||
m_watchersView = new WatchTreeView{WatchersType};
|
||||
m_watchersView->setModel(m_watchHandler.model());
|
||||
m_watchersView->setSettings(settings, "Debugger.WatchersView");
|
||||
m_watchersWindow = addSearch(m_watchersView);
|
||||
m_watchersWindow->setObjectName("CppDebugWatchers");
|
||||
m_watchersWindow->setObjectName("Debugger.Dock.Watchers." + engineId);
|
||||
m_watchersWindow->setWindowTitle(tr("&Expressions"));
|
||||
|
||||
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
|
||||
m_localsWindow, m_inspectorWindow, m_returnWindow);
|
||||
m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR);
|
||||
m_localsAndInspectorWindow->setObjectName("Debugger.Dock.LocalsAndInspector." + engineId);
|
||||
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
|
||||
|
||||
// Locals
|
||||
@@ -719,7 +723,7 @@ void DebuggerEnginePrivate::setupViews()
|
||||
m_breakView->setModel(m_breakHandler.model());
|
||||
m_breakView->setRootIsDecorated(true);
|
||||
m_breakWindow = addSearch(m_breakView);
|
||||
m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
|
||||
m_breakWindow->setObjectName("Debugger.Dock.Break." + engineId);
|
||||
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
|
||||
|
||||
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
||||
@@ -846,7 +850,6 @@ void DebuggerEnginePrivate::setupViews()
|
||||
DebuggerEngine::DebuggerEngine()
|
||||
: d(new DebuggerEnginePrivate(this))
|
||||
{
|
||||
updateState(false);
|
||||
}
|
||||
|
||||
DebuggerEngine::~DebuggerEngine()
|
||||
@@ -1020,7 +1023,6 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
|
||||
|
||||
void DebuggerEngine::start()
|
||||
{
|
||||
EngineManager::registerEngine(this);
|
||||
d->m_watchHandler.resetWatchers();
|
||||
d->setInitialActionStates();
|
||||
setState(EngineSetupRequested);
|
||||
@@ -1116,7 +1118,7 @@ void DebuggerEngine::abortDebugger()
|
||||
|
||||
void DebuggerEngine::updateUi(bool isCurrentEngine)
|
||||
{
|
||||
updateState(false);
|
||||
updateState();
|
||||
if (isCurrentEngine) {
|
||||
gotoCurrentLocation();
|
||||
} else {
|
||||
@@ -1319,7 +1321,7 @@ void DebuggerEngine::notifyInferiorSpontaneousStop()
|
||||
{
|
||||
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
|
||||
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
||||
EngineManager::activateEngine(this);
|
||||
d->m_perspective->select();
|
||||
showMessage(tr("Stopped."), StatusBar);
|
||||
setState(InferiorStopOk);
|
||||
if (boolSetting(RaiseOnInterrupt))
|
||||
@@ -1386,10 +1388,12 @@ void DebuggerEnginePrivate::setInitialActionStates()
|
||||
m_threadLabel->setEnabled(false);
|
||||
}
|
||||
|
||||
void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
||||
void DebuggerEnginePrivate::updateState()
|
||||
{
|
||||
if (!m_perspective)
|
||||
// Can happen in mixed debugging.
|
||||
if (!m_threadLabel)
|
||||
return;
|
||||
QTC_ASSERT(m_threadLabel, return);
|
||||
|
||||
const DebuggerState state = m_state;
|
||||
const bool companionPreventsAction = m_engine->companionPreventsActions();
|
||||
@@ -1399,7 +1403,7 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
||||
// visible, possibly disabled.
|
||||
if (state == DebuggerNotReady) {
|
||||
// Happens when companion starts, otherwise this should not happen.
|
||||
QTC_CHECK(m_companionEngine);
|
||||
//QTC_CHECK(m_companionEngine);
|
||||
m_interruptAction.setVisible(true);
|
||||
m_interruptAction.setEnabled(false);
|
||||
m_continueAction.setVisible(false);
|
||||
@@ -1529,9 +1533,6 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
||||
|| state == DebuggerFinished
|
||||
|| state == InferiorUnrunnable;
|
||||
setBusyCursor(!notbusy);
|
||||
|
||||
if (alsoUpdateCompanion && m_companionEngine)
|
||||
m_companionEngine->updateState(false);
|
||||
}
|
||||
|
||||
void DebuggerEnginePrivate::updateReverseActions()
|
||||
@@ -1690,9 +1691,9 @@ void DebuggerEngine::notifyInferiorExited()
|
||||
d->doShutdownEngine();
|
||||
}
|
||||
|
||||
void DebuggerEngine::updateState(bool alsoUpdateCompanion)
|
||||
void DebuggerEngine::updateState()
|
||||
{
|
||||
d->updateState(alsoUpdateCompanion);
|
||||
d->updateState();
|
||||
}
|
||||
|
||||
WatchTreeView *DebuggerEngine::inspectorView()
|
||||
@@ -1793,17 +1794,28 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
|
||||
if (!forced && !isAllowedTransition(oldState, state))
|
||||
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
||||
|
||||
if (state == EngineRunRequested)
|
||||
if (state == EngineRunRequested) {
|
||||
emit engineStarted();
|
||||
d->m_perspective->select();
|
||||
}
|
||||
|
||||
showMessage(msg, LogDebug);
|
||||
|
||||
d->updateState(true);
|
||||
d->updateState();
|
||||
if (d->m_companionEngine)
|
||||
d->m_companionEngine->d->updateState();
|
||||
|
||||
if (oldState != d->m_state)
|
||||
emit EngineManager::instance()->engineStateChanged(this);
|
||||
|
||||
if (state == DebuggerFinished) {
|
||||
d->setBusyCursor(false);
|
||||
|
||||
// Give up ownership on claimed breakpoints.
|
||||
d->m_breakHandler.releaseAllBreakpoints();
|
||||
d->m_toolTipManager.deregisterEngine();
|
||||
d->m_memoryAgents.handleDebuggerFinished();
|
||||
|
||||
d->destroyPerspective();
|
||||
emit engineFinished();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user