Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-117GitHub issuePublicDecided· Out of scope

Notification popup shows placeholder icon for Ghostty-forwarded notifications (missing desktop-entry hint fallback)

Reported by hexploder · filed Sep 24, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

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

Notification popup shows placeholder icon for Ghostty-forwarded notifications (missing desktop-entry hint fallback)revision 1 · captured 2026-09-28 21:23 UTC via poll

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:

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:

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" />

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