From 31f7ed44b6b64a31109f083af833fe79e4bd35cb Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 8 Aug 2023 13:43:19 +0200 Subject: [PATCH 1/8] FilePath: Use isSameDevice Some places compared the scheme and host of a filepath to decide whether its the same device. This is incorrect and leads to false negatives. isSameDevice is the correct way to decide whether two paths are from the same device. Fixes: QTCREATORBUG-29474 Change-Id: Iced8f434dadb931f6595f47f95647b341c48d3aa Reviewed-by: hjk --- src/libs/utils/fileutils.cpp | 3 +-- src/libs/utils/process.cpp | 2 +- src/plugins/cmakeprojectmanager/cmakeprocess.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp index 0c6a321c714..4f67ee8105a 100644 --- a/src/libs/utils/fileutils.cpp +++ b/src/libs/utils/fileutils.cpp @@ -722,8 +722,7 @@ bool FileUtils::copyRecursively( bool FileUtils::copyIfDifferent(const FilePath &srcFilePath, const FilePath &tgtFilePath) { QTC_ASSERT(srcFilePath.exists(), return false); - QTC_ASSERT(srcFilePath.scheme() == tgtFilePath.scheme(), return false); - QTC_ASSERT(srcFilePath.host() == tgtFilePath.host(), return false); + QTC_ASSERT(srcFilePath.isSameDevice(tgtFilePath), return false); if (tgtFilePath.exists()) { const QDateTime srcModified = srcFilePath.lastModified(); diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index 5f8e3612f7f..8721d6c4214 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -1204,7 +1204,7 @@ FilePath Process::workingDirectory() const void Process::setWorkingDirectory(const FilePath &dir) { if (dir.needsDevice() && d->m_setup.m_commandLine.executable().needsDevice()) { - QTC_CHECK(dir.host() == d->m_setup.m_commandLine.executable().host()); + QTC_CHECK(dir.isSameDevice(d->m_setup.m_commandLine.executable())); } d->m_setup.m_workingDirectory = dir; } diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index 1455cbf88b9..f38eb2c628f 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -79,7 +79,7 @@ void CMakeProcess::run(const BuildDirParameters ¶meters, const QStringList & } if (buildDirectory.needsDevice()) { - if (cmake->cmakeExecutable().host() != buildDirectory.host()) { + if (!cmake->cmakeExecutable().isSameDevice(buildDirectory)) { const QString msg = ::CMakeProjectManager::Tr::tr( "CMake executable \"%1\" and build directory \"%2\" must be on the same device.") .arg(cmake->cmakeExecutable().toUserOutput(), buildDirectory.toUserOutput()); From fbb99463315cd020aa7458c3b550df91375f81ec Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 4 Aug 2023 14:33:54 +0200 Subject: [PATCH 2/8] Copilot: avoid crash on misconfigured agent When setting up a wrong or unusable agent.js the client used inside the AuthWidget get's deleted eventually. In that case we need to reset the tracked client otherwise we use a pointer to the deleted client in the destructor of AuthWidget. Change-Id: Ide4067c01cdcd05a33d44bc9460acfe9a56c7815 Reviewed-by: Reviewed-by: Marcus Tillmanns Reviewed-by: Artem Sokolovskii --- src/plugins/copilot/authwidget.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/copilot/authwidget.cpp b/src/plugins/copilot/authwidget.cpp index 559dee30cf9..4052ce600a7 100644 --- a/src/plugins/copilot/authwidget.cpp +++ b/src/plugins/copilot/authwidget.cpp @@ -95,14 +95,19 @@ void AuthWidget::updateClient(const Utils::FilePath &nodeJs, const Utils::FilePa m_client = nullptr; setState(Tr::tr("Sign In"), false); m_button->setEnabled(false); - if (!nodeJs.isExecutableFile() || !agent.exists()) { + if (!nodeJs.isExecutableFile() || !agent.exists()) return; - } setState(Tr::tr("Sign In"), true); m_client = new CopilotClient(nodeJs, agent); connect(m_client, &Client::initialized, this, &AuthWidget::checkStatus); + connect(m_client, &QObject::destroyed, this, [destroyedClient = m_client, this]() { + if (destroyedClient != m_client) + return; + m_client = nullptr; + m_progressIndicator->hide(); + }); } void AuthWidget::signIn() From 4330736db331c4e42e5c3625eaa2028aabcb96a4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 9 Aug 2023 08:33:06 +0200 Subject: [PATCH 3/8] Bump version to 11.0.2 Change-Id: Ib733cb5adf7fb583dc161d3d20d0c4a61638cf0e Reviewed-by: David Schulz --- cmake/QtCreatorIDEBranding.cmake | 4 ++-- qbs/modules/qtc/qtc.qbs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 3f3e4e7a0c7..72009ad7fc1 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ -set(IDE_VERSION "11.0.1") # The IDE version. +set(IDE_VERSION "11.0.2") # The IDE version. set(IDE_VERSION_COMPAT "11.0.0") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "11.0.1") # The IDE display version. +set(IDE_VERSION_DISPLAY "11.0.2") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2023") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index 2f36c8887d9..a0d249d777c 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -6,10 +6,10 @@ import qbs.Utilities Module { Depends { name: "cpp"; required: false } - property string qtcreator_display_version: '11.0.1' + property string qtcreator_display_version: '11.0.2' property string ide_version_major: '11' property string ide_version_minor: '0' - property string ide_version_release: '1' + property string ide_version_release: '2' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release From 6528bd3eeda563d7d692c54b2b7035488f5f8974 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 8 Aug 2023 19:21:46 +0200 Subject: [PATCH 4/8] CMakePM: Find the right AUTOUIC generated header Amends c4e15769ec43ff46ec08f639c1f09f9fd8872225 When using ui files in static libraries AUTOUIC reports fake header file names. By using the target that includes the source ui file we can find the correct header file name. Change-Id: I1c8e0b81ad2c670be87c3620f98bd0f5cce40cd1 Reviewed-by: Jarek Kobus Reviewed-by: Christian Kandeler --- .../cmakeprojectmanager/cmakebuildsystem.cpp | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 329048b19cc..c5e307cfb70 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -654,15 +654,29 @@ FilePaths CMakeBuildSystem::filesGeneratedFrom(const FilePath &sourceFile) const FilePath generatedFilePath = buildConfiguration()->buildDirectory().resolvePath(relativePath); if (sourceFile.suffix() == "ui") { - const QString generatedFileSuffix = "ui_" + sourceFile.completeBaseName() + ".h"; + const QString generatedFileName = "ui_" + sourceFile.completeBaseName() + ".h"; - // If AUTOUIC reports the generated header file name, use that path - FilePaths generatedFilePaths = this->project()->files([generatedFileSuffix](const Node *n) { - return Project::GeneratedFiles(n) && n->filePath().endsWith(generatedFileSuffix); - }); + auto targetNode = this->project()->nodeForFilePath(sourceFile); + while (!dynamic_cast(targetNode)) + targetNode = targetNode->parentFolderNode(); + + FilePaths generatedFilePaths; + if (targetNode) { + const QString autogenSignature = targetNode->buildKey() + "_autogen/include"; + + // If AUTOUIC reports the generated header file name, use that path + generatedFilePaths = this->project()->files( + [autogenSignature, generatedFileName](const Node *n) { + const FilePath filePath = n->filePath(); + if (!filePath.contains(autogenSignature)) + return false; + + return Project::GeneratedFiles(n) && filePath.endsWith(generatedFileName); + }); + } if (generatedFilePaths.empty()) - generatedFilePaths = {generatedFilePath.pathAppended(generatedFileSuffix)}; + generatedFilePaths = {generatedFilePath.pathAppended(generatedFileName)}; return generatedFilePaths; } From 1ca8487e913a5656ec3a529a032ec35d8ff7a5f8 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 9 Aug 2023 11:33:16 +0200 Subject: [PATCH 5/8] Utils: Fix for invalid docker paths from installer Some installers wrote "docker:/" into the settings instead of "docker://". This adds a workaround for that. Fixes: QTCREATORBUG-29474 Change-Id: I49a69d6fa9e4fe383257313e534660814c4a011f Reviewed-by: hjk --- src/libs/utils/filepath.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 9059a37ecc3..049ae325bd8 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -1269,7 +1269,16 @@ FilePath FilePath::fromSettings(const QVariant &variant) const QUrl url = variant.toUrl(); return FilePath::fromParts(url.scheme(), url.host(), url.path()); } - return FilePath::fromUserInput(variant.toString()); + + // The installer sometimes fails and adds "docker:/..." instead of "docker://... + // So we fix these paths here in those cases. + QString data = variant.toString(); + if (data.length() > 8 && data.startsWith("docker:/") && data[8] != '/') { + qWarning() << "Broken path in settings:" << data << ", applying workaround."; + data.insert(8, '/'); + } + + return FilePath::fromUserInput(data); } QVariant FilePath::toSettings() const From 578ecfc846c078df77ad308ee8bda297d24ce0ee Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 9 Aug 2023 12:27:31 +0200 Subject: [PATCH 6/8] SdkTool: Don't destroy :// parts in qmake paths Change-Id: I1b8fef656550b7d2e59e6a606728d0f3e85d5af2 Reviewed-by: Marcus Tillmanns --- src/tools/sdktool/addqtoperation.cpp | 11 ++++++++++- src/tools/sdktool/operation.cpp | 11 ++++++++++- src/tools/sdktool/operation.h | 2 ++ src/tools/sdktool/sdkpersistentsettings.cpp | 4 +++- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/tools/sdktool/addqtoperation.cpp b/src/tools/sdktool/addqtoperation.cpp index 61e19855ff6..6b372b1efd9 100644 --- a/src/tools/sdktool/addqtoperation.cpp +++ b/src/tools/sdktool/addqtoperation.cpp @@ -252,6 +252,15 @@ void AddQtOperation::unittest() QCOMPARE(version1.value(QLatin1String(QMAKE)).toString(), QLatin1String("/tmp/test/qmake2")); QVERIFY(version1.contains(QLatin1String("extraData"))); QCOMPARE(version1.value(QLatin1String("extraData")).toString(), QLatin1String("extraValue")); + + // Docker paths + qtData.m_id = "testId3"; + qtData.m_qmake = "docker://image///path/to//some/qmake"; + + map = qtData.addQt(map); + QVariantMap version2 = map.value(QLatin1String("QtVersion.2")).toMap(); + QVERIFY(version2.contains(QLatin1String(QMAKE))); + QCOMPARE(version2.value(QLatin1String(QMAKE)).toString(), QLatin1String("docker://image/path/to/some/qmake")); } #endif @@ -279,7 +288,7 @@ QVariantMap AddQtData::addQt(const QVariantMap &map) const const QString qt = QString::fromLatin1(PREFIX) + QString::number(versionCount); // Sanitize qmake path: - QString saneQmake = QDir::cleanPath(m_qmake); + const QString saneQmake = cleanPath(m_qmake); // insert data: KeyValuePairList data; diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp index 7a81c3c7adf..d045a440d47 100644 --- a/src/tools/sdktool/operation.cpp +++ b/src/tools/sdktool/operation.cpp @@ -84,7 +84,7 @@ bool Operation::save(const QVariantMap &map, const QString &file) const return false; } - QString dirName = QDir::cleanPath(path + "/.."); + QString dirName = cleanPath(path + "/.."); QDir dir(dirName); if (!dir.exists() && !dir.mkpath(QLatin1String("."))) { std::cerr << "Error: Could not create directory " << qPrintable(dirName) @@ -108,3 +108,12 @@ bool Operation::save(const QVariantMap &map, const QString &file) const } return true; } + +QString cleanPath(const QString &orig) +{ + // QDir::cleanPath() destroys "//", one of which might be needed. + const int pos = orig.indexOf("://"); + if (pos == -1) + return QDir::cleanPath(orig); + return orig.left(pos) + "://" + QDir::cleanPath(orig.mid(pos + 3)); +} diff --git a/src/tools/sdktool/operation.h b/src/tools/sdktool/operation.h index 886ed386675..438bf302b75 100644 --- a/src/tools/sdktool/operation.h +++ b/src/tools/sdktool/operation.h @@ -22,6 +22,8 @@ using KeyValuePairList = QList; QVariant valueFromString(const QString &v); +QString cleanPath(const QString &orig); + class Operation { public: diff --git a/src/tools/sdktool/sdkpersistentsettings.cpp b/src/tools/sdktool/sdkpersistentsettings.cpp index 7fda2d8d03c..b72fffa4c57 100644 --- a/src/tools/sdktool/sdkpersistentsettings.cpp +++ b/src/tools/sdktool/sdkpersistentsettings.cpp @@ -3,6 +3,8 @@ #include "sdkpersistentsettings.h" +#include "operation.h" // for cleanPath() + #include #include #include @@ -826,7 +828,7 @@ void SdkPersistentSettingsWriter::setContents(const QVariantMap &data) bool SdkPersistentSettingsWriter::write(const QVariantMap &data, QString *errorString) const { - const QString parentDir = QDir::cleanPath(m_fileName + "/.."); + const QString parentDir = cleanPath(m_fileName + "/.."); const QFileInfo fi(parentDir); if (!(fi.exists() && fi.isDir() && fi.isWritable())) { From 9c2527eea6d7d2e703e51d056a16cc10c0f12667 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 9 Aug 2023 16:18:06 +0200 Subject: [PATCH 7/8] QmakeProjectManager: Do not run the clean steps spuriously Amends c73266783875e49dbb4722ff673119c8213f993e. Fixes: QTCREATORBUG-29451 Fixes: QTCREATORBUG-29481 Change-Id: Ib79977d49ec7650f025887ec956efde45a8efb7c Reviewed-by: Marcus Tillmanns --- src/plugins/qmakeprojectmanager/qmakestep.cpp | 13 ++++--------- src/plugins/qmakeprojectmanager/qmakestep.h | 1 - 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 93e13f71f0c..2c2f5695c96 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -512,7 +512,9 @@ QWidget *QMakeStep::createConfigWidget() connect(abisListWidget, &QListWidget::itemChanged, this, [this] { if (m_ignoreChanges.isLocked()) return; - handleAbiWidgetChange(); + updateAbiWidgets(); + if (QmakeBuildConfiguration *bc = qmakeBuildConfiguration()) + BuildManager::buildLists({bc->cleanSteps()}); }); connect(widget, &QObject::destroyed, this, [this] { @@ -704,7 +706,7 @@ void QMakeStep::updateAbiWidgets() item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); item->setCheckState(selectedAbis.contains(param) ? Qt::Checked : Qt::Unchecked); } - handleAbiWidgetChange(); + abisChanged(); } } @@ -713,13 +715,6 @@ void QMakeStep::updateEffectiveQMakeCall() m_effectiveCall->setValue(effectiveQMakeCall()); } -void QMakeStep::handleAbiWidgetChange() -{ - abisChanged(); - if (QmakeBuildConfiguration *bc = qmakeBuildConfiguration()) - BuildManager::buildLists({bc->cleanSteps()}); -} - void QMakeStep::recompileMessageBoxFinished(int button) { if (button == QMessageBox::Yes) { diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index d977eedd904..f72c48d4612 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -155,7 +155,6 @@ private: void updateAbiWidgets(); void updateEffectiveQMakeCall(); - void handleAbiWidgetChange(); Utils::CommandLine m_qmakeCommand; Utils::CommandLine m_makeCommand; From d1deeb2c0d2c3f22be7d970e5e0f166f5101667b Mon Sep 17 00:00:00 2001 From: Aaron Barany Date: Wed, 2 Aug 2023 16:11:18 -0700 Subject: [PATCH 8/8] App: Use PassThrough high DPI rounding policy When high DPI is enabled, use PassThrough rounding policy to allow for fractional scaling without having to manually set an environment variable. The high DPI setting is now respected even if various Qt scale/ratio environment variables are set, which is the case in valid default situations such as setting the global scaling factor for KDE Plasma. Task-number: QTCREATORBUG-29461 Change-Id: Ife2820d205b3440646255dc997744b2b8867bc70 Reviewed-by: Reviewed-by: Cristian Adam --- src/app/main.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index d4c4a47b8c8..46233ba19ca 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -278,26 +278,16 @@ static Utils::QtcSettings *createUserSettings() static void setHighDpiEnvironmentVariable() { - if (Utils::HostOsInfo::isMacHost()) + if (Utils::HostOsInfo::isMacHost() || qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY")) return; std::unique_ptr settings(createUserSettings()); const bool defaultValue = Utils::HostOsInfo::isWindowsHost(); const bool enableHighDpiScaling = settings->value("Core/EnableHighDpiScaling", defaultValue).toBool(); - - static const char ENV_VAR_QT_DEVICE_PIXEL_RATIO[] = "QT_DEVICE_PIXEL_RATIO"; - if (enableHighDpiScaling - && !qEnvironmentVariableIsSet(ENV_VAR_QT_DEVICE_PIXEL_RATIO) // legacy in 5.6, but still functional - && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") - && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR") - && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) { - return; - } - - if (!qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY")) - QGuiApplication::setHighDpiScaleFactorRoundingPolicy( - Qt::HighDpiScaleFactorRoundingPolicy::Floor); + const auto policy = enableHighDpiScaling ? Qt::HighDpiScaleFactorRoundingPolicy::PassThrough + : Qt::HighDpiScaleFactorRoundingPolicy::Floor; + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(policy); } void setPixmapCacheLimit()