Add xwayland-game-wrapper
This commit is contained in:
parent
e291adb39d
commit
2c33cdc65f
127
xwayland-game-wrapper
Executable file
127
xwayland-game-wrapper
Executable file
@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
setopt rcquotes
|
||||
|
||||
# eprintf <format> [args...]
|
||||
function eprintf {
|
||||
printf "${@}" >&2
|
||||
}
|
||||
|
||||
# die <format> [args...]
|
||||
function die {
|
||||
eprintf '\e[91mfatal\e[m: '"${1}\n" "${(@)@:2}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# print_help <argv[0]>
|
||||
function print_help {
|
||||
printf 'usage: %s [OPTIONS...] <GAME> [ARGS...]\n' "${1}"
|
||||
printf 'Run a game inside an Xwayland session with a window manager. This\n'
|
||||
printf 'is very similar to gamescope, except that there is a window\n'
|
||||
printf 'involved. The default window manager is OpenBox.\n'
|
||||
printf '\n'
|
||||
printf ' -h Print this message, then exit.\n'
|
||||
printf ' -w Specify the window manager to use. This argument to this option will be\n'
|
||||
printf ' passed to "sh -c".\n'
|
||||
printf ' -r Specify the resolution of the Xwayland display. This should in the form\n'
|
||||
printf ' of ''WxH''. By default, the resolution of the currently focused output\n'
|
||||
printf ' will be used.\n'
|
||||
printf ' -d Specify the current desktop environment (or standalone Wayland\n'
|
||||
printf ' compositor). This is used if -r is not specified to find the resolution.\n'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# get_current_desktop
|
||||
function get_current_desktop {
|
||||
[[ -z "${XDG_CURRENT_DESKTOP}" ]] &&
|
||||
die 'set $XDG_CURRENT_DESKTOP or pass -d top specify desktop'
|
||||
eprintf 'Detected desktop: "%s"\n' "${XDG_CURRENT_DESKTOP}"
|
||||
printf '%s' "${XDG_CURRENT_DESKTOP}"
|
||||
}
|
||||
|
||||
# get_default_resolution [desktop]
|
||||
function get_default_resolution {
|
||||
case "${1}" in
|
||||
'river')
|
||||
local output="$(ristate -o |
|
||||
jq -r '.outputs | keys.[] as $names |
|
||||
{output: $names, focused: .[$names].focused} |
|
||||
select(.focused) | .output')"
|
||||
eprintf 'Detected output: %s\n' "${output}"
|
||||
local resolution="$(wlr-randr --json |
|
||||
jq -r --arg output "${output}" \
|
||||
'.[] | select(.name == $output).modes.[] |
|
||||
select(.current) | "\(.width)x\(.height)"')"
|
||||
;;
|
||||
*)
|
||||
die 'unknown desktop session: "%s"' "${1}"
|
||||
;;
|
||||
esac
|
||||
eprintf 'Detected resolution: %s\n' "${resolution}"
|
||||
printf '%s\n' "${resolution}"
|
||||
}
|
||||
|
||||
while getopts ':hw:r:d:' OPTOPT; do
|
||||
case "${OPTOPT}" in
|
||||
'h')
|
||||
print_help "${1}"
|
||||
;;
|
||||
'w')
|
||||
window_manager="${OPTARG}"
|
||||
;;
|
||||
'r')
|
||||
resolution="${OPTARG}"
|
||||
;;
|
||||
'd')
|
||||
current_desktop="${OPTARG}"
|
||||
;;
|
||||
':')
|
||||
die 'option requires an argument: %s' "${OPTARG}"
|
||||
;;
|
||||
'?')
|
||||
die 'unknown option: %s' "${OPTARG}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
(( "${OPTIND}" > ${#} )) && print_help
|
||||
shift $(( "${OPTIND}" - 1))
|
||||
|
||||
{
|
||||
set -e
|
||||
[[ -v window_manager ]] ||
|
||||
window_manager='openbox'
|
||||
[[ -v current_desktop ]] ||
|
||||
current_desktop="$(get_current_desktop 2>&3)"
|
||||
[[ -v resolution ]] ||
|
||||
resolution="$(get_default_resolution "${current_desktop}" 2>&3)"
|
||||
} 3>&2
|
||||
|
||||
function on_sigchld {
|
||||
eprintf 'Xwayland or window manager died! Exiting...\n'
|
||||
kill %sh %Xwayland 2>/dev/null
|
||||
wait ${cat_pid}
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap on_sigchld CHLD
|
||||
|
||||
coproc Xwayland -fullscreen -geometry "${resolution}" -displayfd 1
|
||||
local xwayland_display
|
||||
read <&p xwayland_display
|
||||
export DISPLAY=":${xwayland_display}"
|
||||
unset WAYLAND_DISPLAY
|
||||
eprintf 'Xwayland display: %s\n' "${DISPLAY}"
|
||||
|
||||
cat <&p >&2
|
||||
let cat_pid="${!}"
|
||||
|
||||
sh -c "exec -- ${window_manager}" &
|
||||
|
||||
${@}
|
||||
trap -
|
||||
kill %sh %Xwayland
|
||||
|
||||
wait "${cat_pid}"
|
||||
|
||||
eprintf 'Child died! Exiting...\n'
|
Loading…
Reference in New Issue
Block a user