Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow monitor choice #24

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/qubes-video-companion.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ The project emphasizes correctness and security all the while also sporting supe

OPTIONS
=======
resolution
The video resolution to stream and receive video in. The format is [WIDTHxHEIGHTxFPS], meaning resolution is optional. If you set the environment variable "QVC_MONITOR" in the target, that monitor is going to be preferred and if not found, will fallback to the primary monitor. Example: "1920x1080x60"


video_source
The video source to stream and receive video from. Either "webcam" or "screenshare".

Expand Down
26 changes: 24 additions & 2 deletions qubes-rpc/services/qvc.ScreenShare
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,30 @@
# Copyright (C) 2021 Elliot Killick <[email protected]>
# Copyright (C) 2021 Demi Marie Obenour <[email protected]>
# Licensed under the MIT License. See LICENSE file for details.

set -eu

## DISPLAY variable used by: xrandr, zenity
export DISPLAY=:0

true "${XDG_RUNTIME_DIR:="/run/user/$(id -u)"}"
true "${DBUS_SESSION_BUS_ADDRESS:="unix:path=${XDG_RUNTIME_DIR}/bus"}"
export DISPLAY=:0 XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS
true "${DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"}"
monitors="$(xrandr --listactivemonitors \
| awk '/^ [0-9]+: \+/ { print "FALSE", $4, $3 }')"
monitor_count="$(echo "${monitors}" | wc -l)"
monitor_longest_line="$(echo "${monitors}" | wc -L)"
dialog_height="$((monitor_count*50+60))"
dialog_width="$((monitor_longest_line*10))"
if test "${monitor_count}" -gt 1; then
# shellcheck disable=SC2086
QVC_MONITOR="$(zenity --list --radiolist \
--height="${dialog_height}" --width="${dialog_width}" \
--column "ID" --column "Name" --column "Resolution" \
--title "Screen share" \
--text "Select monitor to present to qube ${QREXEC_REMOTE_DOMAIN}" \
${monitors})"
fi
true "${QVC_MONITOR:=}"

export XDG_RUNTIME_DIR DBUS_SESSION_BUS_ADDRESS QVC_MONITOR
exec python3 -- /usr/share/qubes-video-companion/sender/screenshare.py
13 changes: 7 additions & 6 deletions receiver/qubes-video-companion
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ unset GETOPT_COMPATIBLE
name=${0##*/}

usage() {
printf '%s: Usage: qubes-video-companion [--resolution=WIDTHxHEIGHTxFPS] [--] webcam|screenshare [destination qube]\n' "$name"
echo "Usage: $name [--resolution=[WIDTHxHEIGHTxFPS]] [--] webcam|screenshare [destination qube]" >&2
echo "Resolution example: 1920x1080x60"
exit "$1"
}

Expand All @@ -23,14 +24,14 @@ while :; do
case $1 in
-r|--resolution)
if [[ -z "$2" ]]; then
printf '%s: Empty resolution argument\n' "$name"
usage 0
fi >&2
echo "$name: Empty resolution argument" >&2
usage 1
fi
resolution=${2//@/+}
resolution=${resolution//x/+}
shift 2
;;
--help) usage 0;;
-h|--help) usage 0;;
--) shift; break;;
*) exit 1;; # cannot happen
esac
Expand Down Expand Up @@ -71,7 +72,7 @@ if ! [ -f "$qvc_lock_file" ]; then
trap exit_clean EXIT
sudo touch "$qvc_lock_file"
else
echo "Qubes Video Companion is already running! Please stop the previous session before starting a new one." >&2
echo "Qubes Video Companion is already running! Please stop the previous session before starting a new one. If you think this is an error, remove the lockfile $qvc_lock_file" >&2
exit 1
fi

Expand Down
22 changes: 16 additions & 6 deletions sender/screenshare.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# pylint: disable=wrong-import-position

import gi
import os

gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
Expand All @@ -30,15 +31,24 @@ def icon(self) -> str:
return "video-display"

def parameters(self) -> Tuple[int, int, int]:
monitor = Gdk.Display().get_default().get_monitor(0).get_geometry()
display = Gdk.Display().get_default()
monitor_count = display.get_n_monitors()
monitor_wanted = os.environ["QVC_MONITOR"]
## If wanted monitor is not found, use the primary monitor (0).
monitor_index = 0
for m in range(monitor_count):
if display.get_monitor(m).get_model() == monitor_wanted:
monitor_index = m
break
geometry = display.get_monitor(monitor_index).get_geometry()
screen = Gdk.Screen().get_default()
kwargs = {
"crop_t": monitor.y,
"crop_l": monitor.x,
"crop_r": screen.width() - monitor.x - monitor.width,
"crop_b": screen.height() - monitor.y - monitor.height,
"crop_t": geometry.y,
"crop_l": geometry.x,
"crop_r": screen.width() - geometry.x - geometry.width,
"crop_b": screen.height() - geometry.y - geometry.height,
}
return (monitor.width, monitor.height, 30, kwargs)
return (geometry.width, geometry.height, 30, kwargs)

def pipeline(self, width: int, height: int, fps: int,
**kwargs) -> List[str]:
Expand Down