waylandserver: only signal lockScreenShown once it has actually been shown
When the system goes to suspend and screen locking for suspend is enabled, suspend is inhibited until ScreenLocker::KSldApp::self()->lockScreenShown() gets called, in order to make sure that the lockscreen is shown before the system goes to standby, and thus also when the system wakes (instead of potentially sensitive user information). However, signalling that when the lockscreen gets mapped can't work reliably, as it's then a matter of timing whether or not KWin actually presents an image with the lockscreen before suspending. To fix that, this commit replaces that logic with only calling lockScreenShown once every output actually got a lockscreen presented.
This commit is contained in:
parent
2aaa9ed5c2
commit
c16a8e09d7
2 changed files with 33 additions and 6 deletions
|
@ -581,12 +581,6 @@ void WaylandServer::initScreenLocker()
|
|||
|
||||
ScreenLocker::KSldApp::self()->setGreeterEnvironment(kwinApp()->processStartupEnvironment());
|
||||
|
||||
connect(this, &WaylandServer::shellClientAdded, this, [](AbstractClient *client) {
|
||||
if (client->isLockScreen()) {
|
||||
ScreenLocker::KSldApp::self()->lockScreenShown();
|
||||
}
|
||||
});
|
||||
|
||||
connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::aboutToLock, this, [this, screenLockerApp]() {
|
||||
if (m_screenLockerClientConnection) {
|
||||
// Already sent data to KScreenLocker.
|
||||
|
@ -598,6 +592,8 @@ void WaylandServer::initScreenLocker()
|
|||
}
|
||||
ScreenLocker::KSldApp::self()->setWaylandFd(clientFd);
|
||||
|
||||
new LockScreenPresentationWatcher(this);
|
||||
|
||||
const QVector<SeatInterface *> seatIfaces = m_display->seats();
|
||||
for (auto *seat : seatIfaces) {
|
||||
connect(seat, &KWaylandServer::SeatInterface::timestampChanged,
|
||||
|
@ -794,4 +790,25 @@ QString WaylandServer::socketName() const
|
|||
return QString();
|
||||
}
|
||||
|
||||
#if KWIN_BUILD_SCREENLOCKER
|
||||
WaylandServer::LockScreenPresentationWatcher::LockScreenPresentationWatcher(WaylandServer *server)
|
||||
{
|
||||
connect(server, &WaylandServer::shellClientAdded, this, [this](AbstractClient *client) {
|
||||
if (client->isLockScreen()) {
|
||||
connect(client->output()->renderLoop(), &RenderLoop::framePresented, this, [this, client]() {
|
||||
// only signal lockScreenShown once all outputs have been presented at least once
|
||||
m_signaledOutputs << client->output();
|
||||
if (m_signaledOutputs.size() == kwinApp()->platform()->enabledOutputs().size()) {
|
||||
ScreenLocker::KSldApp::self()->lockScreenShown();
|
||||
delete this;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
QTimer::singleShot(1000, this, [this]() {
|
||||
ScreenLocker::KSldApp::self()->lockScreenShown();
|
||||
delete this;
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -252,6 +252,16 @@ private:
|
|||
void handleOutputRemoved(AbstractOutput *output);
|
||||
void handleOutputEnabled(AbstractOutput *output);
|
||||
void handleOutputDisabled(AbstractOutput *output);
|
||||
|
||||
class LockScreenPresentationWatcher : public QObject
|
||||
{
|
||||
public:
|
||||
LockScreenPresentationWatcher(WaylandServer *server);
|
||||
|
||||
private:
|
||||
QSet<AbstractOutput *> m_signaledOutputs;
|
||||
};
|
||||
|
||||
KWaylandServer::Display *m_display = nullptr;
|
||||
KWaylandServer::CompositorInterface *m_compositor = nullptr;
|
||||
KWaylandServer::SeatInterface *m_seat = nullptr;
|
||||
|
|
Loading…
Reference in a new issue