Package: release.debian.org
Severity: normal
X-Debbugs-Cc: kscreenloc...@packages.debian.org, Debian Qt/KDE Maintainers 
<debian-qt-kde@lists.debian.org>
Control: affects -1 + src:kscreenlocker
User: release.debian....@packages.debian.org
Usertags: unblock

Dear Release Team,

please unblock package kscreenlocker.

[ Reason ]
It contains the following changes:
* New upstream release (6.3.5).
* Relax inter-plasma versioned dependency constraint so we can upload
  only 6.3.5 packages that have actual code changes.
* Backport upstream commits:
  - Sync password input between screens in multi-monitor setups.
  (kde#433563)
  - Correctly use PAM configuration for login timeout instead of hardcoded
  value. (kde#489898)
  - Fix hard freeze under wayland when triggering sleep inhibition in some
  situations like starting a video in firefox. (kde#501073)
* Fix unwanted lockcreen messages due to missing PAM configurations to
  handle fingerprint sensors and smartcards. (Closes: #1089081)

[ Tests ]
- Tested lock screen and user switch, suspend and resume in various
  screen configurations.
- Upstream test suite passes in sbuild.

[ Risks ]
Only backport of upstream commits that apply cleanly. Further fixes can
easily be backported or the changes reverted.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing


Thanks!


unblock kscreenlocker/6.3.5-1
diff -Nru kscreenlocker-6.3.4/CMakeLists.txt kscreenlocker-6.3.5/CMakeLists.txt
--- kscreenlocker-6.3.4/CMakeLists.txt  2025-04-02 05:36:23.000000000 +0200
+++ kscreenlocker-6.3.5/CMakeLists.txt  2025-05-06 19:57:16.000000000 +0200
@@ -2,10 +2,10 @@
 
 project(kscreenlocker)
 set(CMAKE_C_STANDARD 99)
-set(PROJECT_VERSION "6.3.4")
+set(PROJECT_VERSION "6.3.5")
 set(PROJECT_VERSION_MAJOR 6)
 
-set(PROJECT_DEP_VERSION "6.3.4")
+set(PROJECT_DEP_VERSION "6.3.5")
 set(QT_MIN_VERSION "6.7.0")
 set(KF6_MIN_VERSION "6.10.0")
 
diff -Nru kscreenlocker-6.3.4/debian/changelog 
kscreenlocker-6.3.5/debian/changelog
--- kscreenlocker-6.3.4/debian/changelog        2025-04-03 01:02:14.000000000 
+0200
+++ kscreenlocker-6.3.5/debian/changelog        2025-05-19 00:58:41.000000000 
+0200
@@ -1,3 +1,21 @@
+kscreenlocker (6.3.5-1) unstable; urgency=medium
+
+  [ Aurélien COUDERC ]
+  * New upstream release (6.3.5).
+  * Relax inter-plasma versioned dependency constraint so we can upload
+    only 6.3.5 packages that have actual code changes.
+  * Backport upstream commits:
+    - Sync password input between screens in multi-monitor setups.
+    (kde#433563)
+    - Correctly use PAM configuration for login timeout instead of hardcoded
+    value. (kde#489898)
+    - Fix hard freeze under wayland when triggering sleep inhibition in some
+    situations like starting a video in firefox. (kde#501073)
+  * Fix unwanted lockcreen messages due to missing PAM configurations to
+    handle fingerprint sensors and smartcards. (Closes: #1089081)
+
+ -- Aurélien COUDERC <couc...@debian.org>  Mon, 19 May 2025 00:58:41 +0200
+
 kscreenlocker (6.3.4-1) unstable; urgency=medium
 
   [ Pino Toscano ]
diff -Nru kscreenlocker-6.3.4/debian/control kscreenlocker-6.3.5/debian/control
--- kscreenlocker-6.3.4/debian/control  2025-04-03 00:08:49.000000000 +0200
+++ kscreenlocker-6.3.5/debian/control  2025-05-19 00:58:41.000000000 +0200
@@ -88,6 +88,10 @@
 Pre-Depends: psmisc,
 Depends: ${misc:Depends}, ${shlibs:Depends},
 Recommends: kde-config-screenlocker,
+Suggests: libpam-fprintd,
+          libpam-kwallet5,
+          libpam-sss,
+          libpam-pkcs11,
 Breaks: libkscreenlocker5,
 Replaces: libkscreenlocker5,
 Description: Secure lock screen architecture
diff -Nru kscreenlocker-6.3.4/debian/libkscreenlocker6.install 
kscreenlocker-6.3.5/debian/libkscreenlocker6.install
--- kscreenlocker-6.3.4/debian/libkscreenlocker6.install        2024-11-26 
23:48:59.000000000 +0100
+++ kscreenlocker-6.3.5/debian/libkscreenlocker6.install        2025-05-19 
00:58:41.000000000 +0200
@@ -1,3 +1,4 @@
+../pam.d/* usr/lib/pam.d/
 usr/lib/*/libKScreenLocker.so.6
 usr/lib/*/libKScreenLocker.so.6.*
 usr/lib/*/libexec/kscreenlocker_greet
diff -Nru kscreenlocker-6.3.4/debian/pam.d/kde 
kscreenlocker-6.3.5/debian/pam.d/kde
--- kscreenlocker-6.3.4/debian/pam.d/kde        1970-01-01 01:00:00.000000000 
+0100
+++ kscreenlocker-6.3.5/debian/pam.d/kde        2025-05-19 00:58:41.000000000 
+0200
@@ -0,0 +1,26 @@
+#%PAM-1.0
+# Taken from gdm3’s gdm-password
+auth    requisite       pam_nologin.so
+auth   required        pam_succeed_if.so user != root quiet_success
+@include common-auth
+auth    optional        pam_kwallet5.so
+@include common-account
+# SELinux needs to be the first session rule. This ensures that any 
+# lingering context has been cleared. Without this it is possible 
+# that a module could execute code in the wrong domain.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so close
+session required        pam_loginuid.so
+# SELinux needs to intervene at login time to ensure that the process
+# starts in the proper default security context. Only sessions which are
+# intended to run in the user's context should be run after this.
+# pam_selinux.so changes the SELinux context of the used TTY and configures
+# SELinux in order to transition to the user context with the next execve()
+# call.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so open
+session optional        pam_keyinit.so force revoke
+session required        pam_limits.so
+session required        pam_env.so readenv=1
+session required        pam_env.so readenv=1 envfile=/etc/default/locale
+@include common-session
+session optional        pam_kwallet5.so auto_start
+@include common-password
diff -Nru kscreenlocker-6.3.4/debian/pam.d/kde-fingerprint 
kscreenlocker-6.3.5/debian/pam.d/kde-fingerprint
--- kscreenlocker-6.3.4/debian/pam.d/kde-fingerprint    1970-01-01 
01:00:00.000000000 +0100
+++ kscreenlocker-6.3.5/debian/pam.d/kde-fingerprint    2025-05-19 
00:58:41.000000000 +0200
@@ -0,0 +1,26 @@
+#%PAM-1.0
+# Taken from gdm3’s gdm-fingerprint
+auth    requisite       pam_nologin.so
+auth   required        pam_succeed_if.so user != root quiet_success
+auth   required        pam_fprintd.so
+auth    optional        pam_kwallet5.so
+@include common-account
+# SELinux needs to be the first session rule. This ensures that any 
+# lingering context has been cleared. Without this it is possible 
+# that a module could execute code in the wrong domain.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so close
+session required        pam_loginuid.so
+# SELinux needs to intervene at login time to ensure that the process
+# starts in the proper default security context. Only sessions which are
+# intended to run in the user's context should be run after this.
+# pam_selinux.so changes the SELinux context of the used TTY and configures
+# SELinux in order to transition to the user context with the next execve()
+# call.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so open
+session optional        pam_keyinit.so force revoke
+session required        pam_limits.so
+session required        pam_env.so readenv=1
+session required        pam_env.so readenv=1 envfile=/etc/default/locale
+@include common-session
+session optional        pam_kwallet5.so auto_start
+password required       pam_fprintd.so
diff -Nru kscreenlocker-6.3.4/debian/pam.d/kde-smartcard 
kscreenlocker-6.3.5/debian/pam.d/kde-smartcard
--- kscreenlocker-6.3.4/debian/pam.d/kde-smartcard      1970-01-01 
01:00:00.000000000 +0100
+++ kscreenlocker-6.3.5/debian/pam.d/kde-smartcard      2025-05-19 
00:58:41.000000000 +0200
@@ -0,0 +1,29 @@
+#%PAM-1.0
+# Adapted from gdm3’s gdm-smartcard-sssd-or-password
+auth    [success=ok user_unknown=ignore default=bad] pam_succeed_if.so user != 
root quiet_success
+#auth    [success=2 default=ignore] pam_sss.so allow_missing_name try_cert_auth
+auth    required        pam_sss.so allow_missing_name try_cert_auth
+#auth    substack        common-auth
+auth    requisite       pam_nologin.so
+auth    optional        pam_kwallet5.so
+
+@include common-account
+# SELinux needs to be the first session rule. This ensures that any
+# lingering context has been cleared. Without this it is possible
+# that a module could execute code in the wrong domain.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so close
+session required        pam_loginuid.so
+# SELinux needs to intervene at login time to ensure that the process
+# starts in the proper default security context. Only sessions which are
+# intended to run in the user's context should be run after this.
+# pam_selinux.so changes the SELinux context of the used TTY and configures
+# SELinux in order to transition to the user context with the next execve()
+# call.
+session [success=ok ignore=ignore module_unknown=ignore default=bad]        
pam_selinux.so open
+session optional        pam_keyinit.so force revoke
+session required        pam_limits.so
+session required        pam_env.so readenv=1
+session required        pam_env.so readenv=1 envfile=/etc/default/locale
+@include common-session
+session optional        pam_kwallet5.so auto_start
+@include common-password
diff -Nru 
kscreenlocker-6.3.4/debian/patches/relax-interplasma-versioned-deps.patch 
kscreenlocker-6.3.5/debian/patches/relax-interplasma-versioned-deps.patch
--- kscreenlocker-6.3.4/debian/patches/relax-interplasma-versioned-deps.patch   
1970-01-01 01:00:00.000000000 +0100
+++ kscreenlocker-6.3.5/debian/patches/relax-interplasma-versioned-deps.patch   
2025-05-08 00:30:22.000000000 +0200
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -5,7 +5,7 @@
+ set(PROJECT_VERSION "6.3.5")
+ set(PROJECT_VERSION_MAJOR 6)
+ 
+-set(PROJECT_DEP_VERSION "6.3.5")
++set(PROJECT_DEP_VERSION "6.3.4")
+ set(QT_MIN_VERSION "6.7.0")
+ set(KF6_MIN_VERSION "6.10.0")
+ 
diff -Nru kscreenlocker-6.3.4/debian/patches/series 
kscreenlocker-6.3.5/debian/patches/series
--- kscreenlocker-6.3.4/debian/patches/series   1970-01-01 01:00:00.000000000 
+0100
+++ kscreenlocker-6.3.5/debian/patches/series   2025-05-16 22:53:32.000000000 
+0200
@@ -0,0 +1,9 @@
+relax-interplasma-versioned-deps.patch
+# Sync password input between screens in multi-monitor setups.
+upstream_99702e2d_greeter-sync-password-across-screens.patch
+upstream_1d175e50_greeter-remove-obselete-shareEvent.patch
+upstream_081efa76_greeter-Add-loginFailedDelayStarted-event.patch
+# Fix hard freeze under wayland when triggering sleep inhibition in some 
situations like starting a video in firefox. (kde#501073)
+upstream_da9cca9d_Port-the-ScreenSaver-interface-from-sync-calls-to-powerdevil.patch
+upstream_29378c61_Bump-C-version-to-23.patch
+upstream_ad8d2273_Use-std-expected-to-clean-up-PowerInhibitor.patch
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_081efa76_greeter-Add-loginFailedDelayStarted-event.patch
 
kscreenlocker-6.3.5/debian/patches/upstream_081efa76_greeter-Add-loginFailedDelayStarted-event.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_081efa76_greeter-Add-loginFailedDelayStarted-event.patch
        1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_081efa76_greeter-Add-loginFailedDelayStarted-event.patch
        2025-05-16 22:53:07.000000000 +0200
@@ -0,0 +1,136 @@
+From 081efa761f175ab87965771eef9629279164afee Mon Sep 17 00:00:00 2001
+From: Akash Suresh <akash.sur...@mercedes-benz.com>
+Date: Sun, 2 Mar 2025 18:57:31 +0530
+Subject: [PATCH] greeter: Add loginFailedDelayStarted event
+
+- Add a loginFailedDelayStarted to track when we know that the login failed, 
but control is still with PAM.
+- This event can replace the falsely named "graceLockTimer" in the lockscreen.
+- Required for https://bugs.kde.org/show_bug.cgi?id=407473
+
+BUG: 489898
+---
+ greeter/pamauthenticator.cpp  | 25 ++++++++++++++++++++-----
+ greeter/pamauthenticator.h    |  1 +
+ greeter/pamauthenticators.cpp | 10 ++++++++++
+ greeter/pamauthenticators.h   |  1 +
+ 4 files changed, 32 insertions(+), 5 deletions(-)
+
+diff --git a/greeter/pamauthenticator.cpp b/greeter/pamauthenticator.cpp
+index ef43989b..077831d7 100644
+--- a/greeter/pamauthenticator.cpp
++++ b/greeter/pamauthenticator.cpp
+@@ -9,6 +9,7 @@
+ #include <QDebug>
+ #include <QEventLoop>
+ #include <QMetaMethod>
++#include <QThread>
+ #include <security/pam_appl.h>
+ 
+ #include "kscreenlocker_greet_logging.h"
+@@ -30,6 +31,7 @@ Q_SIGNALS:
+     void infoMessage(const QString &msg);
+     void errorMessage(const QString &msg);
+     void failed();
++    void loginFailedDelayStarted(const uint uSecDelay);
+     void succeeded();
+     void unavailabilityChanged(bool unavailable);
+     void inAuthenticateChanged(bool inAuthenticate);
+@@ -188,9 +190,19 @@ void PamWorker::authenticate()
+ 
+ static void fail_delay(int retval, unsigned usec_delay, void *appdata_ptr)
+ {
+-    Q_UNUSED(retval);
+-    Q_UNUSED(usec_delay);
+-    Q_UNUSED(appdata_ptr);
++    auto* worker = reinterpret_cast< PamWorker* >(appdata_ptr); // Refer the 
pam_conv (@sa m_conv) structure for info on appdata_ptr
++    if (!worker) {
++        qCFatal(KSCREENLOCKER_GREET) << "[PAM worker] appdata_ptr not 
convertible to a valid PamWorker! Cannot apply fail delay";
++        return;
++    }
++    if (retval == PAM_SUCCESS) {
++        qCDebug(KSCREENLOCKER_GREET) << "[PAM worker] Fail delay function was 
called, but authentication result was a success!";
++        return;
++    }
++    Q_EMIT worker->loginFailedDelayStarted(usec_delay);
++    if (usec_delay > 0u) {
++        QThread::usleep(usec_delay); // This calls nanosleep as of Qt 6.8. It 
also handles EINTR (restarts the sleep with the remainder duration when 
interrupted), but not EFAULT or EINVAL.
++    }
+ }
+ 
+ void PamWorker::start(const QString &service, const QString &user)
+@@ -202,8 +214,10 @@ void PamWorker::start(const QString &service, const 
QString &user)
+         m_result = pam_start(qPrintable(service), qPrintable(user), &m_conv, 
&m_handle);
+ 
+     // get errors quicker
+-#ifdef PAM_FAIL_DELAY
+-    pam_set_item(m_handle, PAM_FAIL_DELAY, (void *)fail_delay);
++#if defined(HAVE_PAM_FAIL_DELAY)
++    pam_set_item(m_handle, PAM_FAIL_DELAY, reinterpret_cast< void* 
>(fail_delay));
++#else
++    Q_UNUSED(fail_delay);
+ #endif
+ 
+     if (m_result != PAM_SUCCESS) {
+@@ -268,6 +282,7 @@ PamAuthenticator::PamAuthenticator(const QString &service, 
const QString &user,
+     // Failed is not a persistent state. When a view provides authentication 
that will either result in failure or success,
+     // failure simply means that the prompt is getting delayed.
+     connect(d, &PamWorker::failed, this, &PamAuthenticator::failed);
++    connect(d, &PamWorker::loginFailedDelayStarted, this, 
&PamAuthenticator::loginFailedDelayStarted);
+ 
+     m_thread.start();
+     init(service, user);
+diff --git a/greeter/pamauthenticator.h b/greeter/pamauthenticator.h
+index aa3ecb68..914f22ab 100644
+--- a/greeter/pamauthenticator.h
++++ b/greeter/pamauthenticator.h
+@@ -65,6 +65,7 @@ Q_SIGNALS:
+     void succeeded();
+     void failed();
+     void availableChanged();
++    void loginFailedDelayStarted(const uint uSecDelay);
+ 
+ public Q_SLOTS:
+     void tryUnlock();
+diff --git a/greeter/pamauthenticators.cpp b/greeter/pamauthenticators.cpp
+index b84d4eb1..e9e925a8 100644
+--- a/greeter/pamauthenticators.cpp
++++ b/greeter/pamauthenticators.cpp
+@@ -53,6 +53,11 @@ 
PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator> &&interac
+         d->cancelNoninteractive();
+         Q_EMIT 
failed(PamAuthenticator::NoninteractiveAuthenticatorType::None, 
d->interactive.get());
+     });
++    connect(d->interactive.get(), &PamAuthenticator::loginFailedDelayStarted, 
this, [this](const uint uSecDelay) noexcept -> void {
++        qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Delay started on 
login failure for interactive authenticator" << 
qUtf8Printable(d->interactive->service())
++        << "duration:" << uSecDelay;
++        Q_EMIT 
loginFailedDelayStarted(PamAuthenticator::NoninteractiveAuthenticatorType::None,
 d->interactive.get(), uSecDelay);
++    });
+     for (auto &&noninteractive : d->noninteractive) {
+         connect(noninteractive.get(), &PamAuthenticator::succeeded, this, 
[this, &noninteractive] {
+             qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Success from 
non-interactive authenticator" << qUtf8Printable(noninteractive->service());
+@@ -68,6 +73,11 @@ 
PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator> &&interac
+             qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: 
Non-interactive authenticator" << qUtf8Printable(noninteractive->service()) << 
"failed";
+             Q_EMIT failed(noninteractive->authenticatorType(), 
noninteractive.get());
+         });
++        connect(noninteractive.get(), 
&PamAuthenticator::loginFailedDelayStarted, this, [this, &noninteractive](const 
uint uSecDelay) noexcept -> void {
++            qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Delay started 
on login failure for non-interactive authenticator" << 
qUtf8Printable(noninteractive->service())
++            << "duration:" << uSecDelay;
++            Q_EMIT 
loginFailedDelayStarted(noninteractive->authenticatorType(), 
noninteractive.get(), uSecDelay);
++        });
+         connect(noninteractive.get(), &PamAuthenticator::infoMessage, this, 
[this, &noninteractive]() {
+             if (!d->hadPrompt) {
+                 d->hadPrompt = true;
+diff --git a/greeter/pamauthenticators.h b/greeter/pamauthenticators.h
+index 9184e7e8..14221b75 100644
+--- a/greeter/pamauthenticators.h
++++ b/greeter/pamauthenticators.h
+@@ -77,6 +77,7 @@ public:
+     Q_SIGNAL void failed(PamAuthenticator::NoninteractiveAuthenticatorTypes 
what, PamAuthenticator *authenticator);
+     Q_SIGNAL void 
noninteractiveError(PamAuthenticator::NoninteractiveAuthenticatorTypes what, 
PamAuthenticator *authenticator);
+     Q_SIGNAL void 
noninteractiveInfo(PamAuthenticator::NoninteractiveAuthenticatorTypes what, 
PamAuthenticator *authenticator);
++    Q_SIGNAL void 
loginFailedDelayStarted(PamAuthenticator::NoninteractiveAuthenticatorTypes 
what, PamAuthenticator *authenticator, const uint uSecDelay);
+ 
+     void setGraceLocked(bool b);
+ 
+-- 
+GitLab
+
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_1d175e50_greeter-remove-obselete-shareEvent.patch
 
kscreenlocker-6.3.5/debian/patches/upstream_1d175e50_greeter-remove-obselete-shareEvent.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_1d175e50_greeter-remove-obselete-shareEvent.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_1d175e50_greeter-remove-obselete-shareEvent.patch
       2025-05-16 22:53:07.000000000 +0200
@@ -0,0 +1,82 @@
+From 1d175e50b05d0873c0f94031c1e196b2be195bb3 Mon Sep 17 00:00:00 2001
+From: Yifan Zhu <fanzhuyi...@gmail.com>
+Date: Fri, 10 Jan 2025 11:30:40 -0800
+Subject: [PATCH] greeter: remove obselete shareEvent
+
+shareEvent used to sync passwords across multiple screens. This has been
+reported to be broken since 5.21, and has been superseded by better
+method of syncing passwords.
+
+CCBUG: 433563
+---
+ greeter/greeterapp.cpp | 30 ------------------------------
+ greeter/greeterapp.h   |  1 -
+ 2 files changed, 31 deletions(-)
+
+diff --git a/greeter/greeterapp.cpp b/greeter/greeterapp.cpp
+index fc24323a..7b2b1a18 100644
+--- a/greeter/greeterapp.cpp
++++ b/greeter/greeterapp.cpp
+@@ -612,12 +612,10 @@ bool UnlockApp::eventFilter(QObject *obj, QEvent *event)
+     }
+ 
+     if (event->type() == QEvent::KeyPress) { // react if saver is visible
+-        shareEvent(event, qobject_cast<PlasmaQuick::QuickViewSharedEngine 
*>(obj));
+         return false; // we don't care
+     } else if (event->type() == QEvent::KeyRelease) { // conditionally reshow 
the saver
+         QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+         if (ke->key() != Qt::Key_Escape) {
+-            shareEvent(event, qobject_cast<PlasmaQuick::QuickViewSharedEngine 
*>(obj));
+             return false; // irrelevant
+         } else if (!m_testing) { // don't turn screen off in testing mode.
+             auto dpms = new KScreen::Dpms(this);
+@@ -638,34 +636,6 @@ bool UnlockApp::eventFilter(QObject *obj, QEvent *event)
+     return false;
+ }
+ 
+-/*
+- * This function forwards an event from one greeter window to all others
+- * It's used to have the keyboard operate on all greeter windows (on every 
screen)
+- * at once so that the user gets visual feedback on the screen he's looking 
at -
+- * even if the focus is actually on a powered off screen.
+- */
+-
+-void UnlockApp::shareEvent(QEvent *e, PlasmaQuick::QuickViewSharedEngine 
*from)
+-{
+-    // from can be NULL any time (because the parameter is passed as 
qobject_cast)
+-    // m_views.contains(from) is atm. supposed to be true but required if any 
further
+-    // QQuickView are added (which are not part of m_views)
+-    // this makes "from" an optimization (nullptr check aversion)
+-    if (from && m_views.contains(from)) {
+-        // NOTICE any recursion in the event sharing will prevent 
authentication on multiscreen setups!
+-        // Any change in regarded event processing shall be tested thoroughly!
+-        removeEventFilter(this); // prevent recursion!
+-        const bool accepted = e->isAccepted(); // store state
+-        for (PlasmaQuick::QuickViewSharedEngine *view : 
std::as_const(m_views)) {
+-            if (view != from) {
+-                QCoreApplication::sendEvent(view, e);
+-                e->setAccepted(accepted);
+-            }
+-        }
+-        installEventFilter(this);
+-    }
+-}
+-
+ void UnlockApp::setGraceTime(int milliseconds)
+ {
+     m_graceTime = milliseconds;
+diff --git a/greeter/greeterapp.h b/greeter/greeterapp.h
+index 7e138469..b636640e 100644
+--- a/greeter/greeterapp.h
++++ b/greeter/greeterapp.h
+@@ -75,7 +75,6 @@ private Q_SLOTS:
+ 
+ private:
+     void initialize();
+-    void shareEvent(QEvent *e, PlasmaQuick::QuickViewSharedEngine *from);
+     PlasmaQuick::SharedQmlEngine 
*loadWallpaperPlugin(PlasmaQuick::QuickViewSharedEngine *view);
+     void setWallpaperItemProperties(PlasmaQuick::SharedQmlEngine 
*wallpaperObject, PlasmaQuick::QuickViewSharedEngine *view);
+     void screenGeometryChanged(QScreen *screen, const QRect &geo);
+-- 
+GitLab
+
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_29378c61_Bump-C-version-to-23.patch 
kscreenlocker-6.3.5/debian/patches/upstream_29378c61_Bump-C-version-to-23.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_29378c61_Bump-C-version-to-23.patch 
    1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_29378c61_Bump-C-version-to-23.patch 
    2025-05-16 22:53:32.000000000 +0200
@@ -0,0 +1,26 @@
+From 29378c617913600a913f4bcaca500aab4fb449e8 Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorod...@kde.org>
+Date: Wed, 23 Apr 2025 11:16:56 +0300
+Subject: [PATCH] Bump C++ version to 23
+
+So it's possible to use std::expected.
+---
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index c82a28e6..dee6b70c 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -9,7 +9,7 @@ set(PROJECT_DEP_VERSION "6.2.90")
+ set(QT_MIN_VERSION "6.7.0")
+ set(KF6_MIN_VERSION "6.10.0")
+ 
+-set(CMAKE_CXX_STANDARD 20)
++set(CMAKE_CXX_STANDARD 23)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ 
+ find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE)
+-- 
+GitLab
+
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_99702e2d_greeter-sync-password-across-screens.patch
 
kscreenlocker-6.3.5/debian/patches/upstream_99702e2d_greeter-sync-password-across-screens.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_99702e2d_greeter-sync-password-across-screens.patch
     1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_99702e2d_greeter-sync-password-across-screens.patch
     2025-05-16 22:52:47.000000000 +0200
@@ -0,0 +1,94 @@
+From 99702e2def21cba69439a754690d6a47251816df Mon Sep 17 00:00:00 2001
+From: Yifan Zhu <fanzhuyi...@gmail.com>
+Date: Fri, 10 Jan 2025 11:23:40 -0800
+Subject: [PATCH] greeter: sync password across screens
+
+Create PasswordSync Singleton to explicitly sync password on different
+screens.
+
+Test plan:
+- use multiscreen setup
+- break lock screen theme, lock screen and verify fallback theme is used
+- type on one password box, verify password is synced to other screen
+- make deletions and insertions in other screen, and verify changes are
+  synced back
+
+CCBUG: 433563
+---
+ greeter/fallbacktheme.qrc              |  2 ++
+ greeter/fallbacktheme/Greeter.qml      | 12 +++++++++++-
+ greeter/fallbacktheme/PasswordSync.qml | 13 +++++++++++++
+ greeter/fallbacktheme/qmldir           |  4 ++++
+ 4 files changed, 30 insertions(+), 1 deletion(-)
+ create mode 100644 greeter/fallbacktheme/PasswordSync.qml
+ create mode 100644 greeter/fallbacktheme/qmldir
+
+diff --git a/greeter/fallbacktheme.qrc b/greeter/fallbacktheme.qrc
+index 58740eaa..150816bc 100644
+--- a/greeter/fallbacktheme.qrc
++++ b/greeter/fallbacktheme.qrc
+@@ -2,5 +2,7 @@
+  <qresource>
+     <file>fallbacktheme/LockScreen.qml</file>
+     <file>fallbacktheme/Greeter.qml</file>
++    <file>fallbacktheme/PasswordSync.qml</file>
++    <file>fallbacktheme/qmldir</file>
+  </qresource>
+ </RCC>
+diff --git a/greeter/fallbacktheme/Greeter.qml 
b/greeter/fallbacktheme/Greeter.qml
+index e4683931..17715e22 100644
+--- a/greeter/fallbacktheme/Greeter.qml
++++ b/greeter/fallbacktheme/Greeter.qml
+@@ -80,9 +80,19 @@ Item {
+             Layout.alignment: Qt.AlignHCenter
+             implicitWidth: Kirigami.Units.gridUnit * 15
+             enabled: !authenticator.busy
++            text: PasswordSync.password
+             Keys.onEnterPressed: authenticator.startAuthenticating()
+             Keys.onReturnPressed: authenticator.startAuthenticating()
+-            Keys.onEscapePressed: password.text = ""
++            Keys.onEscapePressed: {
++                password.text = ""
++                password.text = Qt.binding(() => PasswordSync.password)
++            }
++        }
++
++        Binding {
++            target: PasswordSync
++            property: "password"
++            value: password.text
+         }
+ 
+         PlasmaComponents3.Label {
+diff --git a/greeter/fallbacktheme/PasswordSync.qml 
b/greeter/fallbacktheme/PasswordSync.qml
+new file mode 100644
+index 00000000..8a1eb983
+--- /dev/null
++++ b/greeter/fallbacktheme/PasswordSync.qml
+@@ -0,0 +1,13 @@
++/*
++    SPDX-FileCopyrightText: 2025 Yifan Zhu <fanzhuyi...@gmail.com>
++
++    SPDX-License-Identifier: GPL-2.0-or-later
++*/
++
++pragma Singleton
++
++import QtQuick 2.15
++
++QtObject {
++    property string password
++}
+diff --git a/greeter/fallbacktheme/qmldir b/greeter/fallbacktheme/qmldir
+new file mode 100644
+index 00000000..759d12d5
+--- /dev/null
++++ b/greeter/fallbacktheme/qmldir
+@@ -0,0 +1,4 @@
++# SPDX-FileCopyrightText: 2025 Yifan Zhu <fanzhuyi...@gmail.com>
++# SPDX-License-Identifier: GPL-2.0-or-later
++
++singleton PasswordSync 1.0 PasswordSync.qml
+-- 
+GitLab
+
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_ad8d2273_Use-std-expected-to-clean-up-PowerInhibitor.patch
 
kscreenlocker-6.3.5/debian/patches/upstream_ad8d2273_Use-std-expected-to-clean-up-PowerInhibitor.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_ad8d2273_Use-std-expected-to-clean-up-PowerInhibitor.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_ad8d2273_Use-std-expected-to-clean-up-PowerInhibitor.patch
      2025-05-16 22:53:32.000000000 +0200
@@ -0,0 +1,88 @@
+From ad8d2273b9169564c95acbe58e7a78da37e14a2d Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorod...@kde.org>
+Date: Wed, 23 Apr 2025 11:25:35 +0300
+Subject: [PATCH] Use std::expected to clean up PowerInhibitor
+
+---
+ interface.cpp | 23 +++++++++--------------
+ interface.h   |  5 +++--
+ 2 files changed, 12 insertions(+), 16 deletions(-)
+
+diff --git a/interface.cpp b/interface.cpp
+index 2b73b677..e4a83f01 100644
+--- a/interface.cpp
++++ b/interface.cpp
+@@ -38,10 +38,7 @@ PowerInhibitor::~PowerInhibitor()
+ void PowerInhibitor::release()
+ {
+     m_released = true;
+-    // TODO: See how to clean up this code.
+-    if (m_failed) {
+-        deleteLater();
+-    } else if (m_cookie) {
++    if (m_cookie.has_value()) {
+         uninhibit();
+     }
+ }
+@@ -60,27 +57,25 @@ void PowerInhibitor::inhibit(const QString 
&applicationName, const QString &reas
+ 
+         if (!reply.isValid()) {
+             qCWarning(KSCREENLOCKER) << 
"org.kde.Solid.PowerManagement.PolicyAgent.AddInhibition failed:" << 
reply.error();
+-            m_failed = true;
++            m_cookie = std::unexpected(reply.error());
+         } else {
+             m_cookie = reply.value();
+         }
+ 
+         if (m_released) {
+-            if (m_failed) {
+-                deleteLater();
+-            } else {
+-                uninhibit();
+-            }
++            uninhibit();
+         }
+     });
+ }
+ 
+ void PowerInhibitor::uninhibit()
+ {
+-    OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
+-                                                               
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
+-                                                               
QDBusConnection::sessionBus());
+-    policyAgent.ReleaseInhibition(m_cookie.value());
++    if (const auto &result = m_cookie.value()) {
++        OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
++                                                                   
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
++                                                                   
QDBusConnection::sessionBus());
++        policyAgent.ReleaseInhibition(result.value());
++    }
+ 
+     deleteLater();
+ }
+diff --git a/interface.h b/interface.h
+index fac7842a..21447810 100644
+--- a/interface.h
++++ b/interface.h
+@@ -10,6 +10,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ #include <QDBusMessage>
+ #include <QObject>
+ 
++#include <expected>
++
+ class QDBusServiceWatcher;
+ 
+ namespace ScreenLocker
+@@ -29,8 +31,7 @@ private:
+     void inhibit(const QString &applicationName, const QString &reason);
+     void uninhibit();
+ 
+-    std::optional<uint> m_cookie;
+-    bool m_failed = false;
++    std::optional<std::expected<uint, QDBusError>> m_cookie;
+     bool m_released = false;
+ };
+ 
+-- 
+GitLab
+
diff -Nru 
kscreenlocker-6.3.4/debian/patches/upstream_da9cca9d_Port-the-ScreenSaver-interface-from-sync-calls-to-powerdevil.patch
 
kscreenlocker-6.3.5/debian/patches/upstream_da9cca9d_Port-the-ScreenSaver-interface-from-sync-calls-to-powerdevil.patch
--- 
kscreenlocker-6.3.4/debian/patches/upstream_da9cca9d_Port-the-ScreenSaver-interface-from-sync-calls-to-powerdevil.patch
     1970-01-01 01:00:00.000000000 +0100
+++ 
kscreenlocker-6.3.5/debian/patches/upstream_da9cca9d_Port-the-ScreenSaver-interface-from-sync-calls-to-powerdevil.patch
     2025-05-16 22:53:07.000000000 +0200
@@ -0,0 +1,171 @@
+From da9cca9d8f386e52e5d9b001bf48ab977ff735ed Mon Sep 17 00:00:00 2001
+From: Vlad Zahorodnii <vlad.zahorod...@kde.org>
+Date: Wed, 23 Apr 2025 11:00:42 +0300
+Subject: [PATCH] Port the ScreenSaver interface from sync calls to powerdevil
+
+If powerdevil doesn't respond, kwin_wayland can experience a hard
+freeze. This change ports the powerdevil inhibition part away from
+sync calls to async calls to prevent the hard freeze.
+---
+ interface.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++---------
+ interface.h   | 22 ++++++++++++++-
+ 2 files changed, 84 insertions(+), 13 deletions(-)
+
+diff --git a/interface.cpp b/interface.cpp
+index bef7bd52..2b73b677 100644
+--- a/interface.cpp
++++ b/interface.cpp
+@@ -5,6 +5,7 @@ SPDX-FileCopyrightText: 2011 Martin Gräßlin 
<mgraess...@kde.org>
+ SPDX-License-Identifier: GPL-2.0-or-later
+ */
+ #include "interface.h"
++#include "kscreenlocker_logging.h"
+ #include "kscreensaveradaptor.h"
+ #include "ksldapp.h"
+ #include "powerdevilpolicyagent.h"
+@@ -16,6 +17,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ // Qt
+ #include <QDBusConnection>
+ #include <QDBusContext>
++#include <QDBusPendingCallWatcher>
+ #include <QDBusReply>
+ #include <QDBusServiceWatcher>
+ #include <QRandomGenerator>
+@@ -24,6 +26,65 @@ namespace ScreenLocker
+ {
+ const uint ChangeScreenSettings = 4;
+ 
++PowerInhibitor::PowerInhibitor(const QString &applicationName, const QString 
&reason)
++{
++    inhibit(applicationName, reason);
++}
++
++PowerInhibitor::~PowerInhibitor()
++{
++}
++
++void PowerInhibitor::release()
++{
++    m_released = true;
++    // TODO: See how to clean up this code.
++    if (m_failed) {
++        deleteLater();
++    } else if (m_cookie) {
++        uninhibit();
++    }
++}
++
++void PowerInhibitor::inhibit(const QString &applicationName, const QString 
&reason)
++{
++    OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
++                                                               
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
++                                                               
QDBusConnection::sessionBus());
++    QDBusPendingReply<uint> reply = 
policyAgent.AddInhibition(ChangeScreenSettings, applicationName, reason);
++
++    auto watcher = new QDBusPendingCallWatcher(reply, this);
++    connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, 
watcher]() {
++        QDBusPendingReply<uint> reply = *watcher;
++        watcher->deleteLater();
++
++        if (!reply.isValid()) {
++            qCWarning(KSCREENLOCKER) << 
"org.kde.Solid.PowerManagement.PolicyAgent.AddInhibition failed:" << 
reply.error();
++            m_failed = true;
++        } else {
++            m_cookie = reply.value();
++        }
++
++        if (m_released) {
++            if (m_failed) {
++                deleteLater();
++            } else {
++                uninhibit();
++            }
++        }
++    });
++}
++
++void PowerInhibitor::uninhibit()
++{
++    OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
++                                                               
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
++                                                               
QDBusConnection::sessionBus());
++    policyAgent.ReleaseInhibition(m_cookie.value());
++
++    deleteLater();
++}
++
+ Interface::Interface(KSldApp *parent)
+     : QObject(parent)
+     , m_daemon(parent)
+@@ -112,15 +173,10 @@ bool Interface::SetActive(bool state)
+ 
+ uint Interface::Inhibit(const QString &application_name, const QString 
&reason_for_inhibit)
+ {
+-    OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
+-                                                               
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
+-                                                               
QDBusConnection::sessionBus());
+-    QDBusReply<uint> reply = policyAgent.AddInhibition(ChangeScreenSettings, 
application_name, reason_for_inhibit);
+-
+     InhibitRequest sr;
+     sr.cookie = m_next_cookie++;
+     sr.dbusid = message().service();
+-    sr.powerdevilcookie = reply.isValid() ? reply : 0;
++    sr.powerInhibitor = new PowerInhibitor(application_name, 
reason_for_inhibit);
+     m_requests.append(sr);
+     m_serviceWatcher->addWatchedService(sr.dbusid);
+     KSldApp::self()->inhibit();
+@@ -132,12 +188,7 @@ void Interface::UnInhibit(uint cookie)
+     QMutableListIterator<InhibitRequest> it(m_requests);
+     while (it.hasNext()) {
+         if (it.next().cookie == cookie) {
+-            if (uint powerdevilcookie = it.value().powerdevilcookie) {
+-                OrgKdeSolidPowerManagementPolicyAgentInterface 
policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"),
+-                                                                           
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"),
+-                                                                           
QDBusConnection::sessionBus());
+-                policyAgent.ReleaseInhibition(powerdevilcookie);
+-            }
++            it.value().powerInhibitor->release();
+             it.remove();
+             KSldApp::self()->uninhibit();
+             break;
+diff --git a/interface.h b/interface.h
+index 489b404e..fac7842a 100644
+--- a/interface.h
++++ b/interface.h
+@@ -14,12 +14,32 @@ class QDBusServiceWatcher;
+ 
+ namespace ScreenLocker
+ {
++
++class PowerInhibitor : public QObject
++{
++    Q_OBJECT
++
++public:
++    PowerInhibitor(const QString &applicationName, const QString &reason);
++    void release();
++
++private:
++    ~PowerInhibitor() override;
++
++    void inhibit(const QString &applicationName, const QString &reason);
++    void uninhibit();
++
++    std::optional<uint> m_cookie;
++    bool m_failed = false;
++    bool m_released = false;
++};
++
+ class InhibitRequest
+ {
+ public:
+     QString dbusid;
+     uint cookie;
+-    uint powerdevilcookie;
++    PowerInhibitor *powerInhibitor = nullptr;
+ };
+ 
+ class KSldApp;
+-- 
+GitLab
+
diff -Nru kscreenlocker-6.3.4/kcm/kcm_screenlocker.json 
kscreenlocker-6.3.5/kcm/kcm_screenlocker.json
--- kscreenlocker-6.3.4/kcm/kcm_screenlocker.json       2025-04-02 
05:36:23.000000000 +0200
+++ kscreenlocker-6.3.5/kcm/kcm_screenlocker.json       2025-05-06 
19:57:16.000000000 +0200
@@ -118,7 +118,7 @@
     "X-KDE-Keywords[es]": "bloquear,continuar,salvapantallas,bloqueo de 
pantalla,bloqueo,contraseña,dormir,cerrar tapa,bloquear automáticamente,aspecto 
del bloqueo de pantalla,tema de bloqueo de pantalla,fondo del bloqueo de 
pantalla,pantalla de bloqueo,bloquear,bloquear pantalla",
     "X-KDE-Keywords[eu]": 
"giltzatu,berrekin,pantaila-babeslea,pantaila-giltzatua,giltzatzea,blokeoa,blokeatzea,pasahitza,lokartu,tapa
 ixtea,automatikoki giltzatu,pantaila giltzatuaren itxura,pantaila giltzatuaren 
gaia,pantaila giltzatuaren horma-papera,pantaila giltzatua,giltzatu pantaila",
     "X-KDE-Keywords[fi]": 
"lukitus,jatka,näytönsäästäjä,näyttölukko,estä,esto,salasana,valmiustila,sulje 
kansi,lukitse automaattisesti,näytönlukituksen ulkoasu,näytönlukituksen 
teema,näytönlukituksen tausta,taustakuva,lukitusnäyttö",
-    "X-KDE-Keywords[fr]": "verrouiller, continuer, économiseur d'écran, 
verrouillage, bloquer, blocage, mot de passe, veille, basculer l'écran, 
verrouillage automatique, apparence de l'écran de verrouillage, thème de 
l'écran de verrouillage, fond d'écran de verrouillage, écran de verrouillage, 
verouillage de l'écran",
+    "X-KDE-Keywords[fr]": "verrouiller, continuer, économiseur d'écran, 
verrouillage, bloquer, blocage, mot de passe, veille, basculer l'écran, 
verrouillage automatique, apparence de l'écran de verrouillage, thème de 
l'écran de verrouillage, fond d'écran de verrouillage, écran de verrouillage, 
verrouillage de l'écran",
     "X-KDE-Keywords[gl]": 
"lock,bloquear,bloqueo,resume,continuar,screensaver,salvapantallas,screenlock,bloqueo
 de 
pantalla,locking,block,blocking,password,contrasinal,sleep,durmir,suspender,hibernar,close
 lid,pechar a tapa,pechar a pantalla,lock automatically,bloquear 
automaticamente,screen lock appearance,aparencia do bloqueo de pantalla,screen 
lock theme,tema de bloqueo de pantalla,screen lock wallpaper,fondo do bloqueo 
de pantalla,lockscreen,pantalla de bloqueo,lock screen",
     "X-KDE-Keywords[he]": "נעילה,המשך,שומר מסך,נעילת מסך,מסך 
נעילה,נעילה,חסימה,חסום,סיסמה,שינה,סגירת מסך,נעילה אוטומטית,מראה מסך נעילה,ערכת 
עיצוב מסך נעילה,תמונת רקע למסך נעילה,ערכת נושא מסך נעילה",
     "X-KDE-Keywords[hu]": 
"zárolás,feloldás,képernyőkímélő,képernyőzár,zárolás,blokk,blokkolás,jelszó,alvó
 mód,fedél lecsukása,automatikus zárolás,záróképernyő megjelenése,záróképernyő 
téma,záróképernyő háttérkép,zárolóképernyő",
diff -Nru kscreenlocker-6.3.4/po/ko/kscreenlocker.po 
kscreenlocker-6.3.5/po/ko/kscreenlocker.po
--- kscreenlocker-6.3.4/po/ko/kscreenlocker.po  2025-04-02 05:36:23.000000000 
+0200
+++ kscreenlocker-6.3.5/po/ko/kscreenlocker.po  2025-05-06 19:57:16.000000000 
+0200
@@ -1,6 +1,6 @@
 # Copyright (C) YEAR This_file_is_part_of_KDE
 # This file is distributed under the same license as the PACKAGE package.
-# Shinjo Park <k...@peremen.name>, 2012, 2014, 2015, 2017, 2018, 2020, 2021, 
2022, 2023.
+# SPDX-FileCopyrightText: 2012, 2014, 2015, 2017, 2018, 2020, 2021, 2022, 
2023, 2025 Shinjo Park <k...@peremen.name>
 #
 msgid ""
 msgstr ""
@@ -15,7 +15,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Lokalize 22.12.3\n"
+"X-Generator: Lokalize 23.08.5\n"
 
 #: abstractlocker.cpp:43
 #, kde-format

Reply via email to