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);