diff --git a/bin/omarchy-notification-send b/bin/omarchy-notification-send index 6b1a36e4..751ef075 100755 --- a/bin/omarchy-notification-send +++ b/bin/omarchy-notification-send @@ -68,11 +68,12 @@ done # Tag as a user-action toast so it pops through DND. See dnd-fix-plan.md. args+=("-a" "omarchy-action" "-u" "$urgency") -# Glyph is now a custom hint the quickshell daemon renders into the icon -# slot, not prepended to the summary. Old mako-era formatting was glyph + 4 -# spaces + headline, which leaves ugly whitespace in the new card design. +# Send the glyph both as a custom hint and in a summary prefix. +# Quickshell strips the prefix back into the icon slot; other notification +# daemons still get the familiar glyph + spacing presentation. if [[ -n $glyph ]]; then args+=("--hint=string:omarchy-glyph:$glyph") + headline="$glyph $headline" fi if [[ -n $description ]]; then diff --git a/default/quickshell/omarchy-shell/plugins/notifications/Service.qml b/default/quickshell/omarchy-shell/plugins/notifications/Service.qml index 70a005dd..2f81ff7d 100644 --- a/default/quickshell/omarchy-shell/plugins/notifications/Service.qml +++ b/default/quickshell/omarchy-shell/plugins/notifications/Service.qml @@ -67,6 +67,7 @@ Item { onFileChanged: reload() } + // Fired by IPC (`omarchy-shell-ipc notifications showHistory`) so the // bar widget can drop its PopupCard from the same anchor a click would. signal historyOpenRequested() @@ -142,16 +143,20 @@ Item { function snapshotOf(notification) { var glyph = "" try { - if (notification.hints && typeof notification.hints["omarchy-glyph"] === "string") { - glyph = notification.hints["omarchy-glyph"] + if (notification.hints) { + var hintGlyph = notification.hints["omarchy-glyph"] + if (hintGlyph !== undefined && hintGlyph !== null) + glyph = String(hintGlyph) } } catch (e) { glyph = "" } + var summary = String(notification.summary || "") + return { id: notification.id, originalId: notification.id, app: notification.appName || "", appIcon: notification.appIcon || "", - summary: notification.summary || "", + summary: summary, body: notification.body || "", image: notification.image || "", glyph: glyph, diff --git a/default/quickshell/omarchy-shell/plugins/notifications/components/NotificationCard.qml b/default/quickshell/omarchy-shell/plugins/notifications/components/NotificationCard.qml index 88f1dd33..f4e43ceb 100644 --- a/default/quickshell/omarchy-shell/plugins/notifications/components/NotificationCard.qml +++ b/default/quickshell/omarchy-shell/plugins/notifications/components/NotificationCard.qml @@ -54,12 +54,8 @@ Rectangle { lower.endsWith(".jpeg") || lower.endsWith(".webp") || lower.endsWith(".gif") } - readonly property string mediaImageSource: { - if (_isMediaFile(_imageFilePath(image))) return image - if (_isMediaFile(_imageFilePath(appIcon))) return appIcon - return "" - } - readonly property bool mediaMode: mediaImageSource.length > 0 + readonly property string mediaImageSource: "" + readonly property bool mediaMode: false // Use only what the notification explicitly carries — no themed-icon // theme-lookup fallback because Quickshell's icon image provider returns // a placeholder for missing names (rather than erroring), which means @@ -68,7 +64,8 @@ Rectangle { // `appIcon` (-i flag) still get one. readonly property string smallIconSource: image.length > 0 ? image : appIcon readonly property bool hasGlyph: glyph.length > 0 - readonly property bool hasSmallIcon: !mediaMode && (smallIconSource.length > 0 || hasGlyph) + readonly property bool inlineGlyph: summary.match(/^\S\s{2,}/) !== null + readonly property bool hasSmallIcon: !mediaMode && !inlineGlyph && (smallIconSource.length > 0 || hasGlyph) readonly property color dimColor: Qt.darker(Color.notifications.text, 1.4) readonly property color bodyColor: Qt.darker(Color.notifications.text, 1.15) @@ -157,24 +154,24 @@ Rectangle { Layout.rightMargin: 12 Layout.topMargin: 10 Layout.bottomMargin: 10 - spacing: 10 + spacing: 12 Item { id: smallIconSlot - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 + Layout.preferredWidth: 40 + Layout.preferredHeight: 40 Layout.alignment: Qt.AlignVCenter // Hide the slot when the icon failed to resolve (themed-icon name // not in the user's icon theme) AND we don't have a glyph fallback // — prevents rendering Qt's pink broken-image placeholder. - visible: false + visible: root.hasGlyph || (!root.mediaMode && smallIconSource.length > 0 && smallIconImage.status !== Image.Error) Image { id: smallIconImage anchors.fill: parent source: root.smallIconSource - sourceSize.width: 32 * Screen.devicePixelRatio - sourceSize.height: 32 * Screen.devicePixelRatio + sourceSize.width: 40 * Screen.devicePixelRatio + sourceSize.height: 40 * Screen.devicePixelRatio fillMode: Image.PreserveAspectFit asynchronous: true smooth: true @@ -219,7 +216,7 @@ Rectangle { textFormat: Text.StyledText font.family: root.fontFamily color: root.bodyColor - font.pixelSize: 12 + font.pixelSize: 13 wrapMode: Text.WordWrap elide: Text.ElideRight maximumLineCount: 3