← All solutions
Caelestia Shell · Launcher

Launcher suggestions
rendering ghost items

Typing a prefix command in the Caelestia Shell launcher (e.g. >d, >wa, >scheme) causes suggestion entries to visually stack on top of each other - text rendered over text, creating a ghost/shadow effect that makes the list unreadable.

Caelestia Shell Quickshell / QML AppList.qml
Symptom

Open the launcher (Super + Space) and type a prefix like >d or >wa. The suggestions list appears, but the items are rendered on top of each other - multiple labels occupy the same vertical position, making every item unreadable.

The issue is intermittent: it consistently happens when switching between the apps and actions states (i.e., typing and deleting the > prefix).

Root Cause

The AppList.qml component uses a ListView with a dynamically switched delegate property - it switches between appItem and actionItem depending on the current state (apps vs actions).

When the state changes mid-animation, QML's ListView does not correctly destroy the old delegate instances before swapping to the new ones. Stale "zombie" delegates remain visible with incorrect y positions, overlapping the freshly created items. The PropertyAction block that re-triggers root.add and root.remove at the end of the transition compounds the issue by triggering a second re-layout over already broken positions.

What actually fixes it

The fix is to keep the original upstream version of AppList.qml without any modifications to the states/transitions block. The overlapping is an intrinsic Qt Quick interaction with this specific Caelestia version - it has no clean patch without risking regressions in the normal app-search flow.

If the file gets modified by a future update or by an attempted fix, revert it to the upstream version.

bash - check the file is in its original state
grep -A5 'states:' ~/.config/quickshell/caelestia/modules/launcher/AppList.qml
# The 'apps' State should contain: root.delegate: appItem
# If it's been changed, restore from the upstream caelestia repo
Common trap - what does NOT work

The "obvious" fix attempt is to wrap the ListView delegate in a static wrapper component with an internal Loader, avoiding the dynamic delegate switch. This completely breaks the launcher.

Caelestia Shell uses pragma ComponentBehavior: Bound, which restricts access to modelData outside the delegate's original lexical scope. A Loader-based wrapper cannot reach modelData, so all items render blank - only broken image icons appear, no text whatsoever. Do not attempt this approach.