Files
claude-re-setup/launch-claude.sh
T
LinusandClaude Opus 5.5 16dbf25c9b Share a chosen workspace folder and stop with the window
run.sh asks which host folder Claude may access, using the desktop's
folder picker (zenity, or kdialog on KDE; terminal prompt otherwise),
and mounts it read-write at /workspace. It opens at the last folder
used, refuses / and $HOME, and can be skipped with --workspace DIR.
The image creates /workspace and a ~/workspace symlink to it.

Closing Claude Desktop's window only hides the app, which left the
container running invisibly. The new entrypoint launch-claude.sh
watches the app's X windows and quits it once none is open or
minimized, so the container exits with it. run.sh adds --init for
signal handling and reaping.

Also add .gitignore for workspace/ and .env.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 12:22:38 +01:00

47 lines
1.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Container entrypoint: run Claude Desktop and stop when its window is closed.
#
# Closing the window only hides the app (it keeps running for the tray icon,
# which GNOME doesn't show), so the container would keep running invisibly.
# This watches the app's X windows and quits the app once none of them is
# open or minimized. The container then exits with it.
set -u
claude-desktop "$@" &
app=$!
stop_app() { kill -TERM "$app" 2>/dev/null; wait "$app"; exit $?; }
trap stop_app TERM INT HUP
host="$(hostname)"
# True if any of this container's Claude windows is Normal (shown) or Iconic
# (minimized). A closed window is Withdrawn or loses WM_STATE altogether.
# WM_CLIENT_MACHINE filters out Claude windows from other containers or apps
# on the same X server.
window_open() {
local w props
for w in $(xwininfo -root -tree 2>/dev/null \
| awk '/\("com\.anthropic\.claude" "com\.anthropic\.Claude"\)/ {print $1}'); do
props="$(xprop -id "$w" WM_CLIENT_MACHINE WM_STATE 2>/dev/null)" || continue
[[ "$props" == *"WM_CLIENT_MACHINE(STRING) = \"$host\""* ]] || continue
[[ "$props" =~ "window state: "(Normal|Iconic) ]] && return 0
done
return 1
}
seen=0 # only arm the check after the first window has appeared
misses=0 # require a few consecutive misses to ride out brief remaps
while kill -0 "$app" 2>/dev/null; do
sleep 1 & wait $!
if window_open; then
seen=1 misses=0
elif (( seen )) && (( ++misses >= 3 )); then
echo "launch-claude: window closed, quitting Claude Desktop" >&2
stop_app
fi
done
wait "$app"