Skip to content

fix: disable GPU compositing for XRDP/VNC sessions + nightly update scripts#320

Open
davidamacey wants to merge 2 commits intoaaddrick:mainfrom
davidamacey:feature/xrdp-gpu-fix-and-update-scripts
Open

fix: disable GPU compositing for XRDP/VNC sessions + nightly update scripts#320
davidamacey wants to merge 2 commits intoaaddrick:mainfrom
davidamacey:feature/xrdp-gpu-fix-and-update-scripts

Conversation

@davidamacey
Copy link
Copy Markdown

Summary

Fixes #319

Two changes in this PR:

1. XRDP / VNC GPU fix

When Claude Desktop runs inside an XRDP or VNC session, Electron's GPU compositor fails — the window either renders blank or crashes at startup. This adds detection in scripts/launcher-common.sh to disable GPU compositing for those sessions:

# Detect remote desktop sessions that lack GPU acceleration (XRDP, VNC)
if [[ -n "${XRDP_SESSION:-}" ]] || pgrep -x xrdp-sesman &>/dev/null; then
    electron_args+=('--disable-gpu' '--disable-software-rasterizer')
    log_message 'Remote desktop detected (XRDP) - GPU compositing disabled'
fi

Detection uses two signals (either is sufficient):

  • $XRDP_SESSION — set by the XRDP X server
  • xrdp-sesman process probe — catches VNC-via-xrdp and sessions where the env var isn't propagated

2. Nightly auto-update scripts

Three optional helper scripts for keeping Claude Desktop and Claude Code CLI up to date automatically:

Script Purpose
scripts/nightly-update.sh Cron orchestrator — runs both updaters, logs results
scripts/auto-update-desktop.sh Checks version, builds .deb, installs via apt
scripts/auto-update-claude-code.sh Runs claude update, skips if sessions active

Key design points:

  • All paths resolved from script location — no hardcoded absolute paths
  • --dry-run flag: show what would happen without changes
  • --force flag: bypass safety checks (running-process detection)
  • Logs to $HOME/.local/log/claude-updates/
  • NVM sourced automatically for cron's minimal PATH
  • Optional ntfy notifications (silently skipped if no server reachable) — configure via NTFY_URL / NTFY_TOPIC

Suggested cron:

7 3 * * * /path/to/claude-desktop-debian/scripts/nightly-update.sh

Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
95% AI / 5% Human
Claude: authored both changes, generalized paths, wrote issue + PR
Human: identified the XRDP problem and requested the PR

davidamacey and others added 2 commits March 20, 2026 17:43
Electron's GPU-accelerated compositing crashes or renders a blank window
when Claude Desktop is launched inside an XRDP or VNC remote-desktop
session, because those sessions expose a software-only framebuffer with
no GPU acceleration.

Detect such sessions by checking $XRDP_SESSION (set by the XRDP X server)
or by probing for a running xrdp-sesman process (covers VNC via xrdp and
cases where the env var is not propagated). When detected, add:
  --disable-gpu --disable-software-rasterizer

This falls back to Chromium's CPU compositor path, which renders
correctly in remote-desktop sessions.

Fixes #ISSUE_NUM

Co-Authored-By: Claude <claude@anthropic.com>
… Claude Code

Adds three scripts to keep Claude Desktop and the Claude Code CLI up to
date automatically, suitable for running via cron or on-demand.

scripts/nightly-update.sh
  Orchestrator that runs both sub-scripts in sequence, logs results, and
  sends an optional ntfy push notification on success or failure.
  Suggested cron: 7 3 * * * .../scripts/nightly-update.sh

scripts/auto-update-desktop.sh
  Compares the installed claude-desktop version against the latest in
  origin/main:build.sh. When a newer version is available it pulls
  main, builds the .deb, and installs via sudo apt install.
  Safety: skips if Claude Desktop or bwrap/cowork agents are running.

scripts/auto-update-claude-code.sh
  Runs `claude update` to update the Claude Code CLI.
  Safety: skips if active Claude Code sessions are detected.

Both sub-scripts support --force (skip safety checks) and --dry-run
(show what would happen without making changes).

All paths are resolved automatically from the script's location —
no hardcoded absolute paths. Logs are written to
$HOME/.local/log/claude-updates/. NVM is sourced automatically for
cron's minimal PATH environment.

ntfy notifications are optional and silently skipped if no server is
reachable. Configure via NTFY_URL and NTFY_TOPIC environment variables.

Co-Authored-By: Claude <claude@anthropic.com>
Copy link
Copy Markdown
Owner

@aaddrick aaddrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey! Thanks for putting this together, @davidamacey. The XRDP fix addresses a real usability gap for remote desktop users, and the auto-update scripts show solid defensive design with dry-run, force flags, and graceful ntfy handling. Good stuff overall.

Before diving in, I want to flag a scope concern. This PR bundles two unrelated features: a 6-line launcher fix and ~550 lines of new update automation. The commit history already separates them cleanly. I'd recommend splitting this into two PRs — the XRDP fix is small and merge-ready with one tweak, while the update scripts need a larger revision pass.


`scripts/launcher-common.sh`

Issue 1: `pgrep -x xrdp-sesman` false-positives on local sessions

The `xrdp-sesman` process is a system service. It runs whenever xrdp is installed, even when the current user is sitting at a local desktop. This will incorrectly disable GPU compositing for local sessions on any machine that has xrdp available.

The `$XRDP_SESSION` environment variable is session-scoped and sufficient on its own. Process scanning doesn't add reliable signal here.

Recommendation:

```bash

Detect remote desktop sessions that lack GPU acceleration

if [[ -n "${XRDP_SESSION:-}" ]]; then
electron_args+=('--disable-gpu' '--disable-software-rasterizer')
log_message 'XRDP session detected - GPU compositing disabled'
fi
```

If you want broader VNC coverage, check for VNC-specific env vars like `$VNCDESKTOP` rather than process probing.


`scripts/auto-update-desktop.sh`

Issue 2: Sudoers recommendation is overly permissive

The comment suggests `NOPASSWD: /usr/bin/apt install *` which allows passwordless root installation of any package, not just claude-desktop. A compromised user account could install arbitrary `.deb` files with pre/post-install scripts running as root. Restrict to the specific package path.

Issue 3: `is_cowork_active()` matches all bubblewrap processes

`bwrap` is used by Flatpak, Firejail, and other sandboxing tools. On any system running Flatpak apps, this will almost always return true, preventing updates even when Claude isn't involved. Should match `cowork-vm-service\.js` specifically.

Issue 4: `tee` pipeline masks git exit status

`if ! git ... | tee -a "$log_file"` tests `tee`'s exit status, not `git`'s. `tee` almost never fails, so git failures go undetected.

Issue 5: `git checkout main` in a working repo is surprising for cron

An unattended cron job silently switching branches could discard context or build from the wrong state. Consider using `git worktree` or building directly from the fetched remote ref without modifying the working tree.

Issue 6: `repo_dir` resolution doesn't guard against `cd` failure


`scripts/auto-update-claude-code.sh`

Issue 7: `is_claude_code_active()` uses fragile exclusion-based matching

Matches everything with "claude" in the cmdline, then tries to exclude known false positives. Should match what you want (e.g., `@anthropic-ai/claude-code`) rather than excluding what you don't.


All three new scripts

Issue 8: `log()`, `notify()`, and `parse_args()` are copy-pasted three times — extract shared helpers into `scripts/update-common.sh`, following the existing `launcher-common.sh` pattern.

Issue 9: `> /dev/null 2>&1` instead of `&>/dev/null` — inconsistent with codebase convention.

Issue 10: Double quotes used where single quotes suffice per STYLEGUIDE.md.


Summary

The XRDP detection fix (Issue 1) is close — narrowing to the env var check only would make it solid. I'd recommend splitting that out as its own PR.

The update scripts need more work before they're ready:

  1. Security: Tighten the sudoers recommendation (Issue 2)
  2. Correctness: Fix `bwrap` false positives (Issue 3), `tee` masking (Issue 4), and Claude Code detection (Issue 7)
  3. Safety: Rethink `git checkout` in a working repo (Issue 5)
  4. Maintainability: Extract duplicated helpers (Issue 8)
  5. Style: Minor quoting and redirection form fixes (Issues 9-10)

The defensive design choices (dry-run, force, graceful ntfy fallback) are well thought out. These are solid foundations that will be even better after addressing the issues above.


Written by Claude Opus 4.6 via Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Claude Desktop blank/crashed window when launched via XRDP or VNC

2 participants