Open gaming screenshots in annotated Loupe
This commit is contained in:
parent
af785503d6
commit
35959ae819
5 changed files with 63 additions and 6 deletions
21
flake.lock
generated
21
flake.lock
generated
|
|
@ -193,6 +193,26 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"loupe": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1789759456,
|
||||
"narHash": "sha256-pV2iKbCp4F7ux4E3usYHi/KzC08/fxiDa64cL4DdJfc=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "f65d5548de5aa77cc14870d5e7a5f24a972d957a",
|
||||
"revCount": 1671,
|
||||
"type": "git",
|
||||
"url": "https://forg.gregersen.it/lazzexus/Loupe"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://forg.gregersen.it/lazzexus/Loupe"
|
||||
}
|
||||
},
|
||||
"nix-cachyos-kernel": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat",
|
||||
|
|
@ -371,6 +391,7 @@
|
|||
"root": {
|
||||
"inputs": {
|
||||
"home-manager": "home-manager",
|
||||
"loupe": "loupe",
|
||||
"nix-cachyos-kernel": "nix-cachyos-kernel",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"proton-cachyos-nix": "proton-cachyos-nix",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
proton-cachyos-nix.url = "github:powerofthe69/proton-cachyos-nix";
|
||||
|
||||
loupe = {
|
||||
url = "git+https://forg.gregersen.it/lazzexus/Loupe";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# Source only, not this flake's outputs: nixpkgs' redlib predates the wreq
|
||||
# switch and Reddit 403s its rustls TLS fingerprint (see services/redlib.nix).
|
||||
redlib = {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
protonplus
|
||||
unrar
|
||||
p7zip
|
||||
inputs.loupe.packages.${pkgs.stdenv.hostPlatform.system}.default
|
||||
];
|
||||
|
||||
# Nova Pro Wireless base station: open up its vendor HID interface so
|
||||
|
|
|
|||
|
|
@ -79,6 +79,23 @@ in
|
|||
# land in unrelated hues from the ink the shell frame is drawn in.
|
||||
ink4 = ui.mixHex c.base05 c.base00 ui.inkMuted;
|
||||
ink3 = ui.mixHex c.base05 c.base00 ui.inkFaint;
|
||||
screenshotWithLoupe = pkgs.writeShellScript "screenshot-with-loupe" ''
|
||||
set -eu
|
||||
dir="''${XDG_RUNTIME_DIR:?}/loupe-screenshots"
|
||||
${pkgs.coreutils}/bin/mkdir -m 700 -p "$dir"
|
||||
name="$(${pkgs.coreutils}/bin/date +%Y%m%d-%H%M%S-%N).png"
|
||||
${pkgs.hyprshot}/bin/hyprshot -m "$1" -o "$dir" -f "$name" --silent
|
||||
[ -s "$dir/$name" ] || exit 0
|
||||
|
||||
# Quickshell retains at most 30 notifications. Keep the same number of
|
||||
# screenshots so notification clicks work without filling runtime tmpfs.
|
||||
${pkgs.findutils}/bin/find "$dir" -maxdepth 1 -type f -name '*.png' -printf '%f\n' \
|
||||
| ${pkgs.coreutils}/bin/sort \
|
||||
| ${pkgs.coreutils}/bin/head -n -30 \
|
||||
| while IFS= read -r old; do ${pkgs.coreutils}/bin/rm -- "$dir/$old"; done
|
||||
${pkgs.libnotify}/bin/notify-send -a Hyprshot -i "$dir/$name" \
|
||||
'Screenshot copied' 'Click to annotate in Loupe. Saved temporarily until logout.'
|
||||
'';
|
||||
in {
|
||||
# Stylix's Hyprland target injects settings.{general,decoration,group,misc}
|
||||
# as top-level keys, which render as hl.general()/hl.decoration()/… in Lua
|
||||
|
|
@ -506,11 +523,15 @@ in
|
|||
-- Screenshots — Shift+Super+S matches GNOME binding
|
||||
-- Pin/unpin quickshell's focus grab around the region select so an
|
||||
-- open menu survives slurp's input grab (no-ops if qs isn't up).
|
||||
-- --clipboard-only: nothing hits the disk, so there is no folder to
|
||||
-- fill and no file for the notification to thumbnail. The bar draws
|
||||
-- a camera glyph instead of holding a decoded screen-sized texture.
|
||||
${if isMacbook then ''
|
||||
hl.bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd("sh -c 'qs ipc call screenshot pin; hyprshot -m region --clipboard-only; qs ipc call screenshot unpin'"))
|
||||
hl.bind("Print", hl.dsp.exec_cmd("hyprshot -m output --clipboard-only"))
|
||||
'' else ''
|
||||
-- On gaming, save temporary PNGs so the notification can reopen
|
||||
-- the exact screenshot in Loupe, while hyprshot still copies it.
|
||||
hl.bind(mod .. " + SHIFT + S", hl.dsp.exec_cmd("sh -c 'qs ipc call screenshot pin; ${screenshotWithLoupe} region; qs ipc call screenshot unpin'"))
|
||||
hl.bind("Print", hl.dsp.exec_cmd("${screenshotWithLoupe} output"))
|
||||
''}
|
||||
|
||||
-- Settings shortcut — Super+I matches GNOME binding
|
||||
hl.bind(mod .. " + I", hl.dsp.exec_cmd("pavucontrol"))
|
||||
|
|
|
|||
|
|
@ -887,6 +887,7 @@ in
|
|||
readonly property string xdgOpen: "${pkgs.xdg-utils}/bin/xdg-open"
|
||||
readonly property string screenRec: "${screenRecScript}"
|
||||
readonly property string slurpRegion: "${slurpRegionScript}"
|
||||
readonly property string loupe: "${if isMacbook then "" else "${inputs.loupe.packages.${pkgs.stdenv.hostPlatform.system}.default}/bin/loupe"}"
|
||||
readonly property string themeApply: "${themeApply}"
|
||||
}
|
||||
'';
|
||||
|
|
@ -3418,6 +3419,7 @@ in
|
|||
// file-path appIcon (e.g. album art on disk). "" = none.
|
||||
function notifPreviewSource(notif) {
|
||||
if (!notif) return "";
|
||||
if (notif.appName === "Hyprshot") return "";
|
||||
if (notif.image && notif.image !== "") return notif.image;
|
||||
let a = notif.appIcon || "";
|
||||
if (a.startsWith("file://")) return a;
|
||||
|
|
@ -3426,9 +3428,8 @@ in
|
|||
}
|
||||
|
||||
// Glyph to fill the preview slot when there is no image to put
|
||||
// there. Screenshots run --clipboard-only, so nothing is written
|
||||
// to disk and there is no thumbnail to load — which is the point:
|
||||
// a decoded 3440x1440 texture cost ~19MB per retained shot.
|
||||
// there. Gaming screenshots stay on disk for opening in Loupe;
|
||||
// avoid holding full-screen preview textures in the bar.
|
||||
function notifPreviewIcon(notif) {
|
||||
if (!notif) return "";
|
||||
return notif.appName === "Hyprshot" ? "camera" : "";
|
||||
|
|
@ -3459,6 +3460,14 @@ 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")) {
|
||||
Quickshell.execDetached([Commands.loupe, path]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (const a of notif.actions)
|
||||
if (a.identifier === "default") { a.invoke(); break; }
|
||||
focusNotifApp(notif);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue