diff --git a/wayland_server.h b/wayland_server.h --- a/wayland_server.h +++ b/wayland_server.h @@ -242,6 +242,7 @@ void foreignTransientChanged(KWayland::Server::SurfaceInterface *child); private: + int createScreenLockerConnection(); void shellClientShown(Toplevel *t); quint16 createClientId(KWayland::Server::ClientConnection *c); void destroyInternalConnection(); diff --git a/wayland_server.cpp b/wayland_server.cpp --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -505,20 +505,43 @@ void WaylandServer::initScreenLocker() { - ScreenLocker::KSldApp::self(); - ScreenLocker::KSldApp::self()->setWaylandDisplay(m_display); + auto *screenLockerApp = ScreenLocker::KSldApp::self(); + ScreenLocker::KSldApp::self()->setGreeterEnvironment(kwinApp()->processStartupEnvironment()); ScreenLocker::KSldApp::self()->initialize(); - connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::greeterClientConnectionChanged, this, - [this] () { - m_screenLockerClientConnection = ScreenLocker::KSldApp::self()->greeterClientConnection(); + connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::aboutToLock, this, + [this, screenLockerApp] () { + if (m_screenLockerClientConnection) { + // Already sent data to KScreenLocker. + return; + } + int clientFd = createScreenLockerConnection(); + if (clientFd < 0) { + return; + } + ScreenLocker::KSldApp::self()->setWaylandFd(clientFd); + + for (auto *seat : m_display->seats()) { + connect(seat, &KWayland::Server::SeatInterface::timestampChanged, + screenLockerApp, &ScreenLocker::KSldApp::userActivity); + } } ); connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::unlocked, this, - [this] () { - m_screenLockerClientConnection = nullptr; + [this, screenLockerApp] () { + if (m_screenLockerClientConnection) { + m_screenLockerClientConnection->destroy(); + delete m_screenLockerClientConnection; + m_screenLockerClientConnection = nullptr; + } + + for (auto *seat : m_display->seats()) { + disconnect(seat, &KWayland::Server::SeatInterface::timestampChanged, + screenLockerApp, &ScreenLocker::KSldApp::userActivity); + } + ScreenLocker::KSldApp::self()->setWaylandFd(-1); } ); @@ -541,6 +564,18 @@ return ret; } +int WaylandServer::createScreenLockerConnection() +{ + const auto socket = createConnection(); + if (!socket.connection) { + return -1; + } + m_screenLockerClientConnection = socket.connection; + connect(m_screenLockerClientConnection, &KWayland::Server::ClientConnection::disconnected, + this, [this] { m_screenLockerClientConnection = nullptr; }); + return socket.fd; +} + int WaylandServer::createXWaylandConnection() { const auto socket = createConnection();