Add single-output-sway helper script

For sway 1.7, this disables all but one output on connect, then restores
everything on disconnect.

For sway 1.8 and later, creates a virtual HEADLESS output, disables all
others, then restores everything on disconnect.

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
pull/207/head
Jim Ramsay 2022-12-14 16:29:03 -05:00
parent 2f2f6f410b
commit 72cc04098d
2 changed files with 125 additions and 0 deletions

26
examples/README.md 100644
View File

@ -0,0 +1,26 @@
# Example Scripts
The scripts here are examples of how you can automate interesting things with the wayvncctl IPC events.
## event-watcher
This is a pretty simple example that just demonstrates how to tie the
`wayvncctl event-receive` event loop into a bash script. It logs when clients
connect and disconnect.
## single-output-sway
This is more purposeful, and implements an idea for multi-output wayland
servers, collapsing all outputs down to one when the first client connects, and
restoring the configuration when the last client exits.
The mechanism used to collapse the outputs depends on the version of sway installed:
- For sway-1.7 and earlier, the script just temporarily disables all outputs
except the one being captured. This moves all workspaces to the single
remaining output.
- For sway-1.8 and later, the script creates a temporary virtual output called
`HEADLESS-[0-9]+' and then disables all physical outputs, which moves all
workspaces to the virtual output. On disconnect, all original physical
outputs are re-enabled, and the virtual output is destroyed.

View File

@ -0,0 +1,99 @@
#!/bin/bash
WAYVNCCTL=${WAYVNCCTL:-wayvncctl}
SWAYMSG=${SWAYMSG:-swaymsg}
SWAY_HAS_UNPLUG=false
IFS=" .-" read -r _ _ SWAYMAJOR SWAYMINOR _ < <($SWAYMSG -v)
if [[ $SWAYMAJOR -ge 1 && $SWAYMINOR -ge 8 ]]; then
echo "Detected sway version 1.8 or later: Enabling virtual output device mode"
SWAY_HAS_UNPLUG=true
else
echo "Detected sway version 1.7 or earlier: Not enabling virtual output device mode"
fi
find_output_matching() {
local pattern=$1
$WAYVNCCTL -j get-outputs | jq -r ".[].name | match(\"$pattern\").string"
}
wait_for_output_matching() {
local pattern=$1
local output
output=$(find_output_matching "$pattern")
while [[ -z $output ]]; do
sleep 0.5
output=$(find_output_matching "$pattern")
done
echo "$output"
}
OUTPUTS_TO_RECONNECT=()
HEADLESS=
restore_outputs() {
[[ ${#OUTPUTS_TO_RECONNECT[@]} -ge 1 ]] || return
echo "Restoring original output state"
for output in "${OUTPUTS_TO_RECONNECT[@]}"; do
echo "Re-enabling output $output"
$SWAYMSG output "$output" enable
done
if [[ $SWAY_HAS_UNPLUG == true && $HEADLESS ]]; then
local firstOutput=${OUTPUTS_TO_RECONNECT[0]}
echo "Switching wayvnc back to physical output $firstOutput"
wait_for_output_matching "$firstOutput" >/dev/null
$WAYVNCCTL set-output --switch-to="$firstOutput"
echo "Removing virtual output $HEADLESS"
$SWAYMSG output "$HEADLESS" unplug
fi
OUTPUTS_TO_RECONNECT=()
HEADLESS=
}
trap restore_outputs EXIT
collapse_outputs() {
if [[ $SWAY_HAS_UNPLUG == true ]]; then
local preexisting="$(find_output_matching 'HEADLESS-\\d+')"
if [[ $preexisting ]]; then
echo "Switching to preexisting virtual output $preexisting"
$WAYVNCCTL set-output --switch-to="$preexisting"
else
echo "Creating a virtual display"
$SWAYMSG create_output
echo "Waiting for virtusl output to be created..."
HEADLESS=$(wait_for_output_matching 'HEADLESS-\\d+')
echo "Switching to virtual output $HEADLESS"
$WAYVNCCTL set-output --switch-to="$HEADLESS"
fi
fi
for output in $($WAYVNCCTL -j get-outputs | jq -r '.[] | select(.captured==false).name'); do
echo "Disabling extra output $output"
$SWAYMSG output "$output" disable
OUTPUTS_TO_RECONNECT+=("$output")
done
}
connection_count_now() {
local count=$1
if [[ $count == 1 ]]; then
collapse_outputs
elif [[ $count == 0 ]]; then
restore_outputs
fi
}
while IFS= read -r EVT; do
case "$(jq -r '.method' <<<"$EVT")" in
client-*onnected)
count=$(jq -r '.params.connection_count' <<<"$EVT")
connection_count_now "$count"
;;
wayvnc-shutdown)
echo "wayvncctl is no longer running"
connection_count_now 0
;;
wayvnc-startup)
echo "Ready to receive wayvnc events"
;;
esac
done < <("$WAYVNCCTL" --wait --reconnect --json event-receive)