diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index 321d1b9623..0fd38b8308 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -463,6 +463,19 @@ DrmOutput::Transform toDrmTransform(int rotation) Q_UNREACHABLE(); } } + +std::shared_ptr parseMode(Output *output, const QJsonObject &modeInfo) +{ + const QJsonObject size = modeInfo["size"].toObject(); + const QSize modeSize = QSize(size["width"].toInt(), size["height"].toInt()); + const int refreshRate = round(modeInfo["refresh"].toDouble() * 1000); + + const auto modes = output->modes(); + auto it = std::find_if(modes.begin(), modes.end(), [&modeSize, &refreshRate](const auto &mode) { + return mode->size() == modeSize && mode->refreshRate() == refreshRate; + }); + return (it != modes.end()) ? *it : nullptr; +} } bool DrmBackend::readOutputsConfiguration(const QVector &outputs) @@ -497,10 +510,10 @@ bool DrmBackend::readOutputsConfiguration(const QVector &ou props->vrrPolicy = static_cast(outputInfo["vrrpolicy"].toInt(static_cast(props->vrrPolicy))); props->rgbRange = static_cast(outputInfo["rgbrange"].toInt(static_cast(props->rgbRange))); - if (const QJsonObject mode = outputInfo["mode"].toObject(); !mode.isEmpty()) { - const QJsonObject size = mode["size"].toObject(); - props->modeSize = QSize(size["width"].toInt(), size["height"].toInt()); - props->refreshRate = round(mode["refresh"].toDouble() * 1000); + if (const QJsonObject modeInfo = outputInfo["mode"].toObject(); !modeInfo.isEmpty()) { + if (auto mode = KWinKScreenIntegration::parseMode(output, modeInfo)) { + props->mode = mode; + } } } else { props->enabled = true; diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 0abe803923..fcdc389040 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -397,15 +397,7 @@ bool DrmOutput::queueChanges(const OutputConfiguration &config) static int envOnlySoftwareRotations = qEnvironmentVariableIntValue("KWIN_DRM_SW_ROTATIONS_ONLY", &valid) == 1 || !valid; const auto props = config.constChangeSet(this); - const auto modelist = m_connector->modes(); - const auto it = std::find_if(modelist.begin(), modelist.end(), [&props](const auto &mode) { - return mode->size() == props->modeSize && mode->refreshRate() == props->refreshRate; - }); - if (it == modelist.end()) { - qCWarning(KWIN_DRM).nospace() << "Could not find mode " << props->modeSize << "@" << props->refreshRate << " for output " << this; - return false; - } - m_pipeline->setMode(*it); + m_pipeline->setMode(std::static_pointer_cast(props->mode)); m_pipeline->setOverscan(props->overscan); m_pipeline->setRgbRange(props->rgbRange); m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform)); diff --git a/src/outputconfiguration.cpp b/src/outputconfiguration.cpp index 8a36eb3d80..2e34f29779 100644 --- a/src/outputconfiguration.cpp +++ b/src/outputconfiguration.cpp @@ -25,8 +25,7 @@ std::shared_ptr OutputConfiguration::constChangeSet(Output *out props->enabled = output->isEnabled(); props->pos = output->geometry().topLeft(); props->scale = output->scale(); - props->modeSize = output->modeSize(); - props->refreshRate = output->refreshRate(); + props->mode = output->currentMode(); props->transform = output->transform(); props->overscan = output->overscan(); props->rgbRange = output->rgbRange(); diff --git a/src/outputconfiguration.h b/src/outputconfiguration.h index 5076fa21e7..f74d090c74 100644 --- a/src/outputconfiguration.h +++ b/src/outputconfiguration.h @@ -20,11 +20,10 @@ namespace KWin class KWIN_EXPORT OutputChangeSet { public: + std::shared_ptr mode; bool enabled; QPoint pos; float scale; - QSize modeSize; - uint32_t refreshRate; Output::Transform transform; uint32_t overscan; Output::RgbRange rgbRange; diff --git a/src/platform.cpp b/src/platform.cpp index 568cc3df92..b715fb2f85 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -132,12 +132,22 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa qCWarning(KWIN_CORE) << "Could NOT find output matching " << it.key()->uuid(); continue; } + + const auto modes = output->modes(); + const auto modeIt = std::find_if(modes.begin(), modes.end(), [&changeset](const auto &mode) { + return mode->size() == changeset->size() && mode->refreshRate() == changeset->refreshRate(); + }); + if (modeIt == modes.end()) { + qCWarning(KWIN_CORE).nospace() << "Could not find mode " << changeset->size() << "@" << changeset->refreshRate() << " for output " << this; + config->setFailed(); + return; + } + auto props = cfg.changeSet(output); props->enabled = changeset->enabled(); props->pos = changeset->position(); props->scale = changeset->scale(); - props->modeSize = changeset->size(); - props->refreshRate = changeset->refreshRate(); + props->mode = *modeIt; props->transform = static_cast(changeset->transform()); props->overscan = changeset->overscan(); props->rgbRange = static_cast(changeset->rgbRange());