diff --git a/src/app/main.cpp b/src/app/main.cpp index 741b85b7149..b4ac0dfee9f 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -280,26 +280,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() diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index c6d92cff082..7c4383c2949 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -1307,7 +1307,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 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/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 2880caaccdb..d269c1b607d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -661,15 +661,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; } diff --git a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp index 8ec21f28a80..5b9da361e57 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprocess.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprocess.cpp @@ -85,7 +85,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()); diff --git a/src/plugins/copilot/authwidget.cpp b/src/plugins/copilot/authwidget.cpp index f4d9c0e0561..07071d98f7e 100644 --- a/src/plugins/copilot/authwidget.cpp +++ b/src/plugins/copilot/authwidget.cpp @@ -107,14 +107,19 @@ void AuthWidget::updateClient(const FilePath &nodeJs, const FilePath &agent) 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() diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index bfcc8a89402..27b75a4d7cb 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -471,7 +471,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] { @@ -663,7 +665,7 @@ void QMakeStep::updateAbiWidgets() item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); item->setCheckState(selectedAbis.contains(param) ? Qt::Checked : Qt::Unchecked); } - handleAbiWidgetChange(); + abisChanged(); } } @@ -672,13 +674,6 @@ void QMakeStep::updateEffectiveQMakeCall() 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 334cfb8157d..b3177d1f7ae 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -152,7 +152,6 @@ private: void updateAbiWidgets(); void updateEffectiveQMakeCall(); - void handleAbiWidgetChange(); Utils::CommandLine m_qmakeCommand; Utils::CommandLine m_makeCommand; 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())) {