diff options
author | Aaron Barany | 2019-06-01 14:23:59 -0700 |
---|---|---|
committer | Aaron Barany | 2019-06-01 14:23:59 -0700 |
commit | db4191e8398af97de44d7cb87f0e60cb5e1643c6 (patch) | |
tree | 842471f3109d7c879f66afe3a45ff2e20b1e37bd | |
parent | f2b7caac497c84db2667c3c25f82dedf34a576ac (diff) | |
download | aur-db4191e8398af97de44d7cb87f0e60cb5e1643c6.tar.gz |
Updated to 4.9.1.
Theme fixes this package was originally created for have been applied to
the 4.9 release. This package has been re-purposed to apply a patch to fix
EXTREMELY annoying debugger layout bugs that were introduced in 4.9.
-rw-r--r-- | .SRCINFO | 33 | ||||
-rw-r--r-- | PKGBUILD | 57 | ||||
-rw-r--r-- | qtcreator-clang-plugins.patch | 44 | ||||
-rw-r--r-- | qtcreator-clazy-1.5.patch | 45 | ||||
-rw-r--r-- | qtcreator-cmake-edit-fix.patch | 34 | ||||
-rw-r--r-- | qtcreator-cmake-fail-target-fix.patch | 29 | ||||
-rw-r--r-- | qtcreator-debugger-columns-fix.patch | 343 | ||||
-rw-r--r-- | qtcreator-debugger-layout.patch | 1715 | ||||
-rw-r--r-- | qtcreator-occurrences-fix.patch | 104 | ||||
-rw-r--r-- | qtcreator-preload-plugins.patch | 21 | ||||
-rw-r--r-- | qtcreator-theme-fixes.patch | 308 |
11 files changed, 1822 insertions, 911 deletions
@@ -1,14 +1,13 @@ pkgbase = qtcreator-fixed-themes - pkgdesc = Lightweight, cross-platform integrated development environment, with fixes applied for various themes and other bug fixes - pkgver = 4.8.2 - pkgrel = 2 + pkgdesc = Lightweight, cross-platform integrated development environment, with theme and bug fixes applied + pkgver = 4.9.1 + pkgrel = 1 url = https://www.qt.io arch = x86_64 license = LGPL - makedepends = git - makedepends = mesa makedepends = llvm makedepends = python + makedepends = patchelf depends = qt5-tools depends = qt5-quickcontrols depends = qt5-quickcontrols2 @@ -16,6 +15,8 @@ pkgbase = qtcreator-fixed-themes depends = clang=8.0.0 depends = qbs depends = clazy + depends = syntax-highlighting + depends = desktop-file-utils optdepends = qt5-doc: integrated Qt documentation optdepends = qt5-examples: welcome page examples optdepends = qt5-translations: for other languages @@ -28,20 +29,14 @@ pkgbase = qtcreator-fixed-themes optdepends = valgrind: analyze support conflicts = qtcreator options = docs - source = https://download.qt.io/official_releases/qtcreator/4.8/4.8.2/qt-creator-opensource-src-4.8.2.tar.xz - source = qtcreator-clang-plugins.patch - source = qtcreator-theme-fixes.patch - source = qtcreator-occurrences-fix.patch - source = qtcreator-debugger-columns-fix.patch - source = qtcreator-cmake-fail-target-fix.patch - source = qtcreator-cmake-edit-fix.patch - sha256sums = a8257daf39f6025c8523285dc73fd6b66645f3ff071e112b484325966eee0c92 - sha256sums = 34ea74698ddff9925e06bff6b4c995bf93488d1104e8cc517bcfdd621effb428 - sha256sums = bf0f8e88d0fa628d24f59eaf1f359873926998dde442e3bcbd56afcdd6eec7fa - sha256sums = 640c4c1607f9ee867e2445ad576697b9b0d3c9a64ae6589c1b99ea4f1d7e3481 - sha256sums = cf378a8b591a10646ad89d101375d8b04844c76a83d6c9c960036ba6a3b122e3 - sha256sums = df22bfe38bf6dd54b64d9ec0e78873a43e570eb490faf2a247aae7fd44e3d05e - sha256sums = 5f002e93717d99a23ed94842567caa35f5cddfac317bddf29e7a677fb6db61a3 + source = https://download.qt.io/official_releases/qtcreator/4.9/4.9.1/qt-creator-opensource-src-4.9.1.tar.xz + source = qtcreator-clazy-1.5.patch + source = qtcreator-preload-plugins.patch + source = qtcreator-debugger-layout.patch + sha256sums = 79b8228d0871927837681e6af9ab91e3ea28154cecfba317f9c0e56246b8ad81 + sha256sums = 1f6998fea92b9a157f42cca783839ce95f70ccc667027078b7881cbb253838f0 + sha256sums = 150c444e76ec969fc8765774b648984037829623300d0ce9d41a915b2afa792d + sha256sums = 6000452635f8c8f0cd21d1cc8d484821f4d0f8fc36afa744de5c2a3fdd1a5e9c pkgname = qtcreator-fixed-themes @@ -10,15 +10,15 @@ # Contributor: delor <bartekpiech gmail com> pkgname=qtcreator-fixed-themes -pkgver=4.8.2 +pkgver=4.9.1 _clangver=8.0.0 -pkgrel=2 -pkgdesc='Lightweight, cross-platform integrated development environment, with fixes applied for various themes and other bug fixes' +pkgrel=1 +pkgdesc='Lightweight, cross-platform integrated development environment, with theme and bug fixes applied' arch=(x86_64) url='https://www.qt.io' license=(LGPL) -depends=(qt5-tools qt5-quickcontrols qt5-quickcontrols2 qt5-webengine clang=$_clangver qbs clazy) -makedepends=(git mesa llvm python) +depends=(qt5-tools qt5-quickcontrols qt5-quickcontrols2 qt5-webengine clang=$_clangver qbs clazy syntax-highlighting desktop-file-utils) +makedepends=(llvm python patchelf) conflicts=(qtcreator) options=(docs) optdepends=('qt5-doc: integrated Qt documentation' @@ -32,19 +32,13 @@ optdepends=('qt5-doc: integrated Qt documentation' 'bzr: bazaar support' 'valgrind: analyze support') source=("https://download.qt.io/official_releases/qtcreator/${pkgver%.*}/$pkgver/qt-creator-opensource-src-$pkgver.tar.xz" - qtcreator-clang-plugins.patch - qtcreator-theme-fixes.patch - qtcreator-occurrences-fix.patch - qtcreator-debugger-columns-fix.patch - qtcreator-cmake-fail-target-fix.patch - qtcreator-cmake-edit-fix.patch) -sha256sums=('a8257daf39f6025c8523285dc73fd6b66645f3ff071e112b484325966eee0c92' - '34ea74698ddff9925e06bff6b4c995bf93488d1104e8cc517bcfdd621effb428' - 'bf0f8e88d0fa628d24f59eaf1f359873926998dde442e3bcbd56afcdd6eec7fa' - '640c4c1607f9ee867e2445ad576697b9b0d3c9a64ae6589c1b99ea4f1d7e3481' - 'cf378a8b591a10646ad89d101375d8b04844c76a83d6c9c960036ba6a3b122e3' - 'df22bfe38bf6dd54b64d9ec0e78873a43e570eb490faf2a247aae7fd44e3d05e' - '5f002e93717d99a23ed94842567caa35f5cddfac317bddf29e7a677fb6db61a3') + qtcreator-clazy-1.5.patch + qtcreator-preload-plugins.patch + qtcreator-debugger-layout.patch) +sha256sums=('79b8228d0871927837681e6af9ab91e3ea28154cecfba317f9c0e56246b8ad81' + '1f6998fea92b9a157f42cca783839ce95f70ccc667027078b7881cbb253838f0' + '150c444e76ec969fc8765774b648984037829623300d0ce9d41a915b2afa792d' + '6000452635f8c8f0cd21d1cc8d484821f4d0f8fc36afa744de5c2a3fdd1a5e9c') prepare() { mkdir -p build @@ -52,27 +46,27 @@ prepare() { cd qt-creator-opensource-src-$pkgver # fix hardcoded libexec path sed -e 's|libexec\/qtcreator|lib\/qtcreator|g' -i qtcreator.pri + sed -e 's|libexec|lib|g' -i src/tools/tools.pro # use system qbs rm -r src/shared/qbs - # Load analyzer plugins on demand, since upstream clang doesn't link to all plugins + # Adapt to clazy 1.5 plugin rename + patch -p1 -i ../qtcreator-clazy-1.5.patch + # Preload analyzer plugins, since upstream clang doesn't link to all plugins # see http://code.qt.io/cgit/clang/clang.git/commit/?id=7f349701d3ea0c47be3a43e265699dddd3fd55cf # and https://bugs.archlinux.org/task/59492 - patch -p1 -i ../qtcreator-clang-plugins.patch - # Theme fixes - patch -p1 -i ../qtcreator-theme-fixes.patch - patch -p1 -i ../qtcreator-occurrences-fix.patch - # Fix broken sizing for debugger columns. - patch -p1 -i ../qtcreator-debugger-columns-fix.patch - # Fixes for CMake integration - patch -p1 -i ../qtcreator-cmake-fail-target-fix.patch - patch -p1 -i ../qtcreator-cmake-edit-fix.patch + patch -p1 -i ../qtcreator-preload-plugins.patch + # Fixes for debugger layout. + patch -p1 -i ../qtcreator-debugger-layout.patch } build() { cd build - qmake LLVM_INSTALL_DIR=/usr QBS_INSTALL_DIR=/usr CONFIG+=journald QMAKE_CFLAGS_ISYSTEM=-I \ - DEFINES+=QBS_ENABLE_PROJECT_FILE_UPDATES "$srcdir"/qt-creator-opensource-src-$pkgver/qtcreator.pro + qmake LLVM_INSTALL_DIR=/usr QBS_INSTALL_DIR=/usr \ + KSYNTAXHIGHLIGHTING_LIB_DIR=/usr/lib KSYNTAXHIGHLIGHTING_INCLUDE_DIR=/usr/include/KF5/KSyntaxHighlighting \ + CONFIG+=journald QMAKE_CFLAGS_ISYSTEM=-I \ + DEFINES+=QBS_ENABLE_PROJECT_FILE_UPDATES \ + "$srcdir"/qt-creator-opensource-src-$pkgver/qtcreator.pro make make docs } @@ -84,4 +78,7 @@ package() { make INSTALL_ROOT="$pkgdir/usr/" install_docs install -Dm644 "$srcdir"/qt-creator-opensource-src-$pkgver/LICENSE.GPL3-EXCEPT "$pkgdir"/usr/share/licenses/qtcreator/LICENSE.GPL3-EXCEPT + +# Link clazy plugin explicitely + patchelf --add-needed ClazyPlugin.so "$pkgdir"/usr/lib/qtcreator/clangbackend } diff --git a/qtcreator-clang-plugins.patch b/qtcreator-clang-plugins.patch deleted file mode 100644 index 5dc5b567afa4..000000000000 --- a/qtcreator-clang-plugins.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp -index 25054f14ec..b0e17c3260 100644 ---- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp -+++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp -@@ -524,6 +524,7 @@ private: - if (tidyMode == Mode::Disabled) - return; - -+ addXclangArg("-load", "libclangTidyPlugin.so"); - addXclangArg("-add-plugin", "clang-tidy"); - - if (tidyMode == Mode::File) -@@ -539,7 +540,8 @@ private: - if (checks.isEmpty()) - return; - -- addXclangArg("-add-plugin", "clang-lazy"); -+ addXclangArg("-load", "ClazyPlugin.so"); -+ addXclangArg("-add-plugin", "clazy"); - addXclangArg("-plugin-arg-clang-lazy", "enable-all-fixits"); - addXclangArg("-plugin-arg-clang-lazy", "no-autowrite-fixits"); - addXclangArg("-plugin-arg-clang-lazy", checks); -diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp -index d91724392e..75e1692f49 100644 ---- a/src/plugins/clangtools/clangtidyclazyrunner.cpp -+++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp -@@ -83,6 +83,7 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis - - const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode(); - if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) { -+ addXclangArg(arguments, QString("-load"), QString("libclangTidyPlugin.so")); - addXclangArg(arguments, QString("-add-plugin"), QString("clang-tidy")); - if (tidyMode != ClangDiagnosticConfig::TidyMode::File) { - const QString tidyChecks = m_diagnosticConfig.clangTidyChecks(); -@@ -92,7 +93,8 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis - - const QString clazyChecks = m_diagnosticConfig.clazyChecks(); - if (!clazyChecks.isEmpty()) { -- addXclangArg(arguments, QString("-add-plugin"), QString("clang-lazy")); -+ addXclangArg(arguments, QString("-load"), QString("ClazyPlugin.so")); -+ addXclangArg(arguments, QString("-add-plugin"), QString("clazy")); - addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), QString("enable-all-fixits")); - addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), QString("no-autowrite-fixits")); - addXclangArg(arguments, QString("-plugin-arg-clang-lazy"), m_diagnosticConfig.clazyChecks()); diff --git a/qtcreator-clazy-1.5.patch b/qtcreator-clazy-1.5.patch new file mode 100644 index 000000000000..ce9d2cc0ef69 --- /dev/null +++ b/qtcreator-clazy-1.5.patch @@ -0,0 +1,45 @@ +diff --git a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +index 706c5101a3..dbfaeb8457 100644 +--- a/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp ++++ b/src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp +@@ -527,14 +528,14 @@ private: + return; + + m_options.append(CppTools::XclangArgs({"-add-plugin", +- "clang-lazy", +- "-plugin-arg-clang-lazy", ++ "clazy", ++ "-plugin-arg-clazy", + "enable-all-fixits", +- "-plugin-arg-clang-lazy", ++ "-plugin-arg-clazy", + "no-autowrite-fixits", +- "-plugin-arg-clang-lazy", ++ "-plugin-arg-clazy", + checks, +- "-plugin-arg-clang-lazy", ++ "-plugin-arg-clazy", + "ignore-included-files"})); + } + +diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp +index a580704243..7a8740a5cc 100644 +--- a/src/plugins/clangtools/clangtidyclazyrunner.cpp ++++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp +@@ -86,12 +87,12 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis + const QString clazyChecks = m_diagnosticConfig.clazyChecks(); + if (!clazyChecks.isEmpty()) { + arguments << XclangArgs({"-add-plugin", +- "clang-lazy", +- "-plugin-arg-clang-lazy", ++ "clazy", ++ "-plugin-arg-clazy", + "enable-all-fixits", +- "-plugin-arg-clang-lazy", ++ "-plugin-arg-clazy", + "no-autowrite-fixits", +- "-plugin-arg-clang-lazy", ++ "-plugin-arg-clazy", + m_diagnosticConfig.clazyChecks()}); + } + diff --git a/qtcreator-cmake-edit-fix.patch b/qtcreator-cmake-edit-fix.patch deleted file mode 100644 index 40f59c80e28e..000000000000 --- a/qtcreator-cmake-edit-fix.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp -index 396bc00f68..5f0fad9260 100644 ---- a/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp -+++ b/src/plugins/cmakeprojectmanager/cmakebuildsettingswidget.cpp -@@ -171,6 +171,12 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) - m_configTextFilterModel->setFilterKeyColumn(-1); - m_configTextFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); - -+ connect(m_configTextFilterModel, &QAbstractItemModel::layoutChanged, this, [this]() { -+ QModelIndex selectedIdx = m_configView->currentIndex(); -+ if (selectedIdx.isValid()) -+ m_configView->scrollTo(selectedIdx); -+ }); -+ - m_configView->setModel(m_configTextFilterModel); - m_configView->setMinimumHeight(300); - m_configView->setUniformRowHeights(true); -@@ -307,9 +313,13 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) - value = QString::fromLatin1("OFF"); - - m_configModel->appendConfiguration(tr("<UNSET>"), value, type); -- QModelIndex idx; -- idx = m_configView->model()->index( -- m_configView->model()->rowCount(idx) - 1, 0); -+ const Utils::TreeItem* item = m_configModel->findNonRootItem([&value, type](Utils::TreeItem* item) { -+ ConfigModel::DataItem dataItem = ConfigModel::dataItemFromIndex(item->index()); -+ return dataItem.key == tr("<UNSET>") && dataItem.type == type && dataItem.value == value; -+ }); -+ QModelIndex idx = m_configModel->indexForItem(item); -+ idx = m_configTextFilterModel->mapFromSource(m_configFilterModel->mapFromSource(idx)); -+ m_configView->scrollTo(idx); - m_configView->setCurrentIndex(idx); - m_configView->edit(idx); - }); diff --git a/qtcreator-cmake-fail-target-fix.patch b/qtcreator-cmake-fail-target-fix.patch deleted file mode 100644 index a768fb9033e0..000000000000 --- a/qtcreator-cmake-fail-target-fix.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp -index 21556ce0fd..f319af05d4 100644 ---- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp -+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp -@@ -115,8 +115,10 @@ CMakeRunConfiguration *CMakeBuildStep::targetsActiveRunConfiguration() const - return qobject_cast<CMakeRunConfiguration *>(target()->activeRunConfiguration()); - } - --void CMakeBuildStep::handleBuildTargetChanges() -+void CMakeBuildStep::handleBuildTargetChanges(bool success) - { -+ if (!success) -+ return; // Do not change when parsing failed. - if (isCurrentExecutableTarget(m_buildTarget)) - return; // Do not change just because a different set of build targets is there... - if (!static_cast<CMakeProject *>(project())->buildTargetTitles().contains(m_buildTarget)) -diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h -index cfae9c9aab..91dab9b455 100644 ---- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h -+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h -@@ -101,7 +101,7 @@ private: - void runImpl(QFutureInterface<bool> &fi); - void handleProjectWasParsed(QFutureInterface<bool> &fi, bool success); - -- void handleBuildTargetChanges(); -+ void handleBuildTargetChanges(bool success); - CMakeRunConfiguration *targetsActiveRunConfiguration() const; - - QMetaObject::Connection m_runTrigger; diff --git a/qtcreator-debugger-columns-fix.patch b/qtcreator-debugger-columns-fix.patch deleted file mode 100644 index 4f4a632d7ea3..000000000000 --- a/qtcreator-debugger-columns-fix.patch +++ /dev/null @@ -1,343 +0,0 @@ -diff --git a/src/libs/utils/basetreeview.cpp b/src/libs/utils/basetreeview.cpp -index bae4c16fef..3fc12130b7 100644 ---- a/src/libs/utils/basetreeview.cpp -+++ b/src/libs/utils/basetreeview.cpp -@@ -55,6 +55,42 @@ public: - m_settingsTimer.setSingleShot(true); - connect(&m_settingsTimer, &QTimer::timeout, - this, &BaseTreeViewPrivate::doSaveState); -+ connect(q->header(), &QHeaderView::sectionResized, this, [this](int logicalIndex, int oldSize, int newSize) { -+ if (m_processingSpans || m_spanColumn < 0) -+ return; -+ -+ QHeaderView *h = q->header(); -+ QTC_ASSERT(h, return); -+ -+ // Last non-hidden column. -+ int count = h->count(); -+ while (count > 0 && h->isSectionHidden(count - 1)) -+ --count; -+ -+ if (count == 0) -+ return; -+ -+ int column = logicalIndex; -+ if (oldSize < newSize) -+ { -+ // Protect against sizing past the next section. -+ while (column + 1 < count && h->sectionSize(column + 1) == h->minimumSectionSize()) -+ ++column; -+ } -+ -+ if (logicalIndex >= m_spanColumn) { -+ // Resize after the span column. -+ column = column + 1; -+ } else { -+ // Resize the span column or before it. -+ column = m_spanColumn; -+ } -+ -+ rebalanceColumns(column, false); -+ }); -+ connect(q->header(), &QHeaderView::geometriesChanged, this, [this]() { -+ rebalanceColumns(); -+ }); - } - - bool eventFilter(QObject *, QEvent *event) override -@@ -197,6 +233,17 @@ public: - } - } - -+ void setSpanColumn(int column) -+ { -+ if (column == m_spanColumn) -+ return; -+ -+ m_spanColumn = column; -+ if (m_spanColumn >= 0) -+ q->header()->setStretchLastSection(false); -+ rebalanceColumns(); -+ } -+ - void toggleColumnWidth(int logicalIndex) - { - QHeaderView *h = q->header(); -@@ -211,11 +258,72 @@ public: - int minSize = 10 * fm.width(QLatin1Char('x')); - targetSize = qMax(minSize, headerSize); - } -+ -+ // Prevent rebalance as part of this resize. -+ m_processingSpans = true; - h->resizeSection(logicalIndex, targetSize); -+ m_processingSpans = false; -+ -+ // Now trigger a rebalance so it resizes the span column. (if set) -+ rebalanceColumns(); -+ - m_userHandled.remove(logicalIndex); // Reset. - saveState(); - } - -+ void rebalanceColumns() -+ { -+ rebalanceColumns(m_spanColumn, true); -+ } -+ -+ void rebalanceColumns(int column, bool allowResizePrevious) -+ { -+ if (m_spanColumn < 0 || column < 0 || m_processingSpans) -+ return; -+ -+ QHeaderView *h = q->header(); -+ QTC_ASSERT(h, return); -+ -+ int count = h->count(); -+ if (column >= count) -+ return; -+ -+ // Start with the target column, and resize other columns as necessary. -+ int totalSize = q->viewport()->width(); -+ if (tryRebalanceColumns(column, totalSize)) -+ return; -+ -+ for (int i = allowResizePrevious ? 0 : column + 1; i < count; ++i) { -+ if (i != column && tryRebalanceColumns(i, totalSize)) -+ return; -+ } -+ } -+ -+ bool tryRebalanceColumns(int column, int totalSize) -+ { -+ QHeaderView *h = q->header(); -+ -+ int count = h->count(); -+ int otherColumnTotal = 0; -+ for (int i = 0; i < count; ++i) { -+ if (i != column) -+ otherColumnTotal += h->sectionSize(i); -+ } -+ -+ if (otherColumnTotal < totalSize) { -+ m_processingSpans = true; -+ h->resizeSection(column, totalSize - otherColumnTotal); -+ m_processingSpans = false; -+ } else -+ return false; -+ -+ // Make sure this didn't go over the total size. -+ int totalColumnSize = 0; -+ for (int i = 0; i < count; ++i) -+ totalColumnSize += h->sectionSize(i); -+ return totalColumnSize == totalSize; -+ } -+ - public: - BaseTreeView *q; - QMap<int, int> m_userHandled; // column -> width, "not present" means "automatic" -@@ -224,6 +332,8 @@ public: - QString m_settingsKey; - bool m_expectUserChanges = false; - ProgressIndicator *m_progressIndicator = nullptr; -+ int m_spanColumn = -1; -+ bool m_processingSpans = false; - }; - - class BaseTreeViewDelegate : public QItemDelegate -@@ -369,6 +479,12 @@ void BaseTreeView::mouseDoubleClickEvent(QMouseEvent *ev) - TreeView::mouseDoubleClickEvent(ev); - } - -+void BaseTreeView::resizeEvent(QResizeEvent *ev) -+{ -+ TreeView::resizeEvent(ev); -+ d->rebalanceColumns(); -+} -+ - void BaseTreeView::showEvent(QShowEvent *ev) - { - emit aboutToShow(); -@@ -416,6 +532,21 @@ void BaseTreeView::resizeColumns() - d->resizeColumns(); - } - -+int BaseTreeView::spanColumn() const -+{ -+ return d->m_spanColumn; -+} -+ -+void BaseTreeView::setSpanColumn(int column) -+{ -+ d->setSpanColumn(column); -+} -+ -+void BaseTreeView::refreshSpanColumn() -+{ -+ d->rebalanceColumns(); -+} -+ - void BaseTreeView::setSettings(QSettings *settings, const QByteArray &key) - { - QTC_ASSERT(!d->m_settings, qDebug() << "DUPLICATED setSettings" << key); -diff --git a/src/libs/utils/basetreeview.h b/src/libs/utils/basetreeview.h -index 923c69b042..36da658913 100644 ---- a/src/libs/utils/basetreeview.h -+++ b/src/libs/utils/basetreeview.h -@@ -68,11 +68,19 @@ public: - void dropEvent(QDropEvent *ev) override; - void dragMoveEvent(QDragMoveEvent *ev) override; - void mouseDoubleClickEvent(QMouseEvent *ev) override; -+ void resizeEvent(QResizeEvent *event) override; - - void showProgressIndicator(); - void hideProgressIndicator(); - void resizeColumns(); - -+ int spanColumn() const; -+ void setSpanColumn(int column); -+ -+ // In some situations this needs to be called when manually resizing columns when the span -+ // column is set. -+ void refreshSpanColumn(); -+ - signals: - void aboutToShow(); - -diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp -index 0925cb79e4..0e642e4740 100644 ---- a/src/plugins/debugger/debuggerengine.cpp -+++ b/src/plugins/debugger/debuggerengine.cpp -@@ -647,7 +647,7 @@ void DebuggerEnginePrivate::setupViews() - m_registerWindow->setObjectName(DOCKWIDGET_REGISTER); - m_registerWindow->setWindowTitle(tr("Reg&isters")); - -- m_stackView = new BaseTreeView; -+ m_stackView = new StackTreeView; - m_stackView->setModel(m_stackHandler.model()); - m_stackView->setSettings(settings, "Debugger.StackView"); - m_stackView->setIconSize(QSize(10, 10)); -@@ -671,6 +671,7 @@ void DebuggerEnginePrivate::setupViews() - m_threadsView->setSortingEnabled(true); - m_threadsView->setSettings(settings, "Debugger.ThreadsView"); - m_threadsView->setIconSize(QSize(10, 10)); -+ m_threadsView->setSpanColumn(ThreadData::FunctionColumn); - m_threadsWindow = addSearch(m_threadsView); - m_threadsWindow->setObjectName(DOCKWIDGET_THREADS); - m_threadsWindow->setWindowTitle(tr("&Threads")); -@@ -716,6 +717,7 @@ void DebuggerEnginePrivate::setupViews() - m_breakView->setIconSize(QSize(10, 10)); - m_breakView->setWindowIcon(Icons::BREAKPOINTS.icon()); - m_breakView->setSelectionMode(QAbstractItemView::ExtendedSelection); -+ m_breakView->setSpanColumn(BreakpointFunctionColumn); - connect(action(UseAddressInBreakpointsView), &QAction::toggled, - this, [this](bool on) { m_breakView->setColumnHidden(BreakpointAddressColumn, !on); }); - m_breakView->setSettings(settings, "Debugger.BreakWindow"); -diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp -index 3f7b01d2bd..042ea05804 100644 ---- a/src/plugins/debugger/debuggerplugin.cpp -+++ b/src/plugins/debugger/debuggerplugin.cpp -@@ -1038,6 +1038,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, - m_breakpointManagerView->setSettings(settings, "Debugger.BreakWindow"); - m_breakpointManagerView->setRootIsDecorated(true); - m_breakpointManagerView->setModel(BreakpointManager::model()); -+ m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn); - m_breakpointManagerWindow = addSearch(m_breakpointManagerView); - m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset")); - m_breakpointManagerWindow->setObjectName(DOCKWIDGET_BREAKPOINTMANAGER); -diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp -index 83e6af2829..e25f6aa72b 100644 ---- a/src/plugins/debugger/stackwindow.cpp -+++ b/src/plugins/debugger/stackwindow.cpp -@@ -32,33 +32,56 @@ - #include <utils/savedaction.h> - - #include <QAction> -+#include <QHeaderView> - - namespace Debugger { - namespace Internal { - --StackTreeView::StackTreeView() -+StackTreeView::StackTreeView(QWidget *parent) -+ : BaseTreeView(parent) - { -- setWindowTitle(tr("Stack")); -- - connect(action(UseAddressInStackView), &QAction::toggled, - this, &StackTreeView::showAddressColumn); -+ setSpanColumn(StackFunctionNameColumn); - showAddressColumn(false); - } - -+void StackTreeView::setModel(QAbstractItemModel *model) -+{ -+ BaseTreeView::setModel(model); -+ connect(static_cast<StackHandler*>(model), &StackHandler::stackChanged, -+ this, [this]() { -+ if (!m_contentsAdjusted) -+ adjustForContents(); -+ }); -+ -+ // Resize for the current contents if any are available. -+ showAddressColumn(action(UseAddressInStackView)->isChecked()); -+} -+ - void StackTreeView::showAddressColumn(bool on) - { - setColumnHidden(StackAddressColumn, !on); -- resizeColumnToContents(StackLevelColumn); -- resizeColumnToContents(StackLineNumberColumn); -- resizeColumnToContents(StackAddressColumn); -+ adjustForContents(true); - } - --void StackTreeView::setModel(QAbstractItemModel *model) -+void StackTreeView::adjustForContents(bool refreshSpan) - { -- BaseTreeView::setModel(model); -+ // Skip resizing if no contents. This will be called again once contents are available. -+ if (!model() || model()->rowCount() == 0) { -+ if (refreshSpan) -+ refreshSpanColumn(); -+ return; -+ } -+ -+ // Resize without attempting to fix up the columns. -+ setSpanColumn(-1); - resizeColumnToContents(StackLevelColumn); -+ resizeColumnToContents(StackFileNameColumn); - resizeColumnToContents(StackLineNumberColumn); -- showAddressColumn(action(UseAddressInStackView)->isChecked()); -+ resizeColumnToContents(StackAddressColumn); -+ setSpanColumn(StackFunctionNameColumn); -+ m_contentsAdjusted = true; - } - - } // namespace Internal -diff --git a/src/plugins/debugger/stackwindow.h b/src/plugins/debugger/stackwindow.h -index 5439ead73f..79f2974e82 100644 ---- a/src/plugins/debugger/stackwindow.h -+++ b/src/plugins/debugger/stackwindow.h -@@ -34,17 +34,16 @@ namespace Internal { - - class StackTreeView : public Utils::BaseTreeView - { -- Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::StackTreeView) -- - public: -- StackTreeView(); -+ explicit StackTreeView(QWidget *parent = nullptr); - - private: - void setModel(QAbstractItemModel *model) override; - - void showAddressColumn(bool on); -- void reloadFullStack(); -- void copyContentsToClipboard(); -+ void adjustForContents(bool refreshSpan = false); -+ -+ bool m_contentsAdjusted = false; - }; - - } // namespace Internal diff --git a/qtcreator-debugger-layout.patch b/qtcreator-debugger-layout.patch new file mode 100644 index 000000000000..a1823176162f --- /dev/null +++ b/qtcreator-debugger-layout.patch @@ -0,0 +1,1715 @@ +diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp +index 9a5c84894c..de73c6edaa 100644 +--- a/src/libs/utils/fancymainwindow.cpp ++++ b/src/libs/utils/fancymainwindow.cpp +@@ -523,21 +523,6 @@ bool FancyMainWindow::autoHideTitleBars() const + return d->m_autoHideTitleBars.isChecked(); + } + +-void FancyMainWindow::setAutoHideTitleBars(bool on) +-{ +- d->m_autoHideTitleBars.setChecked(on); +-} +- +-bool FancyMainWindow::isCentralWidgetShown() const +-{ +- return d->m_showCentralWidget.isChecked(); +-} +- +-void FancyMainWindow::showCentralWidget(bool on) +-{ +- d->m_showCentralWidget.setChecked(on); +-} +- + void FancyMainWindow::addDockActionsToMenu(QMenu *menu) + { + QList<QAction *> actions; +diff --git a/src/libs/utils/fancymainwindow.h b/src/libs/utils/fancymainwindow.h +index 4424b1c8bb..623ef42408 100644 +--- a/src/libs/utils/fancymainwindow.h ++++ b/src/libs/utils/fancymainwindow.h +@@ -66,10 +66,6 @@ public: + void addDockActionsToMenu(QMenu *menu); + + bool autoHideTitleBars() const; +- void setAutoHideTitleBars(bool on); +- +- bool isCentralWidgetShown() const; +- void showCentralWidget(bool on); + + signals: + // Emitted by resetLayoutAction(). Connect to a slot +diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp +index b86bb1088e..5f89c07875 100644 +--- a/src/plugins/debugger/debuggerengine.cpp ++++ b/src/plugins/debugger/debuggerengine.cpp +@@ -61,7 +61,6 @@ + #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> + +@@ -281,16 +280,12 @@ public: + m_disassemblerAgent(engine), + m_toolTipManager(engine) + { +- m_debuggerName = DebuggerEngine::tr("Debugger"); +- + m_logWindow = new LogWindow(m_engine); // Needed before start() +- m_logWindow->setObjectName("Debugger.Dock.Output"); ++ m_logWindow->setObjectName(DOCKWIDGET_OUTPUT); ++ m_debuggerName = DebuggerEngine::tr("Debugger"); + +- connect(action(EnableReverseDebugging), &SavedAction::valueChanged, this, [this] { +- updateState(); +- if (m_companionEngine) +- m_companionEngine->d->updateState(); +- }); ++ connect(action(EnableReverseDebugging), &SavedAction::valueChanged, ++ this, [this] { updateState(true); }); + static int contextCount = 0; + m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount)); + +@@ -375,15 +370,17 @@ public: + if (!m_perspective) + return; + +- Perspective *perspective = m_perspective; ++ delete m_perspective; + m_perspective = nullptr; + + EngineManager::unregisterEngine(m_engine); + +- // This triggers activity in the EngineManager which +- // recognizes the rampdown by the m_perpective == nullptr above. +- perspective->destroy(); +- delete perspective; ++ // Give up ownership on claimed breakpoints. ++ m_breakHandler.releaseAllBreakpoints(); ++ m_toolTipManager.deregisterEngine(); ++ m_memoryAgents.handleDebuggerFinished(); ++ ++ setBusyCursor(false); + } + + void updateReturnViewHeader(int section, int, int newSize) +@@ -449,14 +446,14 @@ public: + void setInitialActionStates(); + void setBusyCursor(bool on); + void cleanupViews(); +- void updateState(); ++ void updateState(bool alsoUpdateCompanion); + void updateReverseActions(); + + DebuggerEngine *m_engine = nullptr; // Not owned. + QString m_runId; + QPointer<RunConfiguration> m_runConfiguration; // Not owned. + QString m_debuggerName; +- QPointer<Perspective> m_perspective; ++ Perspective *m_perspective = nullptr; + DebuggerRunParameters m_runParameters; + IDevice::ConstPtr m_device; + +@@ -554,17 +551,16 @@ public: + void DebuggerEnginePrivate::setupViews() + { + const DebuggerRunParameters &rp = m_runParameters; +- const QString engineId = EngineManager::registerEngine(m_engine); + + QTC_CHECK(!m_perspective); + +- const QString perspectiveId = "Debugger.Perspective." + m_runId + '.' + m_debuggerName; +- const QString settingsId = "Debugger.Perspective." + m_debuggerName; +- +- m_perspective = new Perspective(perspectiveId, ++ m_perspective = new Perspective("Debugger.Perspective." + m_runId + '.' + m_debuggerName, + m_engine->displayName(), + Debugger::Constants::PRESET_PERSPECTIVE_ID, +- settingsId); ++ m_debuggerName); ++ m_perspective->setShouldPersistChecker([this] { ++ return EngineManager::isLastOf(m_debuggerName); ++ }); + + m_progress.setProgressRange(0, 1000); + FutureProgress *fp = ProgressManager::addTask(m_progress.future(), +@@ -632,7 +628,7 @@ void DebuggerEnginePrivate::setupViews() + m_engine, &DebuggerEngine::reloadModules, + Qt::QueuedConnection); + m_modulesWindow = addSearch(m_modulesView); +- m_modulesWindow->setObjectName("Debugger.Dock.Modules." + engineId); ++ m_modulesWindow->setObjectName(DOCKWIDGET_MODULES); + m_modulesWindow->setWindowTitle(tr("&Modules")); + + m_registerView = new BaseTreeView; +@@ -643,7 +639,7 @@ void DebuggerEnginePrivate::setupViews() + m_engine, &DebuggerEngine::reloadRegisters, + Qt::QueuedConnection); + m_registerWindow = addSearch(m_registerView); +- m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId); ++ m_registerWindow->setObjectName(DOCKWIDGET_REGISTER); + m_registerWindow->setWindowTitle(tr("Reg&isters")); + + m_stackView = new StackTreeView; +@@ -651,7 +647,7 @@ void DebuggerEnginePrivate::setupViews() + m_stackView->setSettings(settings, "Debugger.StackView"); + m_stackView->setIconSize(QSize(10, 10)); + m_stackWindow = addSearch(m_stackView); +- m_stackWindow->setObjectName("Debugger.Dock.Stack." + engineId); ++ m_stackWindow->setObjectName(DOCKWIDGET_STACK); + m_stackWindow->setWindowTitle(tr("&Stack")); + + m_sourceFilesView = new BaseTreeView; +@@ -662,7 +658,7 @@ void DebuggerEnginePrivate::setupViews() + m_engine, &DebuggerEngine::reloadSourceFiles, + Qt::QueuedConnection); + m_sourceFilesWindow = addSearch(m_sourceFilesView); +- m_sourceFilesWindow->setObjectName("Debugger.Dock.SourceFiles." + engineId); ++ m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES); + m_sourceFilesWindow->setWindowTitle(tr("Source Files")); + + m_threadsView = new BaseTreeView; +@@ -672,7 +668,7 @@ void DebuggerEnginePrivate::setupViews() + m_threadsView->setIconSize(QSize(10, 10)); + m_threadsView->setSpanColumn(ThreadData::FunctionColumn); + m_threadsWindow = addSearch(m_threadsView); +- m_threadsWindow->setObjectName("Debugger.Dock.Threads." + engineId); ++ m_threadsWindow->setObjectName(DOCKWIDGET_THREADS); + m_threadsWindow->setWindowTitle(tr("&Threads")); + + m_returnView = new WatchTreeView{ReturnType}; +@@ -686,26 +682,26 @@ void DebuggerEnginePrivate::setupViews() + m_localsView->setModel(m_watchHandler.model()); + m_localsView->setSettings(settings, "Debugger.LocalsView"); + m_localsWindow = addSearch(m_localsView); +- m_localsWindow->setObjectName("Debugger.Dock.Locals." + engineId); ++ m_localsWindow->setObjectName("CppDebugLocals"); + 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("Debugger.Dock.Inspector." + engineId); ++ m_inspectorWindow->setObjectName("Inspector"); + 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("Debugger.Dock.Watchers." + engineId); ++ m_watchersWindow->setObjectName("CppDebugWatchers"); + m_watchersWindow->setWindowTitle(tr("&Expressions")); + + m_localsAndInspectorWindow = new LocalsAndInspectorWindow( + m_localsWindow, m_inspectorWindow, m_returnWindow); +- m_localsAndInspectorWindow->setObjectName("Debugger.Dock.LocalsAndInspector." + engineId); ++ m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR); + m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle()); + + // Locals +@@ -723,7 +719,7 @@ void DebuggerEnginePrivate::setupViews() + m_breakView->setModel(m_breakHandler.model()); + m_breakView->setRootIsDecorated(true); + m_breakWindow = addSearch(m_breakView); +- m_breakWindow->setObjectName("Debugger.Dock.Break." + engineId); ++ m_breakWindow->setObjectName(DOCKWIDGET_BREAK); + m_breakWindow->setWindowTitle(tr("&Breakpoints")); + + m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser()); +@@ -850,6 +846,7 @@ void DebuggerEnginePrivate::setupViews() + DebuggerEngine::DebuggerEngine() + : d(new DebuggerEnginePrivate(this)) + { ++ updateState(false); + } + + DebuggerEngine::~DebuggerEngine() +@@ -1023,6 +1020,7 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool) + + void DebuggerEngine::start() + { ++ EngineManager::registerEngine(this); + d->m_watchHandler.resetWatchers(); + d->setInitialActionStates(); + setState(EngineSetupRequested); +@@ -1118,7 +1116,7 @@ void DebuggerEngine::abortDebugger() + + void DebuggerEngine::updateUi(bool isCurrentEngine) + { +- updateState(); ++ updateState(false); + if (isCurrentEngine) { + gotoCurrentLocation(); + } else { +@@ -1321,7 +1319,7 @@ void DebuggerEngine::notifyInferiorSpontaneousStop() + { + showMessage("NOTE: INFERIOR SPONTANEOUS STOP"); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state()); +- d->m_perspective->select(); ++ EngineManager::activateEngine(this); + showMessage(tr("Stopped."), StatusBar); + setState(InferiorStopOk); + if (boolSetting(RaiseOnInterrupt)) +@@ -1388,12 +1386,10 @@ void DebuggerEnginePrivate::setInitialActionStates() + m_threadLabel->setEnabled(false); + } + +-void DebuggerEnginePrivate::updateState() ++void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion) + { +- // Can happen in mixed debugging. +- if (!m_threadLabel) ++ if (!m_perspective) + return; +- QTC_ASSERT(m_threadLabel, return); + + const DebuggerState state = m_state; + const bool companionPreventsAction = m_engine->companionPreventsActions(); +@@ -1403,7 +1399,7 @@ void DebuggerEnginePrivate::updateState() + // 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); +@@ -1533,6 +1529,9 @@ void DebuggerEnginePrivate::updateState() + || state == DebuggerFinished + || state == InferiorUnrunnable; + setBusyCursor(!notbusy); ++ ++ if (alsoUpdateCompanion && m_companionEngine) ++ m_companionEngine->updateState(false); + } + + void DebuggerEnginePrivate::updateReverseActions() +@@ -1691,9 +1690,9 @@ void DebuggerEngine::notifyInferiorExited() + d->doShutdownEngine(); + } + +-void DebuggerEngine::updateState() ++void DebuggerEngine::updateState(bool alsoUpdateCompanion) + { +- d->updateState(); ++ d->updateState(alsoUpdateCompanion); + } + + WatchTreeView *DebuggerEngine::inspectorView() +@@ -1794,28 +1793,17 @@ 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(); +- if (d->m_companionEngine) +- d->m_companionEngine->d->updateState(); ++ d->updateState(true); + + 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(); + } +diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h +index 736d2b3c03..12e4356ce0 100644 +--- a/src/plugins/debugger/debuggerengine.h ++++ b/src/plugins/debugger/debuggerengine.h +@@ -416,7 +416,7 @@ protected: + void notifyInferiorStopFailed(); + + public: +- void updateState(); ++ void updateState(bool alsoUpdateCompanion); + QString formatStartParameters() const; + WatchTreeView *inspectorView(); + void updateLocalsWindow(bool showReturn); +diff --git a/src/plugins/debugger/debuggerinternalconstants.h b/src/plugins/debugger/debuggerinternalconstants.h +index 8f6599b653..cb9591e8ad 100644 +--- a/src/plugins/debugger/debuggerinternalconstants.h ++++ b/src/plugins/debugger/debuggerinternalconstants.h +@@ -28,6 +28,24 @@ + #include <QtGlobal> + + namespace Debugger { ++namespace Internal { ++ ++// DebuggerMainWindow dock widget names ++const char DOCKWIDGET_BREAKPOINTMANAGER[] = "Debugger.Docks.BreakpointManager"; ++const char DOCKWIDGET_ENGINEMANAGER[] = "Debugger.Docks.Snapshots"; ++const char DOCKWIDGET_GLOBALLOG[] = "Debugger.Docks.GlobalLog"; ++ ++const char DOCKWIDGET_BREAK[] = "Debugger.Docks.Break"; ++const char DOCKWIDGET_MODULES[] = "Debugger.Docks.Modules"; ++const char DOCKWIDGET_REGISTER[] = "Debugger.Docks.Register"; ++const char DOCKWIDGET_OUTPUT[] = "Debugger.Docks.Output"; ++const char DOCKWIDGET_STACK[] = "Debugger.Docks.Stack"; ++const char DOCKWIDGET_SOURCE_FILES[] = "Debugger.Docks.SourceFiles"; ++const char DOCKWIDGET_THREADS[] = "Debugger.Docks.Threads"; ++const char DOCKWIDGET_LOCALS_AND_INSPECTOR[] = "Debugger.Docks.LocalsAndInspector"; ++ ++} // namespace Internal ++ + namespace Constants { + + const char DEBUGGER_COMMON_SETTINGS_ID[] = "A.Debugger.General"; +diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp +index 598344bb25..7d4175fc95 100644 +--- a/src/plugins/debugger/debuggermainwindow.cpp ++++ b/src/plugins/debugger/debuggermainwindow.cpp +@@ -49,10 +49,9 @@ + + #include <QAction> + #include <QComboBox> +-#include <QContextMenuEvent> ++#include <QDebug> + #include <QDockWidget> + #include <QHBoxLayout> +-#include <QLoggingCategory> + #include <QMenu> + #include <QScrollArea> + #include <QStackedWidget> +@@ -63,57 +62,37 @@ + using namespace Debugger; + using namespace Core; + +-Q_LOGGING_CATEGORY(perspectivesLog, "qtc.utils.perspectives", QtWarningMsg) +- + namespace Utils { + +-const int SettingsVersion = 3; +- + const char LAST_PERSPECTIVE_KEY[] = "LastPerspective"; +-const char MAINWINDOW_KEY[] = "Debugger.MainWindow"; +-const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars"; +-const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget"; +-const char STATE_KEY[] = "State"; +-const char CHANGED_DOCK_KEY[] = "ChangedDocks"; ++const char OWNED_BY_PERSPECTIVE[] = "OwnedByPerspective"; + + static DebuggerMainWindow *theMainWindow = nullptr; + + class DockOperation + { + public: +- void setupLayout(); +- QString name() const { QTC_ASSERT(widget, return QString()); return widget->objectName(); } +- +- Core::Id commandId; + QPointer<QWidget> widget; +- QPointer<QDockWidget> dock; +- QPointer<QWidget> anchorWidget; ++ QString anchorDockId; + Perspective::OperationType operationType = Perspective::Raise; + bool visibleByDefault = true; +- bool visibleByUser = true; + Qt::DockWidgetArea area = Qt::BottomDockWidgetArea; + }; + + class PerspectivePrivate + { + public: +- void showInnerToolBar(); +- void hideInnerToolBar(); ++ void showToolBar(); ++ void hideToolBar(); + void restoreLayout(); + void saveLayout(); +- void resetPerspective(); +- void populatePerspective(); +- void depopulatePerspective(); +- void saveAsLastUsedPerspective(); +- Context context() const; +- + QString settingsId() const; + QToolButton *setupToolButton(QAction *action); + + QString m_id; + QString m_name; + QString m_parentPerspectiveId; +- QString m_settingsId; ++ QString m_subPerspectiveType; + QVector<DockOperation> m_dockOperations; + QPointer<QWidget> m_centralWidget; + Perspective::Callback m_aboutToActivateCallback; +@@ -121,6 +100,8 @@ public: + QHBoxLayout *m_innerToolBarLayout = nullptr; + QPointer<QWidget> m_switcher; + QString m_lastActiveSubPerspectiveId; ++ QHash<QString, QVariant> m_nonPersistenSettings; ++ Perspective::ShouldPersistChecker m_shouldPersistChecker; + }; + + class DebuggerMainWindowPrivate : public QObject +@@ -137,30 +118,20 @@ public: + void registerPerspective(Perspective *perspective); + void resetCurrentPerspective(); + int indexInChooser(Perspective *perspective) const; ++ void fixupLayoutIfNeeded(); + void updatePerspectiveChooserWidth(); + +- void cleanDocks(); +- void setCentralWidget(QWidget *widget); +- +- QDockWidget *dockForWidget(QWidget *widget) const; +- +- void setCurrentPerspective(Perspective *perspective) +- { +- m_currentPerspective = perspective; +- } +- + DebuggerMainWindow *q = nullptr; +- QPointer<Perspective> m_currentPerspective = nullptr; ++ Perspective *m_currentPerspective = nullptr; + QComboBox *m_perspectiveChooser = nullptr; + QStackedWidget *m_centralWidgetStack = nullptr; + QHBoxLayout *m_subPerspectiveSwitcherLayout = nullptr; + QHBoxLayout *m_innerToolsLayout = nullptr; +- QPointer<QWidget> m_editorPlaceHolder; ++ QWidget *m_editorPlaceHolder = nullptr; + Utils::StatusLabel *m_statusLabel = nullptr; + QDockWidget *m_toolBarDock = nullptr; + +- QList<QPointer<Perspective>> m_perspectives; +- QSet<QString> m_persistentChangedDocks; ++ QList<Perspective *> m_perspectives; + }; + + DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) +@@ -240,9 +211,10 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent) + m_toolBarDock = dock; + q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock); + +- connect(viewButton, &QAbstractButton::clicked, this, [this, viewButton] { +- ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS); +- viewsMenu->menu()->exec(viewButton->mapToGlobal(QPoint())); ++ connect(viewButton, &QAbstractButton::clicked, [this, viewButton] { ++ QMenu menu; ++ q->addDockActionsToMenu(&menu); ++ menu.exec(viewButton->mapToGlobal(QPoint())); + }); + + connect(closeButton, &QAbstractButton::clicked, [] { +@@ -284,19 +256,6 @@ DebuggerMainWindow::DebuggerMainWindow() + "Debugger.Views.ResetSimple", debugcontext); + cmd->setAttribute(Command::CA_Hide); + viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); +- +- connect(ICore::instance(), &ICore::saveSettingsRequested, this, [this] { +- // There's one saveSettings triggered after plugin loading intentionally. +- // We do not want to save anything at that time. +- static bool firstOne = true; +- if (firstOne) { +- qCDebug(perspectivesLog) << "FIRST SAVE SETTINGS REQUEST IGNORED"; +- firstOne = false; +- } else { +- qCDebug(perspectivesLog) << "SAVING SETTINGS"; +- savePersistentSettings(); +- } +- }); + } + + DebuggerMainWindow::~DebuggerMainWindow() +@@ -304,12 +263,6 @@ DebuggerMainWindow::~DebuggerMainWindow() + delete d; + } + +-void DebuggerMainWindow::contextMenuEvent(QContextMenuEvent *ev) +-{ +- ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS); +- viewsMenu->menu()->exec(ev->globalPos()); +-} +- + void DebuggerMainWindow::ensureMainWindowExists() + { + if (!theMainWindow) +@@ -318,8 +271,6 @@ void DebuggerMainWindow::ensureMainWindowExists() + + void DebuggerMainWindow::doShutdown() + { +- QTC_ASSERT(theMainWindow, return); +- + delete theMainWindow; + theMainWindow = nullptr; + } +@@ -335,12 +286,9 @@ void DebuggerMainWindowPrivate::registerPerspective(Perspective *perspective) + + void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective) + { +- qCDebug(perspectivesLog) << "ABOUT TO DESTROY PERSPECTIVE" << perspective->id(); +- +- const bool wasCurrent = perspective == m_currentPerspective; +- if (wasCurrent) { +- qCDebug(perspectivesLog) << "RAMPING IT DOWN FIRST AS IT WAS CURRENT" << perspective->id(); +- perspective->rampDownAsCurrent(); ++ if (perspective == m_currentPerspective) { ++ depopulateCurrentPerspective(); ++ m_currentPerspective = nullptr; + } + + m_perspectives.removeAll(perspective); +@@ -350,31 +298,6 @@ void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective) + const int idx = indexInChooser(perspective); + if (idx != -1) + m_perspectiveChooser->removeItem(idx); +- +- for (DockOperation &op : perspective->d->m_dockOperations) { +- if (op.commandId.isValid()) +- ActionManager::unregisterAction(op.dock->toggleViewAction(), op.commandId); +- if (op.dock) { +- theMainWindow->removeDockWidget(op.dock); +- op.widget->setParent(nullptr); // Prevent deletion +- op.dock->setParent(nullptr); +- delete op.dock; +- op.dock = nullptr; +- } +- } +- +- if (wasCurrent) { +- if (Perspective *parent = Perspective::findPerspective(perspective->d->m_parentPerspectiveId)) { +- qCDebug(perspectivesLog) << "RAMPING UP PARENT PERSPECTIVE" << parent->id(); +- parent->rampUpAsCurrent(); +- } else { +- qCDebug(perspectivesLog) << "RAMPED DOWN WAS ACTION, BUT NO PARENT AVAILABLE. TAKE FIRST BEST"; +- if (QTC_GUARD(!m_perspectives.isEmpty())) +- m_perspectives.first()->rampUpAsCurrent(); +- } +- } +- +- qCDebug(perspectivesLog) << "DESTROYED PERSPECTIVE" << perspective->id(); + } + + void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS) +@@ -386,124 +309,34 @@ void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS + void DebuggerMainWindow::enterDebugMode() + { + theMainWindow->setDockActionsVisible(true); +- theMainWindow->restorePersistentSettings(); +- QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr); +- +- QSettings *settings = ICore::settings(); +- const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString(); +- Perspective *perspective = Perspective::findPerspective(lastPerspectiveId); +- // If we don't find a perspective with the stored name, pick any. +- // This can happen e.g. when a plugin was disabled that provided +- // the stored perspective, or when the save file was modified externally. +- if (!perspective && !theMainWindow->d->m_perspectives.isEmpty()) +- perspective = theMainWindow->d->m_perspectives.first(); +- ++ Perspective *perspective = theMainWindow->d->m_currentPerspective; ++ if (!perspective) { ++ const QSettings *settings = ICore::settings(); ++ const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString(); ++ perspective = Perspective::findPerspective(lastPerspectiveId); ++ // If we don't find a perspective with the stored name, pick any. ++ // This can happen e.g. when a plugin was disabled that provided ++ // the stored perspective, or when the save file was modified externally. ++ if (!perspective && !theMainWindow->d->m_perspectives.isEmpty()) ++ perspective = theMainWindow->d->m_perspectives.first(); ++ } + // There's at least the debugger preset perspective that should be found above. + QTC_ASSERT(perspective, return); +- +- if (auto sub = Perspective::findPerspective(perspective->d->m_lastActiveSubPerspectiveId)) { +- qCDebug(perspectivesLog) << "SWITCHING TO SUBPERSPECTIVE" << sub->d->m_id; +- perspective = sub; +- } +- +- perspective->rampUpAsCurrent(); ++ perspective->select(); + } + + void DebuggerMainWindow::leaveDebugMode() + { +- theMainWindow->savePersistentSettings(); +- +- if (theMainWindow->d->m_currentPerspective) +- theMainWindow->d->m_currentPerspective->rampDownAsCurrent(); +- QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr); ++ if (Perspective *perspective = theMainWindow->d->m_currentPerspective) ++ perspective->d->saveLayout(); + + theMainWindow->setDockActionsVisible(false); + + // Hide dock widgets manually in case they are floating. + for (QDockWidget *dockWidget : theMainWindow->dockWidgets()) { + if (dockWidget->isFloating()) +- dockWidget->setVisible(false); +- } +-} +- +-void DebuggerMainWindow::restorePersistentSettings() +-{ +- qCDebug(perspectivesLog) << "RESTORE PERSISTENT"; +- QSettings *settings = ICore::settings(); +- settings->beginGroup(MAINWINDOW_KEY); +- const bool res = theMainWindow->restoreState(settings->value(STATE_KEY).toByteArray(), +- SettingsVersion); +- if (!res) +- qCDebug(perspectivesLog) << "NO READABLE PERSISTENT SETTINGS FOUND, ASSUMING NEW CLEAN SETTINGS"; +- +- theMainWindow->setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool()); +- theMainWindow->showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool()); +- theMainWindow->d->m_persistentChangedDocks +- = QSet<QString>::fromList(settings->value(CHANGED_DOCK_KEY).toStringList()); +- settings->endGroup(); +- +- qCDebug(perspectivesLog) << "LOADED DOCKS:" << theMainWindow->d->m_persistentChangedDocks; +- +- QTC_ASSERT(theMainWindow, return); +- QTC_ASSERT(theMainWindow->d, return); +- for (Perspective *perspective : theMainWindow->d->m_perspectives) { +- QTC_ASSERT(perspective, continue); +- qCDebug(perspectivesLog) << "RESTORING PERSPECTIVE" << perspective->d->m_id; +- for (DockOperation &op : perspective->d->m_dockOperations) { +- if (op.operationType != Perspective::Raise) { +- QTC_ASSERT(op.dock, continue); +- QTC_ASSERT(op.widget, continue); +- if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) { +- qCDebug(perspectivesLog) << "DOCK " << op.name() << "*** UNUSUAL"; +- op.visibleByUser = !op.visibleByDefault; +- } else { +- qCDebug(perspectivesLog) << "DOCK " << op.name() << "NORMAL"; +- QTC_CHECK(op.visibleByUser == op.visibleByDefault); +- } +- } +- } +- } +-} +- +-Perspective *DebuggerMainWindow::currentPerspective() +-{ +- return theMainWindow->d->m_currentPerspective; +-} +- +-void DebuggerMainWindow::savePersistentSettings() +-{ +- // The current one might have active, non saved changes. +- if (Perspective *perspective = theMainWindow->d->m_currentPerspective) +- perspective->d->saveLayout(); +- +- qCDebug(perspectivesLog) << "SAVE PERSISTENT"; +- +- QSet<QString> changedDocks = theMainWindow->d->m_persistentChangedDocks; +- for (Perspective *perspective : theMainWindow->d->m_perspectives) { +- QTC_ASSERT(perspective, continue); +- qCDebug(perspectivesLog) << "SAVE PERSPECTIVE" << perspective->d->m_id; +- for (const DockOperation &op : perspective->d->m_dockOperations) { +- if (op.operationType != Perspective::Raise) { +- QTC_ASSERT(op.dock, continue); +- QTC_ASSERT(op.widget, continue); +- qCDebug(perspectivesLog) << "DOCK " << op.name() << "ACTIVE: " << op.visibleByUser; +- if (op.visibleByUser != op.visibleByDefault) +- changedDocks.insert(op.name()); +- else +- changedDocks.remove(op.name()); +- } +- } ++ dockWidget->hide(); + } +- theMainWindow->d->m_persistentChangedDocks = changedDocks; +- qCDebug(perspectivesLog) << "CHANGED DOCKS:" << changedDocks; +- +- QSettings *settings = ICore::settings(); +- settings->beginGroup(MAINWINDOW_KEY); +- settings->setValue(CHANGED_DOCK_KEY, QStringList(changedDocks.toList())); +- settings->setValue(STATE_KEY, theMainWindow->saveState(SettingsVersion)); +- settings->setValue(AUTOHIDE_TITLEBARS_KEY, theMainWindow->autoHideTitleBars()); +- settings->setValue(SHOW_CENTRALWIDGET_KEY, theMainWindow->isCentralWidgetShown()); +- settings->endGroup(); + } + + QWidget *DebuggerMainWindow::centralWidgetStack() +@@ -525,100 +358,67 @@ DebuggerMainWindow *DebuggerMainWindow::instance() + + Perspective *Perspective::findPerspective(const QString &perspectiveId) + { +- QTC_ASSERT(theMainWindow, return nullptr); +- return Utils::findOr(theMainWindow->d->m_perspectives, nullptr, +- [perspectiveId](Perspective *perspective) { +- return perspective && perspective->d->m_id == perspectiveId; ++ return Utils::findOr(theMainWindow->d->m_perspectives, nullptr, [&](Perspective *perspective) { ++ return perspective->d->m_id == perspectiveId; + }); + } + +-bool Perspective::isCurrent() const +-{ +- return theMainWindow->d->m_currentPerspective == this; +-} +- +-QDockWidget *DebuggerMainWindowPrivate::dockForWidget(QWidget *widget) const ++void DebuggerMainWindowPrivate::resetCurrentPerspective() + { +- QTC_ASSERT(widget, return nullptr); +- +- for (QDockWidget *dock : q->dockWidgets()) { +- if (dock->widget() == widget) +- return dock; ++ if (m_currentPerspective) { ++ m_currentPerspective->d->m_nonPersistenSettings.clear(); ++ m_currentPerspective->d->hideToolBar(); + } +- +- return nullptr; ++ depopulateCurrentPerspective(); ++ populateCurrentPerspective(); ++ if (m_currentPerspective) ++ m_currentPerspective->d->saveLayout(); + } + +-void DebuggerMainWindowPrivate::resetCurrentPerspective() ++int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const + { +- QTC_ASSERT(m_currentPerspective, return); +- cleanDocks(); +- m_currentPerspective->d->resetPerspective(); +- setCentralWidget(m_currentPerspective->d->m_centralWidget); ++ return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1; + } + +-void DebuggerMainWindowPrivate::setCentralWidget(QWidget *widget) ++void DebuggerMainWindowPrivate::fixupLayoutIfNeeded() + { +- if (widget) { +- m_centralWidgetStack->addWidget(widget); +- q->showCentralWidgetAction()->setText(widget->windowTitle()); +- } else { +- m_centralWidgetStack->addWidget(m_editorPlaceHolder); +- q->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor")); ++ // Evil workaround for QTCREATORBUG-21455: In some so far unknown situation ++ // the saveLayout/restoreLayout process leads to a situation where some docks ++ // do not end up below the perspective toolbar even though they were there ++ // initially, leading to an awkward dock layout. ++ // This here tries to detect the situation (sonmething else in the bottom ++ // area is at the right of the toolbar) "corrects" that by restoring the ++ // default layout. ++ ++ if (m_toolBarDock->width() != q->width()) { ++ qDebug() << "Scrambled dock layout found. Resetting it."; ++ resetCurrentPerspective(); + } + } + +-void PerspectivePrivate::resetPerspective() ++void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective) + { +- showInnerToolBar(); ++ QTC_ASSERT(perspective, return); + +- for (DockOperation &op : m_dockOperations) { +- if (op.operationType == Perspective::Raise) { +- QTC_ASSERT(op.dock, qCDebug(perspectivesLog) << op.name(); continue); +- op.dock->raise(); +- } else { +- op.setupLayout(); +- op.dock->setVisible(op.visibleByDefault); +- qCDebug(perspectivesLog) << "SETTING " << op.name() +- << " TO ACTIVE: " << op.visibleByDefault; +- } ++ if (m_currentPerspective) { ++ m_currentPerspective->d->saveLayout(); ++ m_currentPerspective->d->hideToolBar(); + } +-} + +-void DockOperation::setupLayout() +-{ +- QTC_ASSERT(widget, return); +- QTC_ASSERT(operationType != Perspective::Raise, return); +- QTC_ASSERT(dock, return); ++ depopulateCurrentPerspective(); + +- QDockWidget *anchor = nullptr; +- if (anchorWidget) +- anchor = theMainWindow->d->dockForWidget(anchorWidget); +- else if (area == Qt::BottomDockWidgetArea) +- anchor = theMainWindow->d->m_toolBarDock; +- +- if (anchor) { +- switch (operationType) { +- case Perspective::AddToTab: +- theMainWindow->tabifyDockWidget(anchor, dock); +- break; +- case Perspective::SplitHorizontal: +- theMainWindow->splitDockWidget(anchor, dock, Qt::Horizontal); +- break; +- case Perspective::SplitVertical: +- theMainWindow->splitDockWidget(anchor, dock, Qt::Vertical); +- break; +- default: +- break; +- } +- } else { +- theMainWindow->addDockWidget(area, dock); ++ m_currentPerspective = perspective; ++ ++ perspective->aboutToActivate(); ++ ++ populateCurrentPerspective(); ++ ++ if (m_currentPerspective) { ++ m_currentPerspective->d->restoreLayout(); ++ fixupLayoutIfNeeded(); + } +-} + +-int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const +-{ +- return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1; ++ updatePerspectiveChooserWidth(); + } + + void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth() +@@ -644,72 +444,111 @@ void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth() + } + } + +-void DebuggerMainWindowPrivate::cleanDocks() ++void DebuggerMainWindowPrivate::depopulateCurrentPerspective() + { +- m_statusLabel->clear(); +- ++ // Clean up old perspective. + for (QDockWidget *dock : q->dockWidgets()) { +- if (dock != m_toolBarDock) +- dock->setVisible(false); ++ if (dock->property(OWNED_BY_PERSPECTIVE).toBool()) { ++ // Prevent deletion of plugin-owned widgets. ++ if (dock->widget()) ++ dock->widget()->setParent(nullptr); ++ ActionManager::unregisterAction(dock->toggleViewAction(), ++ Id("Dock.").withSuffix(dock->objectName())); ++ delete dock; ++ } + } +-} +- +-void PerspectivePrivate::depopulatePerspective() +-{ +- ICore::removeAdditionalContext(context()); +- theMainWindow->d->m_centralWidgetStack +- ->removeWidget(m_centralWidget ? m_centralWidget : theMainWindow->d->m_editorPlaceHolder); + +- theMainWindow->d->m_statusLabel->clear(); +- +- for (QDockWidget *dock : theMainWindow->dockWidgets()) { +- if (dock != theMainWindow->d->m_toolBarDock) +- dock->setVisible(false); ++ if (m_currentPerspective) { ++ ICore::removeAdditionalContext(m_currentPerspective->context()); ++ QWidget *central = m_currentPerspective->centralWidget(); ++ m_centralWidgetStack->removeWidget(central ? central : m_editorPlaceHolder); + } +- +- hideInnerToolBar(); + } + +-void PerspectivePrivate::saveAsLastUsedPerspective() +-{ +- if (Perspective *parent = Perspective::findPerspective(m_parentPerspectiveId)) +- parent->d->m_lastActiveSubPerspectiveId = m_id; +- else +- m_lastActiveSubPerspectiveId.clear(); ++void DebuggerMainWindowPrivate::populateCurrentPerspective() ++{ ++ // Create dock widgets wrapping ther perspective's widgets. ++ QHash<QString, QDockWidget *> dockForDockId; ++ for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) { ++ if (op.operationType == Perspective::Raise) ++ continue; ++ QTC_ASSERT(op.widget, continue); ++ const QString dockId = op.widget->objectName(); ++ QTC_CHECK(!dockId.isEmpty()); ++ QTC_ASSERT(!dockForDockId.contains(dockId), continue); ++ QDockWidget *dock = q->addDockForWidget(op.widget); ++ dock->setProperty(OWNED_BY_PERSPECTIVE, true); ++ dockForDockId[dockId] = dock; ++ q->addDockWidget(op.area, dock); ++ ++ QAction *toggleViewAction = dock->toggleViewAction(); ++ toggleViewAction->setText(dock->windowTitle()); ++ ++ Command *cmd = ActionManager::registerAction(toggleViewAction, ++ Id("Dock.").withSuffix(dock->objectName()), ++ m_currentPerspective->context()); ++ cmd->setAttribute(Command::CA_Hide); ++ ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd); ++ } + +- const QString &lastKey = m_parentPerspectiveId.isEmpty() ? m_id : m_parentPerspectiveId; +- qCDebug(perspectivesLog) << "SAVE LAST USED PERSPECTIVE" << lastKey; +- ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey); +-} ++ m_currentPerspective->d->showToolBar(); + +-void PerspectivePrivate::populatePerspective() +-{ +- showInnerToolBar(); ++ // Pre-arrange dock widgets. ++ for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) { ++ QTC_ASSERT(op.widget, continue); ++ const QString dockId = op.widget->objectName(); ++ QDockWidget *dock = dockForDockId.value(dockId); ++ QTC_ASSERT(dock, continue); ++ if (op.operationType == Perspective::Raise) { ++ dock->raise(); ++ continue; ++ } ++ QDockWidget *anchor = dockForDockId.value(op.anchorDockId); ++ if (!anchor && op.area == Qt::BottomDockWidgetArea) { ++ anchor = m_toolBarDock; ++ } + +- if (m_centralWidget) { +- theMainWindow->d->m_centralWidgetStack->addWidget(m_centralWidget); +- theMainWindow->showCentralWidgetAction()->setText(m_centralWidget->windowTitle()); +- } else { +- theMainWindow->d->m_centralWidgetStack->addWidget(theMainWindow->d->m_editorPlaceHolder); +- theMainWindow->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor")); ++ if (anchor) { ++ switch (op.operationType) { ++ case Perspective::AddToTab: ++ q->tabifyDockWidget(anchor, dock); ++ break; ++ case Perspective::SplitHorizontal: ++ q->splitDockWidget(anchor, dock, Qt::Horizontal); ++ break; ++ case Perspective::SplitVertical: ++ q->splitDockWidget(anchor, dock, Qt::Vertical); ++ break; ++ default: ++ break; ++ } ++ } ++ dock->setVisible(op.visibleByDefault); + } + +- ICore::addAdditionalContext(context()); ++ QWidget *central = m_currentPerspective->centralWidget(); ++ m_centralWidgetStack->addWidget(central ? central : m_editorPlaceHolder); ++ q->showCentralWidgetAction()->setText(central ? central->windowTitle() ++ : DebuggerMainWindow::tr("Editor")); ++ ++ m_statusLabel->clear(); + +- restoreLayout(); ++ ICore::addAdditionalContext(m_currentPerspective->context()); + } + + // Perspective + + Perspective::Perspective(const QString &id, const QString &name, + const QString &parentPerspectiveId, +- const QString &settingsId) ++ const QString &subPerspectiveType) + : d(new PerspectivePrivate) + { ++ const bool shouldPersist = parentPerspectiveId.isEmpty(); + d->m_id = id; + d->m_name = name; + d->m_parentPerspectiveId = parentPerspectiveId; +- d->m_settingsId = settingsId; ++ d->m_subPerspectiveType = subPerspectiveType; ++ d->m_shouldPersistChecker = [shouldPersist] { return shouldPersist; }; + + DebuggerMainWindow::ensureMainWindowExists(); + theMainWindow->d->registerPerspective(this); +@@ -726,8 +565,12 @@ Perspective::Perspective(const QString &id, const QString &name, + Perspective::~Perspective() + { + if (theMainWindow) { ++ d->saveLayout(); ++ + delete d->m_innerToolBar; + d->m_innerToolBar = nullptr; ++ ++ theMainWindow->d->destroyPerspective(this); + } + delete d; + } +@@ -753,6 +596,12 @@ void Perspective::setAboutToActivateCallback(const Perspective::Callback &cb) + d->m_aboutToActivateCallback = cb; + } + ++void Perspective::aboutToActivate() const ++{ ++ if (d->m_aboutToActivateCallback) ++ d->m_aboutToActivateCallback(); ++} ++ + void Perspective::setEnabled(bool enabled) + { + QTC_ASSERT(theMainWindow, return); +@@ -805,24 +654,34 @@ void Perspective::addToolbarSeparator() + d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar)); + } + ++void Perspective::setShouldPersistChecker(const ShouldPersistChecker &checker) ++{ ++ d->m_shouldPersistChecker = checker; ++} ++ + QWidget *Perspective::centralWidget() const + { + return d->m_centralWidget; + } + +-Context PerspectivePrivate::context() const ++Perspective *Perspective::currentPerspective() + { +- return Context(Id::fromName(m_id.toUtf8())); ++ return theMainWindow ? theMainWindow->d->m_currentPerspective : nullptr; + } + +-void PerspectivePrivate::showInnerToolBar() ++Context Perspective::context() const ++{ ++ return Context(Id::fromName(d->m_id.toUtf8())); ++} ++ ++void PerspectivePrivate::showToolBar() + { + m_innerToolBar->setVisible(true); + if (m_switcher) + m_switcher->setVisible(true); + } + +-void PerspectivePrivate::hideInnerToolBar() ++void PerspectivePrivate::hideToolBar() + { + QTC_ASSERT(m_innerToolBar, return); + m_innerToolBar->setVisible(false); +@@ -839,131 +698,63 @@ void Perspective::addWindow(QWidget *widget, + QTC_ASSERT(widget, return); + DockOperation op; + op.widget = widget; ++ if (anchorWidget) ++ op.anchorDockId = anchorWidget->objectName(); + op.operationType = type; +- op.anchorWidget = anchorWidget; + op.visibleByDefault = visibleByDefault; + op.area = area; +- +- if (op.operationType != Perspective::Raise) { +- qCDebug(perspectivesLog) << "CREATING DOCK " << op.name() +- << "DEFAULT: " << op.visibleByDefault; +- op.dock = theMainWindow->addDockForWidget(op.widget); +- op.commandId = Id("Dock.").withSuffix(op.name()); +- if (theMainWindow->restoreDockWidget(op.dock)) { +- qCDebug(perspectivesLog) << "RESTORED SUCCESSFULLY"; +- } else { +- qCDebug(perspectivesLog) << "COULD NOT RESTORE"; +- op.setupLayout(); +- } +- op.dock->setVisible(false); +- op.dock->toggleViewAction()->setText(op.dock->windowTitle()); +- +- QObject::connect(op.dock->toggleViewAction(), &QAction::changed, op.dock, [this, op] { +- qCDebug(perspectivesLog) << "CHANGED: " << op.name() +- << "ACTION CHECKED: " << op.dock->toggleViewAction()->isChecked(); +- }); +- +- Command *cmd = ActionManager::registerAction(op.dock->toggleViewAction(), +- op.commandId, d->context()); +- cmd->setAttribute(Command::CA_Hide); +- ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd); +- } +- +- op.visibleByUser = op.visibleByDefault; +- if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) { +- op.visibleByUser = !op.visibleByUser; +- qCDebug(perspectivesLog) << "*** NON-DEFAULT USER: " << op.visibleByUser; +- } else { +- qCDebug(perspectivesLog) << "DEFAULT USER"; +- } +- + d->m_dockOperations.append(op); + } + +-void Perspective::destroy() +-{ +- theMainWindow->d->destroyPerspective(this); +-} +- +-void Perspective::rampDownAsCurrent() +-{ +- QTC_ASSERT(this == theMainWindow->d->m_currentPerspective, return); +- d->saveLayout(); +- d->depopulatePerspective(); +- theMainWindow->d->setCurrentPerspective(nullptr); +- +- Debugger::Internal::EngineManager::updatePerspectives(); +-} +- +-void Perspective::rampUpAsCurrent() +-{ +- if (d->m_aboutToActivateCallback) +- d->m_aboutToActivateCallback(); +- +- QTC_ASSERT(theMainWindow->d->m_currentPerspective == nullptr, return); +- theMainWindow->d->setCurrentPerspective(this); +- QTC_ASSERT(theMainWindow->d->m_currentPerspective == this, return); +- +- d->populatePerspective(); +- +- theMainWindow->d->updatePerspectiveChooserWidth(); +- +- d->saveAsLastUsedPerspective(); +- +- Debugger::Internal::EngineManager::updatePerspectives(); +-} +- + void Perspective::select() + { + Debugger::Internal::EngineManager::activateDebugMode(); +- +- if (theMainWindow->d->m_currentPerspective == this) ++ if (Perspective::currentPerspective() == this) + return; ++ theMainWindow->d->selectPerspective(this); ++ if (Perspective *parent = Perspective::findPerspective(d->m_parentPerspectiveId)) ++ parent->d->m_lastActiveSubPerspectiveId = d->m_id; ++ else ++ d->m_lastActiveSubPerspectiveId.clear(); + +- if (theMainWindow->d->m_currentPerspective) +- theMainWindow->d->m_currentPerspective->rampDownAsCurrent(); +- QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr); +- +- rampUpAsCurrent(); ++ const QString &lastKey = d->m_parentPerspectiveId.isEmpty() ? d->m_id : d->m_parentPerspectiveId; ++ ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey); + } + + void PerspectivePrivate::restoreLayout() + { +- qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "RESTORING LAYOUT FROM " << settingsId(); +- for (DockOperation &op : m_dockOperations) { +- if (op.operationType != Perspective::Raise) { +- QTC_ASSERT(op.dock, continue); +- const bool active = op.visibleByUser; +- op.dock->toggleViewAction()->setChecked(active); +- op.dock->setVisible(active); +- qCDebug(perspectivesLog) << "RESTORE DOCK " << op.name() << "ACTIVE: " << active +- << (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER"); +- } ++ if (m_nonPersistenSettings.isEmpty()) { ++ //qDebug() << "PERSPECTIVE" << m_id << "RESTORE PERSISTENT FROM " << settingsId(); ++ QSettings *settings = ICore::settings(); ++ settings->beginGroup(settingsId()); ++ theMainWindow->restoreSettings(settings); ++ settings->endGroup(); ++ m_nonPersistenSettings = theMainWindow->saveSettings(); ++ } else { ++ //qDebug() << "PERSPECTIVE" << m_id << "RESTORE FROM LOCAL TEMP"; ++ theMainWindow->restoreSettings(m_nonPersistenSettings); + } + } + + void PerspectivePrivate::saveLayout() + { +- qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "SAVE LAYOUT TO " << settingsId(); +- for (DockOperation &op : m_dockOperations) { +- if (op.operationType != Perspective::Raise) { +- QTC_ASSERT(op.dock, continue); +- QTC_ASSERT(op.widget, continue); +- const bool active = op.dock->toggleViewAction()->isChecked(); +- op.visibleByUser = active; +- if (active == op.visibleByDefault) +- theMainWindow->d->m_persistentChangedDocks.remove(op.name()); +- else +- theMainWindow->d->m_persistentChangedDocks.insert(op.name()); +- qCDebug(perspectivesLog) << "SAVE DOCK " << op.name() << "ACTIVE: " << active +- << (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER"); +- } ++ //qDebug() << "PERSPECTIVE" << m_id << "SAVE LOCAL TEMP"; ++ m_nonPersistenSettings = theMainWindow->saveSettings(); ++ ++ if (m_shouldPersistChecker()) { ++ //qDebug() << "PERSPECTIVE" << m_id << "SAVE PERSISTENT TO " << settingsId(); ++ QSettings *settings = ICore::settings(); ++ settings->beginGroup(settingsId()); ++ theMainWindow->saveSettings(settings); ++ settings->endGroup(); ++ } else { ++ //qDebug() << "PERSPECTIVE" << m_id << "NOT PERSISTENT"; + } + } + + QString PerspectivePrivate::settingsId() const + { +- return m_settingsId.isEmpty() ? m_id : m_settingsId; ++ return m_parentPerspectiveId.isEmpty() ? m_id : (m_parentPerspectiveId + '.' + m_subPerspectiveType); + } + + // ToolbarAction +diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h +index 116eb73717..98ff0a37d1 100644 +--- a/src/plugins/debugger/debuggermainwindow.h ++++ b/src/plugins/debugger/debuggermainwindow.h +@@ -59,12 +59,12 @@ public: + QPointer<QToolButton> m_toolButton; + }; + +-class DEBUGGER_EXPORT Perspective : public QObject ++class DEBUGGER_EXPORT Perspective + { + public: + Perspective(const QString &id, const QString &name, + const QString &parentPerspectiveId = QString(), +- const QString &settingId = QString()); ++ const QString &subPerspectiveType = QString()); + ~Perspective(); + + enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise }; +@@ -92,26 +92,26 @@ public: + + using Callback = std::function<void()>; + void setAboutToActivateCallback(const Callback &cb); ++ void aboutToActivate() const; + + void setEnabled(bool enabled); + + void select(); +- void destroy(); + ++ static Perspective *currentPerspective(); + static Perspective *findPerspective(const QString &perspectiveId); + +- bool isCurrent() const; ++ Core::Context context() const; + +-private: +- void rampDownAsCurrent(); +- void rampUpAsCurrent(); ++ void showToolBar(); ++ void hideToolBar(); + ++private: + Perspective(const Perspective &) = delete; + void operator=(const Perspective &) = delete; + + friend class DebuggerMainWindow; + friend class DebuggerMainWindowPrivate; +- friend class PerspectivePrivate; + class PerspectivePrivate *d = nullptr; + }; + +@@ -132,20 +132,12 @@ public: + static QWidget *centralWidgetStack(); + void addSubPerspectiveSwitcher(QWidget *widget); + +- static void savePersistentSettings(); +- static void restorePersistentSettings(); +- +- static Perspective *currentPerspective(); +- + private: + DebuggerMainWindow(); + ~DebuggerMainWindow() override; + +- void contextMenuEvent(QContextMenuEvent *ev) override; +- + friend class Perspective; + friend class PerspectivePrivate; +- friend class DockOperation; + class DebuggerMainWindowPrivate *d = nullptr; + }; + +diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp +index 322a87277c..89c0dff58f 100644 +--- a/src/plugins/debugger/debuggerplugin.cpp ++++ b/src/plugins/debugger/debuggerplugin.cpp +@@ -1046,7 +1046,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, + m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn); + m_breakpointManagerWindow = addSearch(m_breakpointManagerView); + m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset")); +- m_breakpointManagerWindow->setObjectName("Debugger.Docks.BreakpointManager"); ++ m_breakpointManagerWindow->setObjectName(DOCKWIDGET_BREAKPOINTMANAGER); + addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle()); + + +@@ -1058,7 +1058,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, + m_engineManagerView->setModel(m_engineManager.model()); + m_engineManagerWindow = addSearch(m_engineManagerView); + m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives")); +- m_engineManagerWindow->setObjectName("Debugger.Docks.Snapshots"); ++ m_engineManagerWindow->setObjectName(DOCKWIDGET_ENGINEMANAGER); + addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle()); + + // Logging +@@ -1357,8 +1357,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments, + DebuggerMainWindow::leaveDebugMode(); + }); + +- connect(ModeManager::instance(), &ModeManager::currentModeChanged, [](Id mode, Id oldMode) { +- QTC_ASSERT(mode != oldMode, return); ++ connect(ModeManager::instance(), &ModeManager::currentModeChanged, this, [](Id mode) { + if (mode == MODE_DEBUG) { + DebuggerMainWindow::enterDebugMode(); + if (IEditor *editor = EditorManager::currentEditor()) +@@ -1523,7 +1522,7 @@ void DebuggerPluginPrivate::updatePresetState() + } else { + // The startup phase should be over once we are here. + // But treat it as 'undisturbable if we are here by accident. +- //QTC_CHECK(state != DebuggerNotReady); ++ QTC_CHECK(state != DebuggerNotReady); + // Everything else is "undisturbable". + m_startAction.setEnabled(false); + m_debugWithoutDeployAction.setEnabled(false); +@@ -1561,7 +1560,7 @@ void DebuggerPluginPrivate::onStartupProjectChanged(Project *project) + } + for (DebuggerEngine *engine : EngineManager::engines()) { + // Run controls might be deleted during exit. +- engine->updateState(); ++ engine->updateState(false); + } + + updatePresetState(); +@@ -2016,9 +2015,11 @@ void DebuggerPluginPrivate::aboutToShutdown() + m_shutdownTimer.setInterval(0); + m_shutdownTimer.setSingleShot(true); + connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown); +- if (EngineManager::shutDown()) { +- // If any engine is aborting we give them extra three seconds. +- m_shutdownTimer.setInterval(3000); ++ for (DebuggerEngine *engine : m_engineManager.engines()) { ++ if (engine && engine->state() != Debugger::DebuggerNotReady) { ++ engine->abortDebugger(); ++ m_shutdownTimer.setInterval(3000); ++ } + } + m_shutdownTimer.start(); + } +diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp +index ca76e8cfe1..c72fcb6228 100644 +--- a/src/plugins/debugger/debuggerruncontrol.cpp ++++ b/src/plugins/debugger/debuggerruncontrol.cpp +@@ -728,6 +728,8 @@ void DebuggerRunTool::stop() + + void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine) + { ++ EngineManager::activateEngine(engine); ++ + // Correct: + // if (--d->engineStartsNeeded == 0) { + // EngineManager::activateDebugMode(); +diff --git a/src/plugins/debugger/enginemanager.cpp b/src/plugins/debugger/enginemanager.cpp +index 0ca42d64a7..68a31bde14 100644 +--- a/src/plugins/debugger/enginemanager.cpp ++++ b/src/plugins/debugger/enginemanager.cpp +@@ -155,14 +155,14 @@ public: + } + + EngineItem *findEngineItem(DebuggerEngine *engine); ++ void activateEngine(DebuggerEngine *engine); + void activateEngineItem(EngineItem *engineItem); + void activateEngineByIndex(int index); + void selectUiForCurrentEngine(); + void updateEngineChooserVisibility(); +- void updatePerspectives(); + + TreeModel<TypedTreeItem<EngineItem>, EngineItem> m_engineModel; +- QPointer<EngineItem> m_currentItem; // The primary information is DebuggerMainWindow::d->m_currentPerspective ++ QPointer<EngineItem> m_currentItem; + Core::Id m_previousMode; + QPointer<QComboBox> m_engineChooser; + bool m_shuttingDown = false; +@@ -200,11 +200,6 @@ QWidget *EngineManager::engineChooser() + return d->m_engineChooser; + } + +-void EngineManager::updatePerspectives() +-{ +- d->updatePerspectives(); +-} +- + EngineManager::~EngineManager() + { + theEngineManager = nullptr; +@@ -221,6 +216,11 @@ QAbstractItemModel *EngineManager::model() + return &d->m_engineModel; + } + ++void EngineManager::activateEngine(DebuggerEngine *engine) ++{ ++ d->activateEngine(engine); ++} ++ + QVariant EngineItem::data(int column, int role) const + { + if (m_engine) { +@@ -281,7 +281,7 @@ bool EngineItem::setData(int row, const QVariant &value, int role) + + if (role == BaseTreeView::ItemActivatedRole) { + EngineItem *engineItem = d->findEngineItem(m_engine); +- d->activateEngineByIndex(engineItem->indexInParent()); ++ d->activateEngineItem(engineItem); + return true; + } + +@@ -324,27 +324,21 @@ bool EngineItem::setData(int row, const QVariant &value, int role) + + void EngineManagerPrivate::activateEngineByIndex(int index) + { +- // The actual activation is triggered indirectly via the perspective change. +- Perspective *perspective = nullptr; +- if (index == 0) { +- perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID); +- } else { +- EngineItem *engineItem = m_engineModel.rootItem()->childAt(index); +- QTC_ASSERT(engineItem, return); +- QTC_ASSERT(engineItem->m_engine, return); +- perspective = engineItem->m_engine->perspective(); +- } +- +- QTC_ASSERT(perspective, return); +- perspective->select(); ++ activateEngineItem(m_engineModel.rootItem()->childAt(index)); + } + + void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem) + { +- if (m_currentItem == engineItem) +- return; ++ Context previousContext; ++ if (m_currentItem) { ++ if (DebuggerEngine *engine = m_currentItem->m_engine) { ++ previousContext.add(engine->languageContext()); ++ previousContext.add(engine->debuggerContext()); ++ } else { ++ previousContext.add(Context(Constants::C_DEBUGGER_NOTRUNNING)); ++ } ++ } + +- QTC_ASSERT(engineItem, return); + m_currentItem = engineItem; + + Context newContext; +@@ -357,13 +351,7 @@ void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem) + } + } + +- ICore::updateAdditionalContexts(m_currentAdditionalContext, newContext); +- m_currentAdditionalContext = newContext; +- +- // In case this was triggered externally by some Perspective::select() call. +- const int idx = engineItem->indexInParent(); +- m_engineChooser->setCurrentIndex(idx); +- ++ ICore::updateAdditionalContexts(previousContext, newContext); + selectUiForCurrentEngine(); + } + +@@ -372,7 +360,12 @@ void EngineManagerPrivate::selectUiForCurrentEngine() + if (ModeManager::currentModeId() != Constants::MODE_DEBUG) + return; + ++ Perspective *perspective = nullptr; + int row = 0; ++ ++ if (m_currentItem && m_currentItem->m_engine) ++ perspective = m_currentItem->m_engine->perspective(); ++ + if (m_currentItem) + row = m_engineModel.rootItem()->indexOf(m_currentItem); + +@@ -385,6 +378,12 @@ void EngineManagerPrivate::selectUiForCurrentEngine() + QStyle::CT_ComboBox, &option, sz).width(); + m_engineChooser->setFixedWidth(width); + ++ if (!perspective) ++ perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID); ++ ++ QTC_ASSERT(perspective, return); ++ perspective->select(); ++ + m_engineModel.rootItem()->forFirstLevelChildren([this](EngineItem *engineItem) { + if (engineItem && engineItem->m_engine) + engineItem->m_engine->updateUi(engineItem == m_currentItem); +@@ -400,6 +399,12 @@ EngineItem *EngineManagerPrivate::findEngineItem(DebuggerEngine *engine) + }); + } + ++void EngineManagerPrivate::activateEngine(DebuggerEngine *engine) ++{ ++ EngineItem *engineItem = findEngineItem(engine); ++ activateEngineItem(engineItem); ++} ++ + void EngineManagerPrivate::updateEngineChooserVisibility() + { + // Show it if there's more than one option (i.e. not the preset engine only) +@@ -409,48 +414,12 @@ void EngineManagerPrivate::updateEngineChooserVisibility() + } + } + +-void EngineManagerPrivate::updatePerspectives() +-{ +- d->updateEngineChooserVisibility(); +- +- Perspective *current = DebuggerMainWindow::currentPerspective(); +- if (!current) { +- return; +- } +- +- m_engineModel.rootItem()->forFirstLevelChildren([this, current](EngineItem *engineItem) { +- if (engineItem == m_currentItem) +- return; +- +- bool shouldBeActive = false; +- if (engineItem->m_engine) { +- // Normal engine. +- shouldBeActive = engineItem->m_engine->perspective()->isCurrent(); +- } else { +- // Preset. +- shouldBeActive = current->id() == Debugger::Constants::PRESET_PERSPECTIVE_ID; +- } +- +- if (shouldBeActive && engineItem != m_currentItem) +- activateEngineItem(engineItem); +- }); +-} +- +-QString EngineManager::registerEngine(DebuggerEngine *engine) ++void EngineManager::registerEngine(DebuggerEngine *engine) + { + auto engineItem = new EngineItem; + engineItem->m_engine = engine; + d->m_engineModel.rootItem()->appendChild(engineItem); + d->updateEngineChooserVisibility(); +- return QString::number(d->m_engineModel.rootItem()->childCount()); +-} +- +-void EngineManager::unregisterEngine(DebuggerEngine *engine) +-{ +- EngineItem *engineItem = d->findEngineItem(engine); +- QTC_ASSERT(engineItem, return); +- d->m_engineModel.destroyItem(engineItem); +- d->updateEngineChooserVisibility(); + } + + void EngineManager::activateDebugMode() +@@ -473,6 +442,33 @@ void EngineManager::deactivateDebugMode() + } + } + ++bool EngineManager::isLastOf(const QString &type) ++{ ++ int count = 0; ++ d->m_engineModel.rootItem()->forFirstLevelChildren([&](EngineItem *engineItem) { ++ if (engineItem && engineItem->m_engine) ++ count += (engineItem->m_engine->debuggerName() == type); ++ }); ++ return count == 1; ++} ++ ++void EngineManager::unregisterEngine(DebuggerEngine *engine) ++{ ++ if (ModeManager::currentModeId() == Constants::MODE_DEBUG) { ++ if (Perspective *parent = Perspective::findPerspective(Constants::PRESET_PERSPECTIVE_ID)) ++ parent->select(); ++ } ++ ++ d->activateEngineItem(d->m_engineModel.rootItem()->childAt(0)); // Preset. ++ ++ // Could be that the run controls died before it was appended. ++ if (auto engineItem = d->findEngineItem(engine)) ++ d->m_engineModel.destroyItem(engineItem); ++ ++ d->updateEngineChooserVisibility(); ++ emit theEngineManager->currentEngineChanged(); ++} ++ + QList<QPointer<DebuggerEngine>> EngineManager::engines() + { + QList<QPointer<DebuggerEngine>> result; +@@ -488,18 +484,5 @@ QPointer<DebuggerEngine> EngineManager::currentEngine() + return d->m_currentItem ? d->m_currentItem->m_engine : nullptr; + } + +-bool EngineManager::shutDown() +-{ +- d->m_shuttingDown = true; +- bool anyEngineAborting = false; +- for (DebuggerEngine *engine : EngineManager::engines()) { +- if (engine && engine->state() != Debugger::DebuggerNotReady) { +- engine->abortDebugger(); +- anyEngineAborting = true; +- } +- } +- return anyEngineAborting; +-} +- + } // namespace Internal + } // namespace Debugger +diff --git a/src/plugins/debugger/enginemanager.h b/src/plugins/debugger/enginemanager.h +index 08549ba711..a1ee76c60b 100644 +--- a/src/plugins/debugger/enginemanager.h ++++ b/src/plugins/debugger/enginemanager.h +@@ -45,19 +45,17 @@ public: + static EngineManager *instance(); + static QAbstractItemModel *model(); + +- static QString registerEngine(DebuggerEngine *engine); ++ static void registerEngine(DebuggerEngine *engine); + static void unregisterEngine(DebuggerEngine *engine); +- ++ static void activateEngine(DebuggerEngine *engine); + static void activateDebugMode(); + static void deactivateDebugMode(); ++ static bool isLastOf(const QString &type); + + static QList<QPointer<DebuggerEngine> > engines(); + static QPointer<DebuggerEngine> currentEngine(); + + static QWidget *engineChooser(); +- static void updatePerspectives(); +- +- static bool shutDown(); // Return true if some engine is being forced to shut down. + + signals: + void engineStateChanged(DebuggerEngine *engine); +diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp +index 796416374a..8d2af5008a 100644 +--- a/src/plugins/debugger/gdb/gdbengine.cpp ++++ b/src/plugins/debugger/gdb/gdbengine.cpp +@@ -2953,7 +2953,7 @@ void GdbEngine::handleThreadInfo(const DebuggerResponse &response) + if (response.resultClass == ResultDone) { + ThreadsHandler *handler = threadsHandler(); + handler->setThreads(response.data); +- updateState(); // Adjust Threads combobox. ++ updateState(false); // Adjust Threads combobox. + if (boolSetting(ShowThreadNames)) { + runCommand({"threadnames " + action(MaximalStackDepth)->value().toString(), + Discardable, CB(handleThreadNames)}); +@@ -2993,7 +2993,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response) + thread.name = decodeData(name["value"].data(), name["valueencoded"].data()); + handler->updateThread(thread); + } +- updateState(); ++ updateState(false); + } + } + diff --git a/qtcreator-occurrences-fix.patch b/qtcreator-occurrences-fix.patch deleted file mode 100644 index d6af0d6f6d66..000000000000 --- a/qtcreator-occurrences-fix.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp -index bc8d8c4d1a..a7203e8973 100644 ---- a/src/plugins/texteditor/fontsettings.cpp -+++ b/src/plugins/texteditor/fontsettings.cpp -@@ -143,6 +143,14 @@ uint qHash(const TextStyle &textStyle) - return ::qHash(quint8(textStyle)); - } - -+static bool isOverlayCategory(TextStyle category) -+{ -+ return category == C_OCCURRENCES -+ || category == C_OCCURRENCES_RENAME -+ || category == C_SEARCH_RESULT -+ || category == C_PARENTHESES_MISMATCH; -+} -+ - /** - * Returns the QTextCharFormat of the given format category. - */ -@@ -166,18 +174,18 @@ QTextCharFormat FontSettings::toTextCharFormat(TextStyle category) const - "Unused variable")); - } - -- if (f.foreground().isValid() -- && category != C_OCCURRENCES -- && category != C_OCCURRENCES_RENAME -- && category != C_SEARCH_RESULT -- && category != C_PARENTHESES_MISMATCH) -+ if (f.foreground().isValid() && !isOverlayCategory(category)) - tf.setForeground(f.foreground()); -- if (f.background().isValid() && (category == C_TEXT || f.background() != m_scheme.formatFor(C_TEXT).background())) -- tf.setBackground(f.background()); -- -- // underline does not need to fill without having background color -- if (f.underlineStyle() != QTextCharFormat::NoUnderline && !f.background().isValid()) -- tf.setBackground(QBrush(Qt::BrushStyle::NoBrush)); -+ if (f.background().isValid()) { -+ if (category == C_TEXT || f.background() != m_scheme.formatFor(C_TEXT).background()) -+ tf.setBackground(f.background()); -+ } else if (isOverlayCategory(category)) { -+ // overlays without a background schouldn't get painted -+ tf.setBackground(QColor()); -+ } else if (f.underlineStyle() != QTextCharFormat::NoUnderline) { -+ // underline does not need to fill without having background color -+ tf.setBackground(Qt::BrushStyle::NoBrush); -+ } - - tf.setFontWeight(f.bold() ? QFont::Bold : QFont::Normal); - tf.setFontItalic(f.italic()); -diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp -index 60fe5cc99e..a33ca13810 100644 ---- a/src/plugins/texteditor/texteditoroverlay.cpp -+++ b/src/plugins/texteditor/texteditoroverlay.cpp -@@ -323,9 +323,7 @@ void TextEditorOverlay::paintSelection(QPainter *painter, - const QColor &bg = selection.m_bg; - - -- if (begin.isNull() -- || end.isNull() -- || begin.position() > end.position()) -+ if (begin.isNull() || end.isNull() || begin.position() > end.position() || !bg.isValid()) - return; - - QPainterPath path = createSelectionPath(begin, end, m_editor->viewport()->rect()); -@@ -339,25 +337,21 @@ void TextEditorOverlay::paintSelection(QPainter *painter, - - QRectF pathRect = path.controlPointRect(); - -- if (bg.isValid()) { -- if (!m_alpha || begin.blockNumber() != end.blockNumber()) { -- // gradients are too slow for larger selections :( -- QColor col = bg; -- if (m_alpha) -- col.setAlpha(50); -- painter->setBrush(col); -- } else { -- QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft()); -- QColor col1 = fg.lighter(150); -- col1.setAlpha(20); -- QColor col2 = fg; -- col2.setAlpha(80); -- linearGrad.setColorAt(0, col1); -- linearGrad.setColorAt(1, col2); -- painter->setBrush(QBrush(linearGrad)); -- } -+ if (!m_alpha || begin.blockNumber() != end.blockNumber()) { -+ // gradients are too slow for larger selections :( -+ QColor col = bg; -+ if (m_alpha) -+ col.setAlpha(50); -+ painter->setBrush(col); - } else { -- painter->setBrush(QBrush()); -+ QLinearGradient linearGrad(pathRect.topLeft(), pathRect.bottomLeft()); -+ QColor col1 = fg.lighter(150); -+ col1.setAlpha(20); -+ QColor col2 = fg; -+ col2.setAlpha(80); -+ linearGrad.setColorAt(0, col1); -+ linearGrad.setColorAt(1, col2); -+ painter->setBrush(QBrush(linearGrad)); - } - - painter->setRenderHint(QPainter::Antialiasing); diff --git a/qtcreator-preload-plugins.patch b/qtcreator-preload-plugins.patch new file mode 100644 index 000000000000..f4772dd05de9 --- /dev/null +++ b/qtcreator-preload-plugins.patch @@ -0,0 +1,21 @@ +diff --git a/src/plugins/clangtools/clangtidyclazyrunner.cpp b/src/plugins/clangtools/clangtidyclazyrunner.cpp +index a580704243..7a8740a5cc 100644 +--- a/src/plugins/clangtools/clangtidyclazyrunner.cpp ++++ b/src/plugins/clangtools/clangtidyclazyrunner.cpp +@@ -76,6 +76,7 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis + + const ClangDiagnosticConfig::TidyMode tidyMode = m_diagnosticConfig.clangTidyMode(); + if (tidyMode != ClangDiagnosticConfig::TidyMode::Disabled) { ++ arguments << XclangArgs({"-load", "libclangTidyPlugin.so"}); + arguments << XclangArgs({"-add-plugin", "clang-tidy"}); + if (tidyMode != ClangDiagnosticConfig::TidyMode::File) { + const QString tidyChecks = m_diagnosticConfig.clangTidyChecks(); +@@ -85,7 +86,7 @@ QStringList ClangTidyClazyRunner::constructCommandLineArguments(const QStringLis + + const QString clazyChecks = m_diagnosticConfig.clazyChecks(); + if (!clazyChecks.isEmpty()) { +- arguments << XclangArgs({"-add-plugin", ++ arguments << XclangArgs({"-load", "ClazyPlugin.so", "-add-plugin", + "clazy", + "-plugin-arg-clazy", + "enable-all-fixits", diff --git a/qtcreator-theme-fixes.patch b/qtcreator-theme-fixes.patch deleted file mode 100644 index 0905939ae89b..000000000000 --- a/qtcreator-theme-fixes.patch +++ /dev/null @@ -1,308 +0,0 @@ -diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme -index ef19fc9fa6..41439ff22a 100644 ---- a/share/qtcreator/themes/dark.creatortheme -+++ b/share/qtcreator/themes/dark.creatortheme -@@ -7,8 +7,10 @@ DefaultTextEditorColorScheme=dark.xml - shadowBackground=ff232323 - text=ffe7e7e7 - textDisabled=7fffffff -+textHighlighted=ffe7e7e7 - hoverBackground=18ffffff --selectedBackground=66000000 -+selectedBackground=aa1f75cc -+selectedBackgroundText=aa1f75cc - normalBackground=ff333333 - alternateBackground=ff515151 - error=ffd84044 -@@ -48,6 +50,7 @@ DoubleTabWidget2ndTabInactiveTextColor=textDisabled - EditorPlaceholderColor=normalBackground - FancyToolBarSeparatorColor=43ffffff - FancyTabBarBackgroundColor=shadowBackground -+FancyTabBarSelectedBackgroundColor=88000000 - FancyTabWidgetDisabledSelectedTextColor=textDisabled - FancyTabWidgetDisabledUnselectedTextColor=textDisabled - FancyTabWidgetEnabledSelectedTextColor=text -@@ -118,7 +121,7 @@ SplitterColor=splitterColor - TextColorDisabled=textDisabled - TextColorError=ffff4040 - TextColorHighlight=ffff0000 --TextColorHighlightBackground=555500 -+TextColorHighlightBackground=7a6f1c - TextColorLink=textColorLink - TextColorLinkVisited=textColorLinkVisited - TextColorNormal=text -@@ -143,7 +146,7 @@ OutputPanes_TestWarnTextColor=ffc8c800 - OutputPanes_TestFatalTextColor=ffb42828 - OutputPanes_TestDebugTextColor=ff329696 - OutputPaneButtonFlashColor=error --OutputPaneToggleButtonTextColorChecked=text -+OutputPaneToggleButtonTextColorChecked=textHighlighted - OutputPaneToggleButtonTextColorUnchecked=text - - Debugger_LogWindow_LogInput=ff00acac -@@ -203,10 +206,10 @@ PaletteBrightText=ffff0000 - PaletteText=text - PaletteButtonText=text - PaletteButtonTextDisabled=textDisabled --PaletteToolTipBase=selectedBackground --PaletteHighlight=selectedBackground -+PaletteToolTipBase=66000000 -+PaletteHighlight=selectedBackgroundText - PaletteDark=shadowBackground --PaletteHighlightedText=ffffffff -+PaletteHighlightedText=textHighlighted - PaletteToolTipText=text - PaletteLink=textColorLink - PaletteLinkVisited=textColorLinkVisited -diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme -index 8db109f313..cd90ad49de 100644 ---- a/share/qtcreator/themes/design.creatortheme -+++ b/share/qtcreator/themes/design.creatortheme -@@ -17,6 +17,9 @@ text=ffdadada - ;disabled text - textDisabled=60a4a6a8 - -+;background for selected text -+selectedBackgroundText=aa1f75cc -+ - ;icons, spinbox ticks, - ;toolBarItem=b6fbfdff - toolBarItem=ffb3b3b3 -@@ -50,7 +53,7 @@ hoverBackground=ff404244 - ;blended background color for controls 1 spinboxes, background selection square for snapping modes, publish as alias icon. - ;color for filter background and overwrite width and height boxes - ;selectedBackground=66000000 --selectedBackground=ff111111 -+selectedBackground=aa1f75cc - - - ;background for default "open a document" screen in the edit mode, -@@ -108,6 +111,7 @@ DoubleTabWidget2ndTabInactiveTextColor=text - EditorPlaceholderColor=normalBackground - FancyToolBarSeparatorColor=toolBarItemDisabled - FancyTabBarBackgroundColor=shadowBackground -+FancyTabBarSelectedBackgroundColor=ff000000 - FancyTabWidgetDisabledSelectedTextColor=toolBarItemDisabled - FancyTabWidgetDisabledUnselectedTextColor=toolBarItemDisabled - FancyTabWidgetEnabledSelectedTextColor=fancyBarsBoldTextColor -@@ -378,7 +382,7 @@ PaletteToolTipBase=selectedBackground - - - ;the selection highlight on the dropdown combo box in the file selection top menu and connections panel and tab mode selector dropdowns --PaletteHighlight=selectedBackground -+PaletteHighlight=selectedBackgroundText - ;PaletteHighlight=ffd3299a - - -diff --git a/share/qtcreator/themes/flat-dark.creatortheme b/share/qtcreator/themes/flat-dark.creatortheme -index 0c01aa1707..e79a96056d 100644 ---- a/share/qtcreator/themes/flat-dark.creatortheme -+++ b/share/qtcreator/themes/flat-dark.creatortheme -@@ -4,15 +4,17 @@ PreferredStyles=Fusion - DefaultTextEditorColorScheme=creator-dark.xml - - [Palette] --shadowBackground=ff404244 -+shadowBackground=ff404142 - text=ffd0d0d0 - textDisabled=60a4a6a8 --toolBarItem=b6fbfdff --toolBarItemDisabled=60a4a6a8 -+textHighlighted=fff0f0f0 -+toolBarItem=bcfbfdff -+toolBarItemDisabled=56a5a6a7 - fancyBarsNormalTextColor=ffd0d0d0 - fancyBarsBoldTextColor=b6fbfdff --hoverBackground=22ffffff --selectedBackground=66000000 -+hoverBackground=28ffffff -+selectedBackground=7a000000 -+selectedBackgroundText=ff1d545c - normalBackground=ff2E2F30 - alternateBackground=ff353637 - error=ffdf4f4f -@@ -52,6 +54,7 @@ DoubleTabWidget2ndTabInactiveTextColor=text - EditorPlaceholderColor=normalBackground - FancyToolBarSeparatorColor=toolBarItemDisabled - FancyTabBarBackgroundColor=shadowBackground -+FancyTabBarSelectedBackgroundColor=selectedBackground - FancyTabWidgetDisabledSelectedTextColor=toolBarItemDisabled - FancyTabWidgetDisabledUnselectedTextColor=toolBarItemDisabled - FancyTabWidgetEnabledSelectedTextColor=fancyBarsBoldTextColor -@@ -122,7 +125,7 @@ SplitterColor=splitter - TextColorDisabled=textDisabled - TextColorError=ffff4040 - TextColorHighlight=ffff0000 --TextColorHighlightBackground=8a7f2c -+TextColorHighlightBackground=7a6f1c - TextColorLink=textColorLink - TextColorLinkVisited=textColorLinkVisited - TextColorNormal=text -@@ -147,7 +150,7 @@ OutputPanes_TestWarnTextColor=ffc8c800 - OutputPanes_TestFatalTextColor=ffc82828 - OutputPanes_TestDebugTextColor=ff329696 - OutputPaneButtonFlashColor=error --OutputPaneToggleButtonTextColorChecked=fancyBarsNormalTextColor -+OutputPaneToggleButtonTextColorChecked=textHighlighted - OutputPaneToggleButtonTextColorUnchecked=fancyBarsNormalTextColor - - Debugger_LogWindow_LogInput=ff00acac -@@ -221,10 +224,10 @@ PaletteBrightText=ffff3333 - PaletteText=text - PaletteButtonText=text - PaletteButtonTextDisabled=textDisabled --PaletteToolTipBase=selectedBackground --PaletteHighlight=selectedBackground -+PaletteToolTipBase=darkBackground -+PaletteHighlight=selectedBackgroundText - PaletteDark=shadowBackground --PaletteHighlightedText=ffffffff -+PaletteHighlightedText=textHighlighted - PaletteToolTipText=text - PaletteLink=textColorLink - PaletteLinkVisited=textColorLinkVisited -diff --git a/share/qtcreator/themes/flat-light.creatortheme b/share/qtcreator/themes/flat-light.creatortheme -index 29edca63fd..f6b726762c 100644 ---- a/share/qtcreator/themes/flat-light.creatortheme -+++ b/share/qtcreator/themes/flat-light.creatortheme -@@ -50,6 +50,7 @@ DoubleTabWidget2ndTabInactiveTextColor=ff000000 - EditorPlaceholderColor=fff4f4f4 - FancyToolBarSeparatorColor=toolBarItemDisabled - FancyTabBarBackgroundColor=shadowBackground -+FancyTabBarSelectedBackgroundColor=selectedBackground - FancyTabWidgetDisabledSelectedTextColor=toolBarItemDisabled - FancyTabWidgetDisabledUnselectedTextColor=toolBarItemDisabled - FancyTabWidgetEnabledSelectedTextColor=fancyBarsBoldTextColor -diff --git a/share/qtcreator/themes/flat.creatortheme b/share/qtcreator/themes/flat.creatortheme -index ab0189528f..0f057d80c0 100644 ---- a/share/qtcreator/themes/flat.creatortheme -+++ b/share/qtcreator/themes/flat.creatortheme -@@ -3,15 +3,15 @@ ThemeName=Flat - PreferredStyles= - - [Palette] --shadowBackground=ff404244 -+shadowBackground=ff404142 - text=ff000000 - textDisabled=55000000 --toolBarItem=b6fbfdff --toolBarItemDisabled=60a4a6a8 -+toolBarItem=bcfbfdff -+toolBarItemDisabled=56a5a6a7 - fancyBarsNormalTextColor=ffffffff - fancyBarsBoldTextColor=b6fbfdff --hoverBackground=22ffffff --selectedBackground=66000000 -+hoverBackground=28ffffff -+selectedBackground=7a000000 - normalBackground=ffffffff - alternateBackground=ff515151 - error=ffdf4f4f -@@ -48,6 +48,7 @@ DoubleTabWidget2ndTabInactiveTextColor=ff000000 - EditorPlaceholderColor=ffdddddd - FancyToolBarSeparatorColor=toolBarItemDisabled - FancyTabBarBackgroundColor=shadowBackground -+FancyTabBarSelectedBackgroundColor=selectedBackground - FancyTabWidgetDisabledSelectedTextColor=toolBarItemDisabled - FancyTabWidgetDisabledUnselectedTextColor=toolBarItemDisabled - FancyTabWidgetEnabledSelectedTextColor=fancyBarsBoldTextColor -diff --git a/src/libs/utils/icon.cpp b/src/libs/utils/icon.cpp -index dc7625aae3..f7edbd8614 100644 ---- a/src/libs/utils/icon.cpp -+++ b/src/libs/utils/icon.cpp -@@ -139,13 +139,13 @@ static QPixmap masksToIcon(const MasksAndColors &masks, const QPixmap &combinedM - if (style & Icon::DropShadow && creatorTheme()->flag(Theme::ToolBarIconShadow)) { - const QPixmap shadowMask = maskToColorAndAlpha(combinedMask, Qt::black); - p.setCompositionMode(QPainter::CompositionMode_DestinationOver); -- p.setOpacity(0.05); -+ p.setOpacity(0.08); - p.drawPixmap(QPointF(0, -0.501), shadowMask); - p.drawPixmap(QPointF(-0.501, 0), shadowMask); - p.drawPixmap(QPointF(0.5, 0), shadowMask); - p.drawPixmap(QPointF(0.5, 0.5), shadowMask); - p.drawPixmap(QPointF(-0.501, 0.5), shadowMask); -- p.setOpacity(0.2); -+ p.setOpacity(0.3); - p.drawPixmap(0, 1, shadowMask); - } - -diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h -index 9a881e9e64..f350bf0ca2 100644 ---- a/src/libs/utils/theme/theme.h -+++ b/src/libs/utils/theme/theme.h -@@ -80,6 +80,7 @@ public: - EditorPlaceholderColor, - FancyToolBarSeparatorColor, - FancyTabBarBackgroundColor, -+ FancyTabBarSelectedBackgroundColor, - FancyTabWidgetDisabledSelectedTextColor, - FancyTabWidgetDisabledUnselectedTextColor, - FancyTabWidgetEnabledSelectedTextColor, -diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp -index 4fad26bc12..3df5112be2 100644 ---- a/src/plugins/coreplugin/fancytabwidget.cpp -+++ b/src/plugins/coreplugin/fancytabwidget.cpp -@@ -288,6 +288,13 @@ static void paintIcon(QPainter *painter, const QRect &rect, - if (!enabled && !creatorTheme()->flag(Theme::FlatToolBars)) - painter->setOpacity(0.7); - StyleHelper::drawIconWithShadow(icon, iconRect, painter, iconMode); -+ -+ if (selected && creatorTheme()->flag(Theme::FlatToolBars)) { -+ painter->setOpacity(1.0); -+ QRect accentRect = rect; -+ accentRect.setWidth(2); -+ painter->fillRect(accentRect, creatorTheme()->color(Theme::IconsBaseColor)); -+ } - } - - static void paintIconAndText(QPainter *painter, const QRect &rect, -@@ -315,6 +322,11 @@ static void paintIconAndText(QPainter *painter, const QRect &rect, - } - - painter->setOpacity(1.0); //FIXME: was 0.7 before? -+ if (selected && creatorTheme()->flag(Theme::FlatToolBars)) { -+ QRect accentRect = rect; -+ accentRect.setWidth(2); -+ painter->fillRect(accentRect, creatorTheme()->color(Theme::IconsBaseColor)); -+ } - if (enabled) { - painter->setPen( - selected ? creatorTheme()->color(Theme::FancyTabWidgetEnabledSelectedTextColor) -@@ -349,7 +361,7 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const - if (selected) { - if (creatorTheme()->flag(Theme::FlatToolBars)) { - // background color of a fancy tab that is active -- painter->fillRect(rect, creatorTheme()->color(Theme::FancyToolButtonSelectedColor)); -+ painter->fillRect(rect, creatorTheme()->color(Theme::FancyTabBarSelectedBackgroundColor)); - } else { - paintSelectedTabBackground(painter, rect); - } -diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp -index 7276685d20..2421bd776a 100644 ---- a/src/plugins/coreplugin/locator/locatorwidget.cpp -+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp -@@ -87,6 +87,7 @@ public: - LocatorModel(QObject *parent = nullptr) - : QAbstractListModel(parent) - , mBackgroundColor(Utils::creatorTheme()->color(Utils::Theme::TextColorHighlightBackground)) -+ , mForegroundColor(Utils::creatorTheme()->color(Utils::Theme::TextColorNormal)) - {} - - void clear(); -@@ -100,6 +101,7 @@ private: - mutable QList<LocatorFilterEntry> mEntries; - bool hasExtraInfo = false; - QColor mBackgroundColor; -+ QColor mForegroundColor; - }; - - class CompletionDelegate : public HighlightingItemDelegate -@@ -224,6 +226,8 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const - } - case int(HighlightingItemRole::Background): - return mBackgroundColor; -+ case int(HighlightingItemRole::Foreground): -+ return mForegroundColor; - } - - return QVariant(); |