backends/drm: don't wake displays up when outputs get temporarily removed
When some displays go to sleep, that can be wrongly detected as a temporary hotunplug by the driver. In order to not wrongly wake up the system with such a display, detect that scenario and set the 'new' output to dpms off again. BUG: 452553 BUG: 379474
This commit is contained in:
parent
99244efa3b
commit
482a1f0fb5
3 changed files with 26 additions and 1 deletions
|
@ -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<DrmOutput *>(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);
|
||||
|
|
|
@ -89,7 +89,7 @@ private:
|
|||
std::unique_ptr<QSocketNotifier> m_socketNotifier;
|
||||
Session *m_session;
|
||||
QVector<DrmAbstractOutput *> m_outputs;
|
||||
DrmVirtualOutput *m_placeHolderOutput = nullptr;
|
||||
QVector<QUuid> m_recentlyUnpluggedDpmsOffOutputs;
|
||||
|
||||
const QStringList m_explicitGpus;
|
||||
std::vector<std::unique_ptr<DrmGpu>> m_gpus;
|
||||
|
|
|
@ -1292,6 +1292,9 @@ void Workspace::updateOutputs(const QVector<Output *> &outputOrder)
|
|||
m_tileManagers[output] = std::make_unique<TileManager>(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();
|
||||
|
|
Loading…
Reference in a new issue