From 892393ffa1146894955a8b5e1bfe8df0a38eeb08 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Tue, 13 Dec 2022 13:47:24 +0100 Subject: [PATCH] workspace: handle duplicate output hashes correctly Some outputs have the same EDID, which results in two connected outputs having the same hash. To find out which config values need to be used, also check the connector name. --- src/workspace.cpp | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/workspace.cpp b/src/workspace.cpp index 2aabf874f6..d43bf62c5a 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -563,16 +563,42 @@ QMap outputsConfig(const QVector &outputs, cons return {}; } + QHash duplicate; + QHash outputHashes; + for (Output *output : outputs) { + const QString hash = outputHash(output); + const auto it = std::find_if(outputHashes.cbegin(), outputHashes.cend(), [hash](const auto &value) { + return value == hash; + }); + if (it == outputHashes.cend()) { + duplicate[output] = false; + } else { + duplicate[output] = true; + duplicate[it.key()] = true; + } + outputHashes[output] = hash; + } + QMap ret; const auto outputsJson = doc.array(); for (const auto &outputJson : outputsJson) { const auto outputObject = outputJson.toObject(); - for (auto it = outputs.constBegin(), itEnd = outputs.constEnd(); it != itEnd;) { - if (!ret.contains(*it) && outputObject["id"] == outputHash(*it)) { - ret[*it] = outputObject; - continue; + const auto id = outputObject["id"]; + const auto output = std::find_if(outputs.begin(), outputs.end(), [&duplicate, &id, &outputObject](Output *output) { + if (outputHash(output) != id.toString()) { + return false; } - ++it; + if (duplicate[output]) { + // can't distinguish between outputs by hash alone, need to look at connector names + const auto metadata = outputObject[QStringLiteral("metadata")]; + const auto outputName = metadata[QStringLiteral("name")].toString(); + return outputName == output->name(); + } else { + return true; + } + }); + if (output != outputs.end()) { + ret[*output] = outputObject; } } return ret;