I ran into a small but surprisingly annoying problem with the KDE Plasma lock screen and the fingerprint reader on my ThinkPad.

After opening the laptop, KDE would show the usual lock screen with the wallpaper and clock. Nothing unusual here. The problem was that the password field wouldn’t appear until I pressed a key or moved the mouse.

That also meant the fingerprint reader wasn’t listening yet.

So instead of:

open the lid → put my finger on the sensor

I had to do:

open the lid → wait → press a key → put my finger on the sensor

It’s a small thing, but when you unlock your laptop with a fingerprint dozens of times a day, it gets annoying pretty quickly.

I wanted the lock screen to start accepting fingerprints immediately after it appeared.

Where the problem comes from

KDE doesn’t seem to have a setting for this. The lock screen configuration only controls things like the clock, wallpaper and media controls, so there isn’t an obvious option to make the authentication UI appear immediately.

At that point, I decided to look at the code instead.

In Plasma 6, the lock screen UI is part of plasma-workspace and, on my system, lives here:

/usr/share/plasma/shells/org.kde.plasma.desktop/contents/lockscreen/LockScreenUi.qml

This is worth mentioning because there are quite a few old guides referring to files under /usr/share/plasma/look-and-feel/.... Those paths are from older versions of Plasma.

The interesting part of LockScreenUi.qml is a MouseArea covering the whole screen:

MouseArea {
    id: lockScreenRoot

    property bool uiVisible: false
    // ...
    onPressed: uiVisible = true;
    Keys.onPressed: event => {
        uiVisible = true;
        event.accepted = false;
    }
    onUiVisibleChanged: {
        // ...show UI, start fadeout timer...
        authenticator.startAuthenticating();
    }

The logic is actually quite simple.

Initially, uiVisible is false. The lock screen shows the wallpaper and clock, while the authentication UI remains hidden.

When you press a key or click the screen, uiVisible becomes true. That triggers onUiVisibleChanged, which eventually calls:

authenticator.startAuthenticating();

And that’s the important part.

The fingerprint reader isn’t ignoring the first scan. Authentication simply hasn’t started yet. Until the first input event, fprintd isn’t being asked to verify a fingerprint.

The simple fix

There is already a piece of code that runs when the lock screen is initialized:

Component.onCompleted: launchAnimation.start();

Instead of waiting for user input to make uiVisible true, we can simply make it visible as soon as the component is loaded:

Component.onCompleted: {
    launchAnimation.start();
    lockScreenRoot.uiVisible = true;
}

That’s it.

Setting uiVisible triggers the existing onUiVisibleChanged handler, so the normal authentication flow starts immediately. The password field appears, and fprintd starts listening for a fingerprint without requiring any additional input.

There is no new authentication logic here. We’re just moving the start of the existing logic a little earlier.

Keeping the patch after updates

There is one obvious problem with this approach: LockScreenUi.qml belongs to the plasma-workspace package.

That means a Plasma update will overwrite the file and remove the change.

I considered keeping a complete copy of the lock screen under the user’s local Plasma shell directory, but that seemed worse. We’d have to maintain a copy of a fairly large part of the shell, and sooner or later it could get out of sync with the version shipped by Plasma.

A small patch that can be reapplied after every update seems like a better compromise.

Since I’m running Arch, I used a small script together with a pacman hook.

The patch script

I put the following script at /usr/local/bin/kde-lock-immediate:

#!/usr/bin/env bash
# Patch kscreenlocker's LockScreenUi.qml so the password UI is raised (and
# PAM/fprintd starts listening) as soon as the lock screen appears.
set -euo pipefail

QML=/usr/share/plasma/shells/org.kde.plasma.desktop/contents/lockscreen/LockScreenUi.qml

if [[ ! -f "$QML" ]]; then
  echo "kde-lock-immediate: $QML not found, skipping" >&2
  exit 0
fi

if grep -qF 'lockScreenRoot.uiVisible = true;' "$QML"; then
  exit 0  # already patched
fi

if ! grep -qF 'Component.onCompleted: launchAnimation.start();' "$QML"; then
  echo "kde-lock-immediate: patch target not found in $QML — the file changed upstream, this script needs updating" >&2
  exit 1
fi

# Setting uiVisible triggers onUiVisibleChanged, which both raises the
# password UI and calls authenticator.startAuthenticating() (fprintd on).
sed -i 's|^\( *\)Component\.onCompleted: launchAnimation\.start();$|\1Component.onCompleted: {\n\1    launchAnimation.start();\n\1    lockScreenRoot.uiVisible = true;\n\1}|' "$QML"

echo "kde-lock-immediate: patched $QML"

There are a couple of things I like about this approach.

First, the script is idempotent. Running it again doesn’t modify an already patched file.

Second, it fails loudly if the expected code disappears. If a future Plasma version changes this part of LockScreenUi.qml, the pacman hook will report an error instead of silently pretending that everything is fine.

Finally, it only changes the one line we actually care about. The rest of the file remains untouched and continues to come from the installed Plasma package.

pacman hook

To automatically reapply the patch after plasma-workspace is updated, I created:

/etc/pacman.d/hooks/kde-lock-immediate.hook

with:

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = plasma-workspace

[Action]
Description = Re-applying KDE lock screen immediate-unlock patch...
When = PostTransaction
Exec = /usr/local/bin/kde-lock-immediate
Depends = bash
Depends = sed

Now every time plasma-workspace is installed or upgraded, pacman runs the script after the transaction and reapplies the change.

Installation

With both files prepared, the installation is just:

sudo install -Dm755 kde-lock-immediate /usr/local/bin/kde-lock-immediate
sudo install -Dm644 kde-lock-immediate.hook /etc/pacman.d/hooks/kde-lock-immediate.hook
sudo /usr/local/bin/kde-lock-immediate

The hook is obviously specific to pacman-based distributions such as Arch and its derivatives. On other distributions, the same patch can be used, but it needs to be reapplied after plasma-workspace updates using whatever package-manager mechanism is available.

Testing

You can lock the current session with:

$ loginctl lock-session

The lock screen should now show the authentication UI immediately instead of waiting for a key press or mouse movement.

More importantly, the fingerprint reader is already active.

The workflow is now exactly what I wanted:

close the lid → open the lid → put a finger on the sensor → unlocked

No keyboard interaction required.

A couple of caveats

The normal lock screen fade-out is still there. After about 10 seconds of inactivity, the authentication UI hides again and the screen returns to the wallpaper-and-clock state.

This doesn’t stop fingerprint authentication, though. The authentication session has already been started, so the fingerprint reader continues to work even while the UI is hidden.

There is also a theoretical race condition: if a fingerprint is recognized before PAM has displayed a prompt, the lock screen can end up showing its NoPasswordUnlock state with an “Unlock” button instead of unlocking immediately. In practice, I haven’t been able to reproduce this. PAM starts quickly enough, while fingerprint scanning takes noticeably longer.

Finally, this patch is tied to the current structure of LockScreenUi.qml. If KDE changes Component.onCompleted, renames launchAnimation, or restructures this part of the lock screen, the script will stop with an error. That’s intentional — I’d rather have the update tell me that the patch needs attention than silently leave me with a broken or unapplied modification.

And this only concerns the session lock screen. SDDM is a separate process with its own QML, so this change doesn’t affect the login screen.