Screenshare: grim preview from picker, ~70ms instead of ~1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4a6fb7f5b2
commit
d3ce8f66fc
2 changed files with 115 additions and 25 deletions
|
|
@ -117,28 +117,90 @@ in
|
|||
# or HDT. Gaming's patched Vesktop writes the time to xdph-pick-manually
|
||||
# right before asking the portal ("Pick Another Window", shift-click)
|
||||
# to get the normal picker instead.
|
||||
#
|
||||
# After answering, it grim-shots the selection to xdph-preview.jpg for
|
||||
# Vesktop's dialog (~70ms vs Electron's ~1s PipeWire thumbnail). grim
|
||||
# reads the screen, so a window that isn't visible is skipped and Vesktop
|
||||
# falls back to the thumbnail.
|
||||
xdg.configFile."hypr/xdph.conf".text = ''
|
||||
screencopy {
|
||||
allow_token_by_default = true
|
||||
custom_picker_binary = ${pkgs.writeShellScript "share-picker-game-first" ''
|
||||
flag="''${XDG_RUNTIME_DIR:-/tmp}/xdph-pick-manually"
|
||||
printf -v now '%(%s)T' -1
|
||||
{ forced=$(< "$flag"); } 2>/dev/null # no trailing newline, so not `read`
|
||||
echo 0 > "$flag"
|
||||
custom_picker_binary = ${lib.getExe (pkgs.writeShellApplication {
|
||||
name = "share-picker-game-first";
|
||||
runtimeInputs = with pkgs; [ coreutils gawk jq grim hyprland xdg-desktop-portal-hyprland ];
|
||||
excludeShellChecks = [ "SC2016" ]; # $ in awk/jq programs is meant literally
|
||||
text = ''
|
||||
run=''${XDG_RUNTIME_DIR:-/tmp}
|
||||
flag=$run/xdph-pick-manually
|
||||
preview=$run/xdph-preview.jpg
|
||||
list=''${XDPH_WINDOW_SHARING_LIST-}
|
||||
rm -f "$preview"
|
||||
|
||||
game=$(printf '%s' "''${XDPH_WINDOW_SHARING_LIST-}" | ${pkgs.gawk}/bin/awk '
|
||||
BEGIN { RS = "\\[HA>\\]"; FS = "\\[H[CTE]>\\]" }
|
||||
$2 ~ /^steam_app_/ && $3 == "Hearthstone" { hs = $1 }
|
||||
$2 ~ /^steam_app_/ && $3 != "" && !other \
|
||||
&& $3 !~ /^(Battle\.net|Hearthstone Deck Tracker|HearthstoneOverlay)/ { other = $1 }
|
||||
END { print hs != "" ? hs : other }')
|
||||
printf -v now '%(%s)T' -1
|
||||
{ forced=$(< "$flag"); } 2>/dev/null || forced=0 # no trailing newline, so not `read`
|
||||
echo 0 > "$flag"
|
||||
|
||||
if [ -n "$game" ] && (( now - ''${forced:-0} > 10 )); then
|
||||
echo "[SELECTION]r/window:$game"
|
||||
exit 0
|
||||
fi
|
||||
exec ${pkgs.xdg-desktop-portal-hyprland}/bin/hyprland-share-picker "$@"
|
||||
''}
|
||||
# run awk program $2 over the window list as id/class/title/address
|
||||
# columns, with want=$1
|
||||
entries() {
|
||||
printf '%s' "$list" | awk '
|
||||
BEGIN { RS = "\\[HA>\\]"; FS = "\\[H[CTE]>\\]" }
|
||||
{ print $1 "\t" $2 "\t" $3 "\t" $4 }' | awk -F '\t' -v want="$1" "$2"
|
||||
}
|
||||
game=$(entries "" '
|
||||
$2 ~ /^steam_app_/ && $3 == "Hearthstone" { hs = $1 }
|
||||
$2 ~ /^steam_app_/ && $3 != "" && !other \
|
||||
&& $3 !~ /^(Battle\.net|Hearthstone Deck Tracker|HearthstoneOverlay)/ { other = $1 }
|
||||
END { print hs != "" ? hs : other }')
|
||||
|
||||
if [ -n "$game" ] && (( now - forced > 10 )); then
|
||||
selection=r/window:$game
|
||||
else
|
||||
out=$(hyprland-share-picker "$@") || true
|
||||
selection=''${out#*"[SELECTION]"}
|
||||
if [ "$selection" = "$out" ]; then # closed / failed: pass through
|
||||
printf '%s\n' "$out"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
echo "[SELECTION]$selection"
|
||||
|
||||
shoot() {
|
||||
local target=''${1#*/} where=()
|
||||
case $target in
|
||||
window:*)
|
||||
local id=''${target#window:} addr geom
|
||||
if (( id < 0 )); then id=$(( id + 4294967296 )); fi # the Qt picker prints it signed
|
||||
addr=$(entries "$id" '$1 == want { print $4 }')
|
||||
[ -n "$addr" ] || return 0
|
||||
geom=$(hyprctl -j clients | jq -r --arg a "$(printf '0x%x' "$addr")" \
|
||||
--argjson mons "$(hyprctl -j monitors)" '
|
||||
[$mons[] | .activeWorkspace.id, .specialWorkspace.id] as $shown
|
||||
| .[] | select(.address == $a and (.hidden | not))
|
||||
| select(.workspace.id as $w | any($shown[]; . == $w))
|
||||
| "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"')
|
||||
[ -n "$geom" ] || return 0
|
||||
where=(-g "$geom")
|
||||
;;
|
||||
screen:*)
|
||||
where=(-o "''${target#screen:}")
|
||||
;;
|
||||
region:*)
|
||||
local spec=''${target#region:} x y w h geom
|
||||
IFS=, read -r x y w h <<< "''${spec#*@}"
|
||||
geom=$(hyprctl -j monitors | jq -r --arg o "''${spec%@*}" \
|
||||
--argjson x "$x" --argjson y "$y" --arg wh "''${w}x$h" '
|
||||
.[] | select(.name == $o) | "\(.x + $x),\(.y + $y) \($wh)"')
|
||||
[ -n "$geom" ] || return 0
|
||||
where=(-g "$geom")
|
||||
;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
grim "''${where[@]}" -s 0.5 -t jpeg -q 85 "$preview.tmp" && mv -f "$preview.tmp" "$preview"
|
||||
}
|
||||
shoot "$selection" > /dev/null 2>&1 < /dev/null &
|
||||
'';
|
||||
})}
|
||||
}
|
||||
'';
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue