Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
Notification popup shows placeholder icon for Ghostty-forwarded notifications (missing desktop-entry hint fallback)
Reported by hexploder · filed Sep 24, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- AreaOutside the audited area· Decided by agents · verified
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Decided by agents and verified by a second, independent agent — see the decision.
Original report
What happened
Desktop notifications forwarded through Ghostty (e.g. from Claude Code running in a terminal, or any other app that sends terminal-bell/OSC-style notifications) always show a generic placeholder icon in the Omarchy Quickshell notification popup, instead of Ghostty's own icon.
What I expected
The notification popup to show Ghostty's app icon, the same way it appears for the app in com.mitchellh.ghostty.desktop (Icon=com.mitchellh.ghostty), which is correctly installed under /usr/share/icons/hicolor/*/apps/com.mitchellh.ghostty.png.
Root cause
Captured the actual org.freedesktop.Notifications.Notify D-Bus call with dbus-monitor while Claude Code sent a notification from inside Ghostty:
method call ... member=Notify
string "" # app_icon (empty)
uint32 0
string ""
string "Claude Code" # app_name
string "Screenshot test for the Omarchy bug report — placeholder icon"
array [ string "default" string "" ]
array [
dict entry( string "desktop-entry" variant string "com.mitchellh.ghostty" )
dict entry( string "urgency" variant byte 1 )
dict entry( string "image-path" variant string "com.mitchellh.ghostty" )
]
int32 -1Ghostty leaves app_icon empty and instead identifies itself via the desktop-entry hint (com.mitchellh.ghostty), with image-path also set to that same string (an icon-theme name, not a URI).
In shell/plugins/notifications/components/NotificationCard.qml:
readonly property string smallIconSource: image.length > 0 ? image : iconSource(appIcon)This only ever looks at the Quickshell Notification.image and Notification.appIcon properties. It never reads Notification.desktopEntry. Since:
appIconis literally""here,iconSource(appIcon)→Quickshell.iconPath("", true)resolves to nothing.imagecomes from theimage-pathhint, which per the freedesktop spec may be either a URI or a themed icon name — here it's a bare icon-theme name (com.mitchellh.ghostty), not a URI, so it isn't usable directly as anImage.sourceand doesn't get resolved throughQuickshell.iconPath.
Both paths come back empty/unusable, so the card falls back to the generic placeholder glyph — even though the icon Ghostty is pointing at (com.mitchellh.ghostty, via either hint) is installed and resolves fine through Quickshell.iconPath("com.mitchellh.ghostty", true).
This isn't Claude-specific — any notification forwarded through Ghostty hits the same path, since Ghostty always sends this same empty-app_icon + desktop-entry/image-path-hint shape.
Suggested fix
In NotificationCard.qml (or wherever image/appIcon are resolved before reaching the card), add a fallback chain that also tries desktopEntry, and treats image/image-path as a themed icon name (via Quickshell.iconPath) when it isn't a URI, e.g. roughly:
readonly property string smallIconSource:
image.length > 0 ? image
: appIcon.length > 0 ? iconSource(appIcon)
: desktopEntry.length > 0 ? iconSource(desktopEntry)
: ""(with image itself also going through iconSource()/Quickshell.iconPath() when it isn't already a resolvable URL).
Steps to reproduce
- On Omarchy with Ghostty as the terminal, run any program that sends a terminal notification (e.g. Claude Code finishing a task, or
notify-sendisn't needed — Ghostty's own OSC-triggered D-Bus notification is enough). - Watch the Quickshell notification popup.
- Instead of Ghostty's icon, a generic placeholder glyph is shown.
System details
- Omarchy: 4.0.4-1
- Quickshell: 0.3.1-1
- Ghostty: 1.3.1-arch2
- Hyprland: 0.56.2
- Kernel: 7.2.5-3-omarchy-bore
Screenshot
Notification popup showing the placeholder icon (top right)
<img width="599" height="171" alt="Image" src="https://github.com/user-attachments/assets/05d58971-90db-4dfe-875a-959d2ff5e856" />
View raw text
### What happened
Desktop notifications forwarded through Ghostty (e.g. from Claude Code running in a terminal, or any other app that sends terminal-bell/OSC-style notifications) always show a generic placeholder icon in the Omarchy Quickshell notification popup, instead of Ghostty's own icon.
### What I expected
The notification popup to show Ghostty's app icon, the same way it appears for the app in `com.mitchellh.ghostty.desktop` (`Icon=com.mitchellh.ghostty`), which is correctly installed under `/usr/share/icons/hicolor/*/apps/com.mitchellh.ghostty.png`.
### Root cause
Captured the actual `org.freedesktop.Notifications.Notify` D-Bus call with `dbus-monitor` while Claude Code sent a notification from inside Ghostty:
```
method call ... member=Notify
string "" # app_icon (empty)
uint32 0
string ""
string "Claude Code" # app_name
string "Screenshot test for the Omarchy bug report — placeholder icon"
array [ string "default" string "" ]
array [
dict entry( string "desktop-entry" variant string "com.mitchellh.ghostty" )
dict entry( string "urgency" variant byte 1 )
dict entry( string "image-path" variant string "com.mitchellh.ghostty" )
]
int32 -1
```
Ghostty leaves `app_icon` empty and instead identifies itself via the `desktop-entry` hint (`com.mitchellh.ghostty`), with `image-path` also set to that same string (an icon-theme *name*, not a URI).
In `shell/plugins/notifications/components/NotificationCard.qml`:
```qml
readonly property string smallIconSource: image.length > 0 ? image : iconSource(appIcon)
```
This only ever looks at the Quickshell `Notification.image` and `Notification.appIcon` properties. It never reads `Notification.desktopEntry`. Since:
- `appIcon` is literally `""` here, `iconSource(appIcon)` → `Quickshell.iconPath("", true)` resolves to nothing.
- `image` comes from the `image-path` hint, which per the freedesktop spec may be either a URI *or* a themed icon name — here it's a bare icon-theme name (`com.mitchellh.ghostty`), not a URI, so it isn't usable directly as an `Image.source` and doesn't get resolved through `Quickshell.iconPath`.
Both paths come back empty/unusable, so the card falls back to the generic placeholder glyph — even though the icon Ghostty is pointing at (`com.mitchellh.ghostty`, via either hint) is installed and resolves fine through `Quickshell.iconPath("com.mitchellh.ghostty", true)`.
This isn't Claude-specific — any notification forwarded through Ghostty hits the same path, since Ghostty always sends this same empty-`app_icon` + `desktop-entry`/`image-path`-hint shape.
### Suggested fix
In `NotificationCard.qml` (or wherever `image`/`appIcon` are resolved before reaching the card), add a fallback chain that also tries `desktopEntry`, and treats `image`/`image-path` as a themed icon name (via `Quickshell.iconPath`) when it isn't a URI, e.g. roughly:
```qml
readonly property string smallIconSource:
image.length > 0 ? image
: appIcon.length > 0 ? iconSource(appIcon)
: desktopEntry.length > 0 ? iconSource(desktopEntry)
: ""
```
(with `image` itself also going through `iconSource()`/`Quickshell.iconPath()` when it isn't already a resolvable URL).
### Steps to reproduce
1. On Omarchy with Ghostty as the terminal, run any program that sends a terminal notification (e.g. Claude Code finishing a task, or `notify-send` isn't needed — Ghostty's own OSC-triggered D-Bus notification is enough).
2. Watch the Quickshell notification popup.
3. Instead of Ghostty's icon, a generic placeholder glyph is shown.
### System details
- Omarchy: 4.0.4-1
- Quickshell: 0.3.1-1
- Ghostty: 1.3.1-arch2
- Hyprland: 0.56.2
- Kernel: 7.2.5-3-omarchy-bore
### Screenshot
Notification popup showing the placeholder icon (top right)
<img width="599" height="171" alt="Image" src="https://github.com/user-attachments/assets/05d58971-90db-4dfe-875a-959d2ff5e856" />
- 05d58971-90db-4dfe-875a-959d2ff5e856
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
Not linked to any known issue, other report or change yet.
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Out of scopeDecided by agents · verified · 2026-10-09 19:40 UTC