From d67a0b006a4594edd0607a056cacc9cf15e39411 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Mon, 24 Jan 2022 09:42:17 +0100 Subject: [PATCH] backends/drm: guard against wrong KScreen configs --- src/backends/drm/drm_backend.cpp | 30 ++++++++++++++++++++++++++---- src/backends/drm/drm_backend.h | 2 +- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index a2fd6208d6..4d6efc69de 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -432,11 +432,11 @@ namespace KWinKScreenIntegration } } -void DrmBackend::readOutputsConfiguration(const QVector &outputs) +bool DrmBackend::readOutputsConfiguration(const QVector &outputs) { const auto outputsInfo = KWinKScreenIntegration::outputsConfig(outputs); - AbstractOutput *primaryOutput = m_outputs.constFirst(); + AbstractWaylandOutput *primaryOutput = outputs.constFirst(); WaylandOutputConfig cfg; // default position goes from left to right QPoint pos(0, 0); @@ -475,8 +475,23 @@ void DrmBackend::readOutputsConfiguration(const QVector &out } pos.setX(pos.x() + output->geometry().width()); } - applyOutputChanges(cfg); + bool allDisabled = std::all_of(outputs.begin(), outputs.end(), [&cfg](const auto &output) { + return !cfg.changeSet(output)->enabled; + }); + if (allDisabled) { + qCWarning(KWIN_DRM) << "KScreen config would disable all outputs!"; + return false; + } + if (!cfg.changeSet(primaryOutput)->enabled) { + qCWarning(KWIN_DRM) << "KScreen config would disable the primary output!"; + return false; + } + if (!applyOutputChanges(cfg)) { + qCWarning(KWIN_DRM) << "Applying KScreen config failed!"; + return false; + } setPrimaryOutput(primaryOutput); + return true; } void DrmBackend::enableOutput(DrmAbstractOutput *output, bool enable) @@ -498,7 +513,14 @@ void DrmBackend::enableOutput(DrmAbstractOutput *output, bool enable) if (m_enabledOutputs.count() == 1) { auto outputs = m_outputs; outputs.removeOne(output); - readOutputsConfiguration(outputs); + if (!readOutputsConfiguration(outputs)) { + // config is invalid or failed to apply -> Try to enable an output anyways + WaylandOutputConfig cfg; + cfg.changeSet(outputs.constFirst())->enabled = true; + if (!applyOutputChanges(cfg)) { + qCCritical(KWIN_DRM) << "Could not enable any outputs!"; + } + } } if (m_enabledOutputs.count() == 1 && !kwinApp()->isTerminating()) { qCDebug(KWIN_DRM) << "adding placeholder output"; diff --git a/src/backends/drm/drm_backend.h b/src/backends/drm/drm_backend.h index 368409319f..9d64b0625e 100644 --- a/src/backends/drm/drm_backend.h +++ b/src/backends/drm/drm_backend.h @@ -86,7 +86,7 @@ private: void reactivate(); void deactivate(); void updateOutputs(); - void readOutputsConfiguration(const QVector &outputs); + bool readOutputsConfiguration(const QVector &outputs); void handleUdevEvent(); DrmGpu *addGpu(const QString &fileName);