claude-desktop/nix/default.nix
Eddy 3913e1cce8
All checks were successful
Build AppImage / build (push) Has been skipped
fix: HiDPI-Scaling im Nix-Launcher — liest Xft.dpi, erzwingt Xwayland
GTK3 kann unter Wayland kein natives fractional Scaling. Der Launcher
liest jetzt Xft.dpi aus xrdb, setzt GDK_DPI_SCALE entsprechend (fuer
scharfe Fonts) und erzwingt unter Wayland GDK_BACKEND=x11, damit der
Compositor die Fenstergroesse skaliert. Override per CLAUDE_DESKTOP_SCALE
oder abschaltbar mit CLAUDE_DESKTOP_SCALE=off.

Funktioniert transparent auf X11-VM und KDE-Wayland-Desktop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 17:10:56 +02:00

158 lines
5.5 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Claude Desktop — Nix-Wrapper-Paket
#
# Liefert:
# $out/bin/claude-desktop — Launcher mit LD_LIBRARY_PATH
# $out/bin/claude-desktop-install — Installer (kopiert Binary nach ~/.local/share)
# $out/share/applications/… — Desktop-Entry
# $out/share/icons/… — Icon
#
# Das eigentliche Binary lebt unter ~/.local/share/claude-desktop/bin/claude-desktop
# (writable), damit der Auto-Updater es ersetzen kann. Nix-Store ist read-only und
# waere deshalb inkompatibel mit dem Rename-Trick in apply_update().
#
# Einbinden in /etc/nixos/configuration.nix:
#
# environment.systemPackages = [
# (import /pfad/zum/claude-desktop/nix/default.nix { inherit pkgs; })
# ];
#
# Oder per home-manager:
# home.packages = [ (import ./claude-desktop/nix/default.nix { inherit pkgs; }) ];
{ pkgs ? import <nixpkgs> {} }:
let
# Alle Laufzeit-Libs, die das Tauri-Binary braucht (parallel zu shell.nix).
runtimeLibs = with pkgs; [
webkitgtk_4_1
libappindicator-gtk3
librsvg
gtk3
glib
cairo
pango
gdk-pixbuf
libsoup_3
at-spi2-atk
openssl
];
# Laufzeit-Binaries die die App spawnen muss (node fuer claude-bridge.js,
# npm fuer apply_bundle_update, tar fuer Bundle-Extract)
runtimeBins = [ pkgs.nodejs_22 pkgs.gnutar pkgs.gzip ];
in
pkgs.stdenv.mkDerivation {
pname = "claude-desktop";
version = "0.1.0";
# Keine Quelldateien — Wir packen nur Wrapper + Desktop-Entry
dontUnpack = true;
nativeBuildInputs = [ pkgs.makeWrapper ];
installPhase = ''
runHook preInstall
mkdir -p $out/bin $out/share/applications $out/share/icons/hicolor/256x256/apps
# 1) Launcher: startet das User-Binary mit Nix-LD_LIBRARY_PATH
cat > $out/bin/claude-desktop <<'LAUNCHER'
#!${pkgs.bash}/bin/bash
# Claude Desktop NixOS-Launcher
set -e
APP_DIR="$HOME/.local/share/claude-desktop"
BIN="$APP_DIR/bin/claude-desktop"
if [ ! -x "$BIN" ]; then
echo " Claude-Desktop-Binary nicht gefunden: $BIN" >&2
echo "" >&2
echo "Erst installieren (aus fertigem Build in /tmp/claude-target):" >&2
echo " claude-desktop-install" >&2
echo "" >&2
echo "Oder neu bauen im Repo:" >&2
echo " CARGO_TARGET_DIR=/tmp/claude-target \\" >&2
echo " nix-shell shell.nix --run 'npm ci && npm run tauri build'" >&2
echo " claude-desktop-install" >&2
exit 1
fi
# Marker fuer update.rs: wir laufen unter Nix-Wrapper
export CLAUDE_DESKTOP_NIX_WRAPPER=1
export CLAUDE_DESKTOP_BIN="$BIN"
# HiDPI/Fractional-Scaling GTK3 unter Wayland kann kein natives fractional
# scaling. Workaround: Xwayland erzwingen (der Compositor skaliert das Fenster)
# und GDK_DPI_SCALE aus Xft.dpi ableiten, damit Fonts scharf bleiben.
# Override-bar ueber CLAUDE_DESKTOP_SCALE (z.B. "1.5") oder komplett
# deaktivierbar mit CLAUDE_DESKTOP_SCALE=off.
if [ "''${CLAUDE_DESKTOP_SCALE:-}" != "off" ]; then
SCALE="''${CLAUDE_DESKTOP_SCALE:-}"
if [ -z "$SCALE" ] && command -v xrdb >/dev/null 2>&1 && [ -n "''${DISPLAY:-}" ]; then
DPI="$(xrdb -query 2>/dev/null | awk -F':\\s*' '/^Xft.dpi:/ {print $2; exit}')"
if [ -n "$DPI" ] && [ "$DPI" -gt 96 ] 2>/dev/null; then
# bash-only float-Division: auf 2 Stellen runden
SCALE="$(awk -v d="$DPI" 'BEGIN { printf "%.2f", d/96 }')"
fi
fi
if [ -n "$SCALE" ] && [ "$SCALE" != "1.00" ] && [ "$SCALE" != "1.0" ]; then
export GDK_DPI_SCALE="$SCALE"
# Unter Wayland: Xwayland nutzen, damit der Compositor-Scale greift
if [ "''${XDG_SESSION_TYPE:-}" = "wayland" ]; then
export GDK_BACKEND="''${GDK_BACKEND:-x11}"
fi
fi
fi
exec "$BIN" "$@"
LAUNCHER
chmod +x $out/bin/claude-desktop
# LD_LIBRARY_PATH + PATH dauerhaft ans Launcher-Script binden
# PATH: node/npm/tar muessen fuer die Bridge und apply_bundle_update verfuegbar sein
wrapProgram $out/bin/claude-desktop \
--prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath runtimeLibs} \
--prefix PATH : ${pkgs.lib.makeBinPath runtimeBins}
# 2) Installer: kopiert ein frisch gebautes Binary an den Ziel-Ort
cat > $out/bin/claude-desktop-install <<'INSTALLER'
#!${pkgs.bash}/bin/bash
set -e
SRC="''${1:-/tmp/claude-target/release/claude-desktop}"
DEST_DIR="$HOME/.local/share/claude-desktop/bin"
DEST="$DEST_DIR/claude-desktop"
if [ ! -x "$SRC" ]; then
echo " Quelle nicht gefunden oder nicht ausfuehrbar: $SRC" >&2
echo "" >&2
echo "Erst bauen:" >&2
echo " cd <repo>; CARGO_TARGET_DIR=/tmp/claude-target \\" >&2
echo " nix-shell shell.nix --run 'npm ci && npm run tauri build'" >&2
exit 1
fi
mkdir -p "$DEST_DIR"
cp "$SRC" "$DEST"
chmod +x "$DEST"
echo " Claude Desktop installiert nach $DEST"
echo " Starten mit: claude-desktop (oder aus KDE-Menue)"
INSTALLER
chmod +x $out/bin/claude-desktop-install
# 3) Desktop-Entry
cp ${./claude-desktop.desktop} $out/share/applications/claude-desktop.desktop
# 4) Icon
cp ${../src-tauri/icons/icon.png} $out/share/icons/hicolor/256x256/apps/claude-desktop.png
runHook postInstall
'';
meta = with pkgs.lib; {
description = "Native Desktop-App fuer Claude Code (Wrapper-Paket, Binary in ~/.local/share)";
homepage = "https://git.data-it-solution.de/data/claude-desktop";
license = licenses.mit;
platforms = platforms.linux;
mainProgram = "claude-desktop";
};
}