40 QStringList hashedOutputs;
41 hashedOutputs.reserve(outputs.count());
42 for (
auto output : std::as_const(outputs)) {
49 hashedOutputs << outputHash(output);
51 std::sort(hashedOutputs.begin(), hashedOutputs.end());
52 const auto hash = QCryptographicHash::hash(hashedOutputs.join(QString()).toLatin1(), QCryptographicHash::Md5);
53 return QString::fromLatin1(hash.toHex());
169 const QJsonObject size = modeInfo[
"size"].toObject();
170 const QSize modeSize = QSize(size[
"width"].toInt(), size[
"height"].toInt());
171 const uint32_t refreshRate = std::round(modeInfo[
"refresh"].toDouble() * 1000);
173 const auto modes = output->
modes();
174 auto it = std::find_if(modes.begin(), modes.end(), [&modeSize, &refreshRate](
const auto &mode) {
175 return mode->size() == modeSize && mode->refreshRate() == refreshRate;
177 return (it != modes.end()) ? *it :
nullptr;
180std::optional<std::pair<OutputConfiguration, QList<Output *>>>
readOutputConfig(
const QList<Output *> &outputs,
const QString &hash)
182 const auto outputsInfo = outputsConfig(outputs, hash);
183 if (outputsInfo.isEmpty()) {
186 std::vector<std::pair<uint32_t, Output *>> outputOrder;
190 for (
const auto &output : std::as_const(outputs)) {
191 if (output->isPlaceholder() || output->isNonDesktop()) {
195 const QJsonObject outputInfo = outputsInfo[output];
196 const auto globalOutputInfo = globalOutputConfig(output);
197 qCDebug(KWIN_CORE) <<
"Reading output configuration for " << output;
198 if (!outputInfo.isEmpty() || globalOutputInfo.has_value()) {
200 props->enabled = outputInfo[
"enabled"].toBool(
true);
201 if (outputInfo[
"primary"].toBool()) {
202 outputOrder.push_back(std::make_pair(1, output));
203 if (!props->enabled) {
204 qCWarning(KWIN_CORE) <<
"KScreen config would disable the primary output!";
207 }
else if (
int prio = outputInfo[
"priority"].toInt(); prio > 0) {
208 outputOrder.push_back(std::make_pair(prio, output));
209 if (!props->enabled) {
210 qCWarning(KWIN_CORE) <<
"KScreen config would disable an output with priority!";
214 outputOrder.push_back(std::make_pair(0, output));
216 if (
const QJsonObject pos = outputInfo[
"pos"].toObject(); !pos.isEmpty()) {
217 props->pos = QPoint(pos[
"x"].toInt(), pos[
"y"].toInt());
221 const auto &globalInfo = globalOutputInfo ? globalOutputInfo.value() : outputInfo;
222 if (
const QJsonValue scale = globalInfo[
"scale"]; !scale.isUndefined()) {
223 props->scale = scale.toDouble(1.);
225 if (
const QJsonValue rotation = globalInfo[
"rotation"]; !rotation.isUndefined()) {
227 props->manualTransform = props->transform;
229 if (
const QJsonValue overscan = globalInfo[
"overscan"]; !overscan.isUndefined()) {
230 props->overscan = globalInfo[
"overscan"].toInt();
232 if (
const QJsonValue vrrpolicy = globalInfo[
"vrrpolicy"]; !vrrpolicy.isUndefined()) {
233 props->vrrPolicy =
static_cast<VrrPolicy>(vrrpolicy.toInt());
235 if (
const QJsonValue rgbrange = globalInfo[
"rgbrange"]; !rgbrange.isUndefined()) {
239 if (
const QJsonObject modeInfo = globalInfo[
"mode"].toObject(); !modeInfo.isEmpty()) {
245 props->enabled =
true;
247 props->transform = output->panelOrientation();
248 outputOrder.push_back(std::make_pair(0, output));
250 pos.setX(pos.x() + output->geometry().width());
253 bool allDisabled = std::all_of(outputs.begin(), outputs.end(), [&cfg](
const auto &output) {
254 return !cfg.changeSet(output)->enabled.value_or(output->isEnabled());
257 qCWarning(KWIN_CORE) <<
"KScreen config would disable all outputs!";
260 std::erase_if(outputOrder, [&cfg](
const auto &pair) {
261 return !cfg.
constChangeSet(pair.second)->enabled.value_or(pair.second->isEnabled());
263 std::sort(outputOrder.begin(), outputOrder.end(), [](
const auto &left,
const auto &right) {
264 if (left.first == right.first) {
266 return left.second->name() < right.second->name();
267 }
else if (left.first == 0) {
270 return left.first < right.first;
274 QList<Output *> order;
275 order.reserve(outputOrder.size());
276 std::transform(outputOrder.begin(), outputOrder.end(), std::back_inserter(order), [](
const auto &pair) {
279 return std::make_pair(cfg, order);