mirror of
https://github.com/aaddrick/claude-desktop-debian.git
synced 2026-05-17 00:26:21 +03:00
XRDP sessions lack GPU acceleration; Electron's default GPU compositing renders a blank window. Detect XRDP via the $XRDP_SESSION env var and systemd-logind's session Type, then append --disable-gpu and --disable-software-rasterizer to the Electron args. Based on @davidamacey's fix in #320, with the detection hardened: we use `loginctl show-session -p Type --value` instead of probing for xrdp-sesman, because that daemon runs on any host with xrdp installed and would false-positive on local sessions. Adds tests/launcher-xrdp-detection.bats with 8 cases covering both positive and negative detection paths, including the XDG_SESSION_ID- unset and loginctl-nonzero edge cases. Fixes: #319 Co-authored-by: davidamacey <davidamacey@gmail.com> Co-authored-by: Claude <claude@anthropic.com>
211 lines
6.0 KiB
Bash
211 lines
6.0 KiB
Bash
#!/usr/bin/env bats
|
|
#
|
|
# launcher-xrdp-detection.bats
|
|
# Tests for the XRDP detection block in build_electron_args
|
|
# (scripts/launcher-common.sh). Remote XRDP sessions must disable GPU
|
|
# compositing or the Electron window renders blank (issue #319).
|
|
#
|
|
# The block detects XRDP via two independent signals:
|
|
# 1. XRDP_SESSION env var (set by xrdp's session init)
|
|
# 2. `loginctl show-session $XDG_SESSION_ID -p Type --value` == xrdp
|
|
#
|
|
# These tests mock loginctl with a PATH shim and inspect the
|
|
# electron_args array plus the log file after calling
|
|
# build_electron_args.
|
|
#
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BATS_TEST_FILENAME}")" && pwd)"
|
|
LAUNCHER_COMMON="${SCRIPT_DIR}/../scripts/launcher-common.sh"
|
|
|
|
setup() {
|
|
# Isolated temp dir for PATH shim + log file
|
|
TEST_TMP=$(mktemp -d)
|
|
export TEST_TMP
|
|
|
|
# Mock loginctl via PATH prepend. MOCK_LOGINCTL_TYPE controls
|
|
# the stdout value; MOCK_LOGINCTL_EXIT controls the exit code.
|
|
# Both are read from env at invocation time so each @test can
|
|
# set them independently.
|
|
mkdir -p "$TEST_TMP/bin"
|
|
cat > "$TEST_TMP/bin/loginctl" <<'SHIM'
|
|
#!/usr/bin/env bash
|
|
# Test shim for loginctl. Honours MOCK_LOGINCTL_TYPE and
|
|
# MOCK_LOGINCTL_EXIT from the environment.
|
|
if [[ -n ${MOCK_LOGINCTL_TRACE:-} ]]; then
|
|
printf 'loginctl %s\n' "$*" >> "$MOCK_LOGINCTL_TRACE"
|
|
fi
|
|
if [[ ${MOCK_LOGINCTL_EXIT:-0} -ne 0 ]]; then
|
|
exit "$MOCK_LOGINCTL_EXIT"
|
|
fi
|
|
printf '%s\n' "${MOCK_LOGINCTL_TYPE:-}"
|
|
SHIM
|
|
chmod +x "$TEST_TMP/bin/loginctl"
|
|
export PATH="$TEST_TMP/bin:$PATH"
|
|
|
|
# log_message() appends to $log_file — point at /dev/null by
|
|
# default, override in individual tests that need to inspect it.
|
|
log_file="$TEST_TMP/launcher.log"
|
|
: > "$log_file"
|
|
|
|
# Scrub any XRDP/session env inherited from the outer shell so
|
|
# tests start from a known baseline.
|
|
unset XRDP_SESSION
|
|
unset XDG_SESSION_ID
|
|
unset MOCK_LOGINCTL_TYPE
|
|
unset MOCK_LOGINCTL_EXIT
|
|
unset MOCK_LOGINCTL_TRACE
|
|
|
|
# shellcheck disable=SC1090
|
|
source "$LAUNCHER_COMMON"
|
|
|
|
# build_electron_args reads is_wayland / use_x11_on_wayland.
|
|
# The XRDP block runs before they matter, but they must be set
|
|
# to avoid unbound-variable errors on the later branches.
|
|
is_wayland=false
|
|
use_x11_on_wayland=true
|
|
}
|
|
|
|
teardown() {
|
|
if [[ -n ${TEST_TMP:-} && -d $TEST_TMP ]]; then
|
|
rm -rf "$TEST_TMP"
|
|
fi
|
|
}
|
|
|
|
# Helper: true if electron_args contains the given flag.
|
|
args_contain() {
|
|
local needle="$1"
|
|
local arg
|
|
for arg in "${electron_args[@]}"; do
|
|
[[ $arg == "$needle" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Helper: count occurrences of flag in electron_args.
|
|
args_count() {
|
|
local needle="$1"
|
|
local arg count=0
|
|
for arg in "${electron_args[@]}"; do
|
|
[[ $arg == "$needle" ]] && ((count++))
|
|
done
|
|
printf '%d' "$count"
|
|
}
|
|
|
|
# =============================================================================
|
|
# XRDP detected — flags must be added
|
|
# =============================================================================
|
|
|
|
@test "xrdp: XRDP_SESSION set, loginctl reports x11 — flags added" {
|
|
export XRDP_SESSION=1
|
|
export XDG_SESSION_ID=5
|
|
export MOCK_LOGINCTL_TYPE=x11
|
|
|
|
build_electron_args deb
|
|
|
|
args_contain '--disable-gpu'
|
|
args_contain '--disable-software-rasterizer'
|
|
grep -q 'XRDP session detected' "$log_file"
|
|
}
|
|
|
|
@test "xrdp: XRDP_SESSION unset, loginctl reports xrdp — flags added" {
|
|
export XDG_SESSION_ID=7
|
|
export MOCK_LOGINCTL_TYPE=xrdp
|
|
|
|
build_electron_args deb
|
|
|
|
args_contain '--disable-gpu'
|
|
args_contain '--disable-software-rasterizer'
|
|
grep -q 'XRDP session detected' "$log_file"
|
|
}
|
|
|
|
@test "xrdp: both signals fire — flags added exactly once (no dup)" {
|
|
export XRDP_SESSION=1
|
|
export XDG_SESSION_ID=9
|
|
export MOCK_LOGINCTL_TYPE=xrdp
|
|
|
|
build_electron_args deb
|
|
|
|
[[ "$(args_count '--disable-gpu')" -eq 1 ]]
|
|
[[ "$(args_count '--disable-software-rasterizer')" -eq 1 ]]
|
|
[[ "$(grep -c 'XRDP session detected' "$log_file")" -eq 1 ]]
|
|
}
|
|
|
|
# =============================================================================
|
|
# Local session — flags must NOT be added
|
|
# =============================================================================
|
|
|
|
@test "local: XRDP_SESSION unset, loginctl reports x11 — flags NOT added" {
|
|
export XDG_SESSION_ID=3
|
|
export MOCK_LOGINCTL_TYPE=x11
|
|
|
|
build_electron_args deb
|
|
|
|
run args_contain '--disable-gpu'
|
|
[[ "$status" -ne 0 ]]
|
|
run args_contain '--disable-software-rasterizer'
|
|
[[ "$status" -ne 0 ]]
|
|
run grep -q 'XRDP session detected' "$log_file"
|
|
[[ "$status" -ne 0 ]]
|
|
}
|
|
|
|
@test "local: XRDP_SESSION unset, loginctl reports wayland — flags NOT added" {
|
|
export XDG_SESSION_ID=3
|
|
export MOCK_LOGINCTL_TYPE=wayland
|
|
|
|
build_electron_args deb
|
|
|
|
run args_contain '--disable-gpu'
|
|
[[ "$status" -ne 0 ]]
|
|
run args_contain '--disable-software-rasterizer'
|
|
[[ "$status" -ne 0 ]]
|
|
}
|
|
|
|
@test "local: loginctl exits nonzero — flags NOT added (graceful)" {
|
|
export XDG_SESSION_ID=3
|
|
export MOCK_LOGINCTL_EXIT=1
|
|
|
|
# When loginctl fails, the command substitution's nonzero exit
|
|
# propagates up the `&&` chain; bats' errexit-in-tests would
|
|
# abort if we called build_electron_args directly. In real
|
|
# launchers (no set -e) this is harmless; absorb the status
|
|
# explicitly so this test verifies behaviour, not strict-mode
|
|
# policy.
|
|
build_electron_args deb || true
|
|
|
|
run args_contain '--disable-gpu'
|
|
[[ "$status" -ne 0 ]]
|
|
run args_contain '--disable-software-rasterizer'
|
|
[[ "$status" -ne 0 ]]
|
|
}
|
|
|
|
@test "local: XDG_SESSION_ID unset — loginctl not invoked, flags NOT added" {
|
|
export MOCK_LOGINCTL_TRACE="$TEST_TMP/loginctl-trace.log"
|
|
: > "$MOCK_LOGINCTL_TRACE"
|
|
|
|
build_electron_args deb
|
|
|
|
# loginctl shim must never have been invoked
|
|
[[ ! -s "$MOCK_LOGINCTL_TRACE" ]]
|
|
|
|
run args_contain '--disable-gpu'
|
|
[[ "$status" -ne 0 ]]
|
|
run args_contain '--disable-software-rasterizer'
|
|
[[ "$status" -ne 0 ]]
|
|
}
|
|
|
|
@test "local: XRDP_SESSION empty string — flags NOT added" {
|
|
# Documents that [[ -n ${XRDP_SESSION:-} ]] is false for an
|
|
# exported-but-empty var. If this test ever fails, the semantics
|
|
# of the guard changed.
|
|
export XRDP_SESSION=''
|
|
export XDG_SESSION_ID=3
|
|
export MOCK_LOGINCTL_TYPE=x11
|
|
|
|
build_electron_args deb
|
|
|
|
run args_contain '--disable-gpu'
|
|
[[ "$status" -ne 0 ]]
|
|
run args_contain '--disable-software-rasterizer'
|
|
[[ "$status" -ne 0 ]]
|
|
}
|