โ† All solutions
Caelestia Shell ยท Lock Screen

Lock screen notification
text overlapping

On the Caelestia Shell lock screen, notification entries render their text on top of each other - multiple notification labels occupy the same space, making them completely unreadable. Triggered by a QML Repeater delegate recycling bug combined with parallel layout animations in NotifGroup.qml.

Caelestia Shell Quickshell / QML NotifGroup.qml
Symptom

When the screen is locked and notifications arrive, the notification list on the lock screen shows the text of all entries rendered in the same spot - one on top of the other. The result looks like corrupted text or a typographic ghost effect. Clearing or dismissing notifications can make it worse.

Root Cause

The NotifGroup.qml component uses a Repeater inside a ColumnLayout to render each notification. Each delegate had parallel animations that animated Layout.preferredHeight on entry and exit:

  • Problem 1 - Delegate recycling: When a new notification arrives or an existing one is dismissed, QML's Repeater reuses existing delegate instances rather than destroying and recreating them. The model data bound to the delegate changes, but the in-flight animations were still animating Layout.preferredHeight using the old item's dimensions - leaving items stuck at the wrong height.
  • Problem 2 - Closed notifications staying visible: The notifs property included notifications where notif.closed === true. These "ghost" entries remained in the layout, occupying space and contributing to the overlap.

Together, these caused the ColumnLayout to position items at heights calculated from stale animation state, causing multiple items to share the same vertical position.

Fix - NotifGroup.qml

Two changes in ~/.config/quickshell/caelestia/modules/lock/NotifGroup.qml:

Filter out closed notifications at the data level

Modify the notifs property to exclude entries where notif.closed is true. This prevents ghost entries from entering the Repeater model at all.

qml - before / after
// Before - includes closed notifications
property var notifs: Notifs.list.values

// After - filters them out
property var notifs: Notifs.list.values.filter(notif => !notif.closed)

Remove the parallel layout animations from the Repeater delegate

Delete the ParallelAnimation blocks that animate Layout.preferredHeight on entry and on notif.modelData.closed. Let the ColumnLayout manage item height natively using the implicit height of the Text elements - QML handles this correctly without manual animation.

After removing the animations, notifications on the lock screen render cleanly, stack in order, and never overlap - even when multiple arrive or are dismissed rapidly.
Caelestia Shell updates may overwrite NotifGroup.qml and reintroduce the animations. After running paru -Syu, verify the lock screen notifications still display correctly by locking the screen (Super+L) and sending a test notification: notify-send "Test" "Overlap check".