diff --git a/src/backends/drm/drm_backend.cpp b/src/backends/drm/drm_backend.cpp index ebe7e2ad4c..2d06f84e0d 100644 --- a/src/backends/drm/drm_backend.cpp +++ b/src/backends/drm/drm_backend.cpp @@ -212,6 +212,21 @@ DrmGpu *DrmBackend::addGpu(const QString &fileName) void DrmBackend::addOutput(DrmAbstractOutput *o) { + const bool allOff = std::all_of(m_outputs.begin(), m_outputs.end(), [](Output *output) { + return output->dpmsMode() != Output::DpmsMode::On; + }); + if (allOff && m_recentlyUnpluggedDpmsOffOutputs.contains(o->uuid())) { + if (DrmOutput *drmOutput = qobject_cast(o)) { + // When the system is in dpms power saving mode, KWin turns on all outputs if the user plugs a new output in + // as that's an intentional action and they expect to see the output light up. + // Some outputs however temporarily disconnect in some situations, most often shortly after they go into standby. + // To not turn on outputs in that case, restore the previous dpms state + drmOutput->updateDpmsMode(Output::DpmsMode::Off); + drmOutput->pipeline()->setActive(false); + drmOutput->renderLoop()->inhibit(); + m_recentlyUnpluggedDpmsOffOutputs.removeOne(drmOutput->uuid()); + } + } m_outputs.append(o); Q_EMIT outputAdded(o); o->updateEnabled(true); @@ -219,6 +234,13 @@ void DrmBackend::addOutput(DrmAbstractOutput *o) void DrmBackend::removeOutput(DrmAbstractOutput *o) { + if (o->dpmsMode() == Output::DpmsMode::Off) { + const QUuid id = o->uuid(); + m_recentlyUnpluggedDpmsOffOutputs.push_back(id); + QTimer::singleShot(1000, this, [this, id]() { + m_recentlyUnpluggedDpmsOffOutputs.removeOne(id); + }); + } o->updateEnabled(false); m_outputs.removeOne(o); Q_EMIT outputRemoved(o); diff --git a/src/backends/drm/drm_backend.h b/src/backends/drm/drm_backend.h index ba5f7d287c..4622ccd626 100644 --- a/src/backends/drm/drm_backend.h +++ b/src/backends/drm/drm_backend.h @@ -89,7 +89,7 @@ private: std::unique_ptr m_socketNotifier; Session *m_session; QVector m_outputs; - DrmVirtualOutput *m_placeHolderOutput = nullptr; + QVector m_recentlyUnpluggedDpmsOffOutputs; const QStringList m_explicitGpus; std::vector> m_gpus; diff --git a/src/workspace.cpp b/src/workspace.cpp index 88fd07ec9c..d2fd2d6bd6 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -1292,6 +1292,9 @@ void Workspace::updateOutputs(const QVector &outputOrder) m_tileManagers[output] = std::make_unique(output); connect(output, &Output::aboutToTurnOff, this, &Workspace::createDpmsFilter); connect(output, &Output::dpmsModeChanged, this, &Workspace::maybeDestroyDpmsFilter); + if (output->dpmsMode() != Output::DpmsMode::On) { + createDpmsFilter(); + } Q_EMIT outputAdded(output); } maybeDestroyDpmsFilter();