diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..5f27d5e --- /dev/null +++ b/examples/README.md @@ -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. diff --git a/examples/single-output-sway b/examples/single-output-sway new file mode 100755 index 0000000..60d8915 --- /dev/null +++ b/examples/single-output-sway @@ -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) +