summaryrefslogtreecommitdiff
path: root/kde-plasma/kwin/files/kwin-5.24.4-waylandserver-lockScreenShown.patch
blob: 4defd5ae594555c53efcadc621314d328c3daa26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
From 9d38f57d84fb9a6f2c4e60f7051f685842f34e0f Mon Sep 17 00:00:00 2001
From: Xaver Hugl <xaver.hugl@gmail.com>
Date: Mon, 28 Mar 2022 18:08:59 +0200
Subject: [PATCH] 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.
---
 src/wayland_server.cpp | 25 +++++++++++++++++++++----
 src/wayland_server.h   | 10 ++++++++++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp
index c850a1b697..6d5e1206a5 100644
--- a/src/wayland_server.cpp
+++ b/src/wayland_server.cpp
@@ -213,10 +213,6 @@ KWaylandServer::ClientConnection *WaylandServer::inputMethodConnection() const
 
 void WaylandServer::registerShellClient(AbstractClient *client)
 {
-    if (client->isLockScreen()) {
-        ScreenLocker::KSldApp::self()->lockScreenShown();
-    }
-
     if (client->readyForPainting()) {
         Q_EMIT shellClientAdded(client);
     } else {
@@ -623,6 +619,8 @@ void WaylandServer::initScreenLocker()
                 m_screenLockerClientConnection = nullptr;
             }
 
+            new LockScreenPresentationWatcher(this);
+
             const QVector<SeatInterface *> seatIfaces = m_display->seats();
             for (auto *seat : seatIfaces) {
                 disconnect(seat, &KWaylandServer::SeatInterface::timestampChanged,
@@ -797,4 +795,23 @@ QString WaylandServer::socketName() const
     return QString();
 }
 
+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;
+    });
+}
 }
diff --git a/src/wayland_server.h b/src/wayland_server.h
index bf1ba6eee5..58dda9a7a2 100644
--- a/src/wayland_server.h
+++ b/src/wayland_server.h
@@ -243,6 +243,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;
-- 
GitLab