feat(desktop): Print-key screenshots via grim/slurp

Bare Print grabs the whole screen to a timestamped PNG under
~/Pictures/Screenshots; $mod selects a region (slurp), SHIFT sends to the
clipboard instead. A mako toast confirms each capture. Adds grim/slurp and
enables xdg.userDirs for the Pictures target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 14:09:51 +02:00
parent 46cebeb8fd
commit 5172ca4d18
+43
View File
@@ -25,6 +25,31 @@ let
| ${pkgs.pinentry-qt}/bin/pinentry-qt \ | ${pkgs.pinentry-qt}/bin/pinentry-qt \
| sed -n 's/^D //p' | sed -n 's/^D //p'
''; '';
# Screenshot helper for the Print-key binds below. Two axes, chosen by args:
# scope ($1 = full | region, the latter an interactive slurp selection) and
# destination ($2 = file | clip). Files are timestamped PNGs under
# ~/Pictures/Screenshots; clip copies to the Wayland clipboard. A mako toast
# confirms each grab. slurp exits non-zero on Escape, which aborts here.
screenshot = pkgs.writeShellScript "screenshot" ''
set -eu
if [ "$1" = region ]; then
geom=$(${pkgs.slurp}/bin/slurp) || exit 1
grab() { ${pkgs.grim}/bin/grim -g "$geom" "$@"; }
else
grab() { ${pkgs.grim}/bin/grim "$@"; }
fi
if [ "$2" = clip ]; then
grab - | ${pkgs.wl-clipboard}/bin/wl-copy
${pkgs.libnotify}/bin/notify-send "Screenshot" "Copied to clipboard"
else
dir="${config.xdg.userDirs.pictures}/Screenshots"
mkdir -p "$dir"
file="$dir/$(date +%Y-%m-%d-%H%M%S).png"
grab "$file"
${pkgs.libnotify}/bin/notify-send "Screenshot" "Saved $file"
fi
'';
in in
{ {
imports = [ ./gpg.nix ./media.nix ]; imports = [ ./gpg.nix ./media.nix ];
@@ -75,8 +100,20 @@ in
nodejs nodejs
highlight # `ccat` alias: syntax-highlighted cat highlight # `ccat` alias: syntax-highlighted cat
libreoffice libreoffice
grim # screenshot capture (also used by the Print-key binds)
slurp # interactive region selector for grim
]; ];
# Canonical XDG user dirs. Only Pictures is actually used (screenshot target,
# file-picker default). createDirectories stays off so the rest aren't
# littered into $HOME — they're merely declared in ~/.config/user-dirs.dirs,
# created lazily by whatever app wants them.
xdg.userDirs = {
enable = true;
createDirectories = false;
pictures = "${config.home.homeDirectory}/Pictures";
};
# ---- Per-tool config files, routed into XDG dirs --------------------- # ---- Per-tool config files, routed into XDG dirs ---------------------
xdg.configFile = { xdg.configFile = {
"python/startup".source = ./assets/python-startup.py; "python/startup".source = ./assets/python-startup.py;
@@ -374,6 +411,12 @@ in
", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%+" ", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%+"
", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%-" ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 3%-"
# Screenshots. $mod = pick a region (slurp), SHIFT = to clipboard;
# bare Print grabs the whole screen to a file (the common case).
", Print, exec, ${screenshot} full file"
"$mod, Print, exec, ${screenshot} region file"
"SHIFT, Print, exec, ${screenshot} full clip"
"$mod SHIFT, Print, exec, ${screenshot} region clip"
]; ];
exec-once = [ exec-once = [