diff --git a/src/backends/drm/drm_output.cpp b/src/backends/drm/drm_output.cpp index 1c2f0be885..0fb8fa3e51 100644 --- a/src/backends/drm/drm_output.cpp +++ b/src/backends/drm/drm_output.cpp @@ -404,18 +404,18 @@ 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 mode = props->mode.lock(); + const auto mode = props->mode.value_or(currentMode()).lock(); if (!mode) { return false; } m_pipeline->setMode(std::static_pointer_cast(mode)); - m_pipeline->setOverscan(props->overscan); - m_pipeline->setRgbRange(props->rgbRange); - m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform)); + m_pipeline->setOverscan(props->overscan.value_or(m_pipeline->overscan())); + m_pipeline->setRgbRange(props->rgbRange.value_or(m_pipeline->rgbRange())); + m_pipeline->setRenderOrientation(outputToPlaneTransform(props->transform.value_or(transform()))); if (!envOnlySoftwareRotations && m_gpu->atomicModeSetting()) { m_pipeline->setBufferOrientation(m_pipeline->renderOrientation()); } - m_pipeline->setEnable(props->enabled); + m_pipeline->setEnable(props->enabled.value_or(m_pipeline->enabled())); return true; } @@ -431,15 +431,15 @@ void DrmOutput::applyQueuedChanges(const OutputConfiguration &config) State next = m_state; next.enabled = props->enabled && m_pipeline->crtc(); - next.position = props->pos; - next.scale = props->scale; - next.transform = props->transform; + next.position = props->pos.value_or(m_state.position); + next.scale = props->scale.value_or(m_state.scale); + next.transform = props->transform.value_or(m_state.transform); next.currentMode = m_pipeline->mode(); next.overscan = m_pipeline->overscan(); next.rgbRange = m_pipeline->rgbRange(); setState(next); - setVrrPolicy(props->vrrPolicy); + setVrrPolicy(props->vrrPolicy.value_or(vrrPolicy())); if (!isEnabled() && m_pipeline->needsModeset()) { m_gpu->maybeModeset(); diff --git a/src/core/output.cpp b/src/core/output.cpp index 5a1dfff773..0081336302 100644 --- a/src/core/output.cpp +++ b/src/core/output.cpp @@ -225,14 +225,14 @@ void Output::applyChanges(const OutputConfiguration &config) Q_EMIT aboutToChange(); State next = m_state; - next.enabled = props->enabled; - next.transform = props->transform; - next.position = props->pos; - next.scale = props->scale; - next.rgbRange = props->rgbRange; + next.enabled = props->enabled.value_or(m_state.enabled); + next.transform = props->transform.value_or(m_state.transform); + next.position = props->pos.value_or(m_state.position); + next.scale = props->scale.value_or(m_state.scale); + next.rgbRange = props->rgbRange.value_or(m_state.rgbRange); setState(next); - setVrrPolicy(props->vrrPolicy); + setVrrPolicy(props->vrrPolicy.value_or(vrrPolicy())); Q_EMIT changed(); } diff --git a/src/core/outputconfiguration.cpp b/src/core/outputconfiguration.cpp index 705b22650c..437c3d52b3 100644 --- a/src/core/outputconfiguration.cpp +++ b/src/core/outputconfiguration.cpp @@ -13,25 +13,15 @@ namespace KWin std::shared_ptr OutputConfiguration::changeSet(Output *output) { - const auto ptr = constChangeSet(output); - m_properties[output] = ptr; - return ptr; + auto &ret = m_properties[output]; + if (!ret) { + ret = std::make_shared(); + } + return ret; } std::shared_ptr OutputConfiguration::constChangeSet(Output *output) const { - if (!m_properties.contains(output)) { - auto props = std::make_shared(); - props->enabled = output->isEnabled(); - props->pos = output->geometry().topLeft(); - props->scale = output->scale(); - props->mode = output->currentMode(); - props->transform = output->transform(); - props->overscan = output->overscan(); - props->rgbRange = output->rgbRange(); - props->vrrPolicy = output->vrrPolicy(); - return props; - } return m_properties[output]; } } diff --git a/src/core/outputconfiguration.h b/src/core/outputconfiguration.h index 398cbbc4da..34584257f3 100644 --- a/src/core/outputconfiguration.h +++ b/src/core/outputconfiguration.h @@ -21,14 +21,14 @@ namespace KWin class KWIN_EXPORT OutputChangeSet { public: - std::weak_ptr mode; - bool enabled; - QPoint pos; - float scale; - Output::Transform transform; - uint32_t overscan; - Output::RgbRange rgbRange; - RenderLoop::VrrPolicy vrrPolicy; + std::optional> mode; + std::optional enabled; + std::optional pos; + std::optional scale; + std::optional transform; + std::optional overscan; + std::optional rgbRange; + std::optional vrrPolicy; }; class KWIN_EXPORT OutputConfiguration diff --git a/src/kscreenintegration.cpp b/src/kscreenintegration.cpp index 71a2627775..19584d6f3f 100644 --- a/src/kscreenintegration.cpp +++ b/src/kscreenintegration.cpp @@ -145,7 +145,7 @@ enum Rotation { Right = 8, }; -Output::Transform toDrmTransform(int rotation) +Output::Transform toKWinTransform(int rotation) { switch (Rotation(rotation)) { case None: @@ -207,18 +207,27 @@ std::optional>> readOutputConfi } else { outputOrder.push_back(std::make_pair(0, output)); } - const QJsonObject pos = outputInfo["pos"].toObject(); - props->pos = QPoint(pos["x"].toInt(), pos["y"].toInt()); + if (const QJsonObject pos = outputInfo["pos"].toObject(); !pos.isEmpty()) { + props->pos = QPoint(pos["x"].toInt(), pos["y"].toInt()); + } // settings that are independent of per output setups: const auto &globalInfo = globalOutputInfo ? globalOutputInfo.value() : outputInfo; if (const QJsonValue scale = globalInfo["scale"]; !scale.isUndefined()) { props->scale = scale.toDouble(1.); } - props->transform = KScreenIntegration::toDrmTransform(globalInfo["rotation"].toInt()); - props->overscan = static_cast(globalInfo["overscan"].toInt(props->overscan)); - props->vrrPolicy = static_cast(globalInfo["vrrpolicy"].toInt(static_cast(props->vrrPolicy))); - props->rgbRange = static_cast(globalInfo["rgbrange"].toInt(static_cast(props->rgbRange))); + if (const QJsonValue rotation = globalInfo["rotation"]; !rotation.isUndefined()) { + props->transform = KScreenIntegration::toKWinTransform(rotation.toInt()); + } + if (const QJsonValue overscan = globalInfo["overscan"]; !overscan.isUndefined()) { + props->overscan = globalInfo["overscan"].toInt(); + } + if (const QJsonValue vrrpolicy = globalInfo["vrrpolicy"]; !vrrpolicy.isUndefined()) { + props->vrrPolicy = static_cast(vrrpolicy.toInt()); + } + if (const QJsonValue rgbrange = globalInfo["rgbrange"]; !rgbrange.isUndefined()) { + props->rgbRange = static_cast(rgbrange.toInt()); + } if (const QJsonObject modeInfo = globalInfo["mode"].toObject(); !modeInfo.isEmpty()) { if (auto mode = KScreenIntegration::parseMode(output, modeInfo)) {