Open screenshot notifications in Loupe

This commit is contained in:
rope 2026-09-19 09:38:53 +01:00
parent 6ee092433c
commit 7f18d154cd

View file

@ -1636,16 +1636,14 @@ in
}
SText {
width: parent.width
text: _nc.notif ? (_nc.notif.body || "") : ""
text: bar.isHyprshotNotification(_nc.notif)
? "Click to annotate in Loupe."
: (_nc.notif ? (_nc.notif.body || "") : "")
color: Theme.base04
font.pixelSize: _nc.bodySize
elide: Text.ElideRight
maximumLineCount: _nc.bodyLines
wrapMode: Text.Wrap
// hyprshot's body used to be a noisy save path and was
// hidden. Under --clipboard-only it reads "Image copied
// to the clipboard", which is the only thing correcting
// its own "Screenshot saved" summary — nothing is saved.
visible: text !== ""
}
Row {
@ -3415,11 +3413,39 @@ in
}
}
function isHyprshotNotification(notif) {
return notif && (notif.appName || "").toLowerCase() === "hyprshot";
}
// Hyprshot supplies the saved PNG as an icon and repeats it in
// the body. Quickshell may expose that icon as a themed image
// URL rather than the original path, so keep the body fallback.
function screenshotPath(notif) {
if (!isHyprshotNotification(notif)) return "";
const marker = "/loupe-screenshots/";
const candidates = [notif.appIcon || "", notif.image || ""];
for (let path of candidates) {
if (path.startsWith("file://"))
path = decodeURIComponent(path.substring(7));
if (path.startsWith("/") && path.includes(marker) && path.endsWith(".png"))
return path;
}
const body = notif.body || "";
const markerAt = body.indexOf(marker);
const endAt = body.indexOf(".png", markerAt);
if (markerAt < 0 || endAt < 0) return "";
const tagAt = body.lastIndexOf("<i>", markerAt);
const startAt = tagAt >= 0 ? tagAt + 3 : body.lastIndexOf(" ", markerAt) + 1;
const path = body.substring(startAt, endAt + 4);
return path.startsWith("/") ? path : "";
}
// Preview image for a notification: its image hint, else a
// file-path appIcon (e.g. album art on disk). "" = none.
function notifPreviewSource(notif) {
if (!notif) return "";
if (notif.appName === "Hyprshot") return "";
if (isHyprshotNotification(notif)) return "";
if (notif.image && notif.image !== "") return notif.image;
let a = notif.appIcon || "";
if (a.startsWith("file://")) return a;
@ -3432,7 +3458,7 @@ in
// avoid holding full-screen preview textures in the bar.
function notifPreviewIcon(notif) {
if (!notif) return "";
return notif.appName === "Hyprshot" ? "camera" : "";
return isHyprshotNotification(notif) ? "camera" : "";
}
// Jump to the window that sent a notification. Toplevel.activate()
// goes over wlr-foreign-toplevel — the same path a taskbar uses —
@ -3460,10 +3486,9 @@ in
// behind the default action, so fire that too when they send one.
function activateNotif(notif) {
if (!notif) return;
if (notif.appName === "Hyprshot" && Commands.loupe !== "") {
let path = notif.appIcon || "";
if (path.startsWith("file://")) path = decodeURIComponent(path.substring(7));
if (path.startsWith("/") && path.includes("/loupe-screenshots/") && path.endsWith(".png")) {
if (isHyprshotNotification(notif) && Commands.loupe !== "") {
const path = screenshotPath(notif);
if (path !== "") {
Quickshell.execDetached([Commands.loupe, path]);
return;
}