diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41a54fde3..20ca3f419 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,7 @@ jobs: - build-bench - build-linux-libghostty - build-nix + - build-snap - build-macos - build-macos-matrix - build-windows @@ -276,6 +277,32 @@ jobs: nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_harfbuzz nix develop -c zig build --system ${{ steps.deps.outputs.deps }} -Dapp-runtime=glfw -Drenderer=metal -Dfont-backend=coretext_noshape + build-snap: + strategy: + fail-fast: false + matrix: + os: + [namespace-profile-ghostty-snap, namespace-profile-ghostty-snap-arm64] + runs-on: ${{ matrix.os }} + needs: test + env: + ZIG_LOCAL_CACHE_DIR: /zig/local-cache + ZIG_GLOBAL_CACHE_DIR: /zig/global-cache + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - name: Setup Cache + uses: namespacelabs/nscloud-cache-action@v1.2.0 + with: + path: | + /nix + /zig + - run: sudo apt install -y udev + - run: sudo systemctl start systemd-udevd + - uses: snapcore/action-build@v1 + build-windows: runs-on: windows-2022 # this will not stop other jobs from running diff --git a/nix/devShell.nix b/nix/devShell.nix index 7cfef64c2..66f259656 100644 --- a/nix/devShell.nix +++ b/nix/devShell.nix @@ -14,6 +14,7 @@ python3, qemu, scdoc, + snapcraft, valgrind, #, vulkan-loader # unused vttest, @@ -137,6 +138,7 @@ in qemu gdb + snapcraft valgrind wraptest diff --git a/snap/local/launcher b/snap/local/launcher new file mode 100755 index 000000000..11597f238 --- /dev/null +++ b/snap/local/launcher @@ -0,0 +1,52 @@ +#!/bin/sh +set -e + +# Set these to reasonable defaults if not already set +if [ -z "$XDG_CONFIG_HOME" ]; then + export XDG_CONFIG_HOME="$SNAP_REAL_HOME/.config" +fi + +if [ -z "$XDG_CACHE_HOME" ]; then + export XDG_CACHE_HOME="$SNAP_REAL_HOME/.cache" +fi + +if [ -z "$XDG_DATA_HOME" ]; then + export XDG_DATA_HOME="$SNAP_REAL_HOME/.local/share" +fi + +export HOME="$SNAP_REAL_HOME" + +if [ "$SNAP_ARCH" = "amd64" ]; then + ARCH="x86_64-linux-gnu" +elif [ "$SNAP_ARCH" = "arm64" ]; then + ARCH="aarch64-linux-gnu" +else + ARCH="$SNAP_ARCH-linux-gnu" +fi + +export LD_LIBRARY_PATH=${SNAP}/usr/lib/${ARCH}:${SNAP}/usr/lib/${ARCH}/vdpau:${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:} +export LIBGL_DRIVERS_PATH=${LIBGL_DRIVERS_PATH:+$LIBGL_DRIVERS_PATH:}${SNAP}/usr/lib/${ARCH}/dri/ +export LIBVA_DRIVERS_PATH=${LIBVA_DRIVERS_PATH:+$LIBVA_DRIVERS_PATH:}${SNAP}/usr/lib/${ARCH}/dri/ +export __EGL_VENDOR_LIBRARY_DIRS=${__EGL_VENDOR_LIBRARY_DIRS:+$__EGL_VENDOR_LIBRARY_DIRS:}${SNAP}/usr/share/glvnd/egl_vendor.d +export __EGL_EXTERNAL_PLATFORM_CONFIG_DIRS=${__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS:+$__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS:}${SNAP}/usr/share/egl/egl_external_platform.d +export DRIRC_CONFIGDIR=${SNAP}/usr/share/drirc.d +export VK_LAYER_PATH=${VK_LAYER_PATH:+$VK_LAYER_PATH:}${SNAP}/usr/share/vulkan/implicit_layer.d/:${SNAP}/usr/share/vulkan/explicit_layer.d/ +export XDG_DATA_DIRS=${XDG_DATA_DIRS:+$XDG_DATA_DIRS:}${SNAP}/usr/share +export XLOCALEDIR="${SNAP}/usr/share/X11/locale" +export GDK_PIXBUF_MODULE_FILE="$XDG_CACHE_HOME/gdk-pixbuf-loaders.cache" +export GDK_PIXBUF_MODULEDIR="$SNAP/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders" +export GTK_PATH="$SNAP/usr/lib/$ARCH/gtk-4.0" + +if [ "${__NV_PRIME_RENDER_OFFLOAD:-}" != 1 ]; then + # Prevent picking VA-API (Intel/AMD) over NVIDIA VDPAU + # https://download.nvidia.com/XFree86/Linux-x86_64/510.54/README/primerenderoffload.html#configureapplications + export LIBVA_DRIVERS_PATH +fi + +# Unset all SNAP specific environment variables to keep them from leaking +# into other snaps that might get executed from within the shell +for var in $(printenv | grep SNAP_ | cut -d= -f1); do + unset $var +done + +exec "$@" diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 000000000..9ef2f5cc4 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,139 @@ +name: ghostty +base: core24 +summary: A terminal emulator +description: | + Ghostty is a fast, feature-rich, and cross-platform terminal emulator that + uses platform-native UI and GPU acceleration. +grade: stable +confinement: classic +contact: https://github.com/ghostty-org/ghostty/discussions +issues: https://github.com/ghostty-org/ghostty/issues +website: https://ghostty.org +license: MIT +icon: images/icons/icon_512.png +adopt-info: ghostty + +platforms: + amd64: + arm64: + +apps: + ghostty: + command: bin/ghostty + command-chain: [bin/launcher] + completer: share/bash-completion/completions/ghostty.bash + desktop: share/applications/com.mitchellh.ghostty.desktop + #refresh-mode: ignore-running # Store rejects this, needs fix in review-tools + environment: + PATH: /snap/ghostty/current/bin:/snap/ghostty/current/usr/bin:$PATH + LC_ALL: C.UTF-8 + GHOSTTY_RESOURCES_DIR: /snap/ghostty/current/share/ghostty + +parts: + launcher: + plugin: dump + source: snap/local + source-type: local + organize: + launcher: bin/ + + zig: + plugin: nil + build-packages: + - curl + override-pull: | + set -ex + case "$CRAFT_ARCH_BUILD_FOR" in + amd64) arch=x86_64 ;; + arm64) arch=aarch64 ;; + *) arch="" ;; + esac + + rm -rf $CRAFT_PART_SRC/* + + if [[ -n $arch ]]; then + curl -LO --retry-connrefused --retry 10 https://ziglang.org/download/0.13.0/zig-linux-$arch-0.13.0.tar.xz + else + echo "Unsupported arch" + exit 1 + fi + + tar xf zig-lin*xz + rm -f *xz + mv zig-linux*/* . + prime: + - -* + + ghostty: + source: . + after: [zig] + plugin: nil + build-attributes: [enable-patchelf] + build-packages: + - libgtk-4-dev + - libadwaita-1-dev + - git + - patchelf + override-build: | + craftctl set version=$(git describe --abbrev=8) + $CRAFT_PART_SRC/../../zig/src/zig build -Dpatch-rpath=\$ORIGIN/../usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/core24/current/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR -Doptimize=ReleaseFast + cp -rp zig-out/* $CRAFT_PART_INSTALL/ + sed -i 's|Icon=com.mitchellh.ghostty|Icon=/snap/ghostty/current/share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png|g' $CRAFT_PART_INSTALL/share/applications/com.mitchellh.ghostty.desktop + + libs: + plugin: nil + build-attributes: [enable-patchelf] + stage-packages: + - libadwaita-1-0 + - libglib2.0-0t64 + - libgtk-4-1 + - libgtk-4-media-gstreamer + - ibus-gtk4 + - libpciaccess0 + - libtinfo6 + - libedit2 + - libelf1t64 + - libsensors5 + - libllvm17 + - libunistring5 + - librsvg2-2 + - on amd64: + [ + i965-va-driver, + libdrm-intel1, + libdrm-nouveau2, + libdrm-amdgpu1, + libdrm-radeon1, + ] + stage: + # The libraries in dri need no-patchelf, so they come from the mesa-unpatched part + - -usr/lib/*/dri + + mesa: + plugin: nil + build-attributes: [enable-patchelf] + stage-packages: + - libglu1-mesa + - libgl1-mesa-dri + - libegl-mesa0 + - libegl1 + - libglx-mesa0 + - mesa-libgallium + stage: + # The libraries in dri need no-patchelf, so they come from the mesa-unpatched part + - usr/lib/*/*.so* + - usr/lib/*/dri/libdril_dri.so + - -usr/lib/*/libgallium*so + - -usr/lib/*/dri + + mesa-gl1-dri: + plugin: nil + stage-packages: + - libgl1-mesa-dri + build-attributes: [no-patchelf] + stage: + # Only the libraries in dri need to not be patched, the rest come from the mesa part + # Otherwise snapcraft may strip the build ID and cause the driver to crash + - usr/lib/*/libgallium*so + - -usr/lib/*/dri/libdril_dri.so + - usr/lib/*/dri diff --git a/src/apprt/gtk/Surface.zig b/src/apprt/gtk/Surface.zig index 6c39677d5..42c8278a2 100644 --- a/src/apprt/gtk/Surface.zig +++ b/src/apprt/gtk/Surface.zig @@ -2264,6 +2264,23 @@ pub fn defaultTermioEnv(self: *Surface) !std.process.EnvMap { env.remove("GDK_DISABLE"); env.remove("GSK_RENDERER"); + // Unset environment varies set by snaps if we're running in a snap. + // This allows Ghostty to further launch additional snaps. + if (env.get("SNAP")) |_| { + env.remove("SNAP"); + env.remove("DRIRC_CONFIGDIR"); + env.remove("__EGL_EXTERNAL_PLATFORM_CONFIG_DIRS"); + env.remove("__EGL_VENDOR_LIBRARY_DIRS"); + env.remove("LD_LIBRARY_PATH"); + env.remove("LIBGL_DRIVERS_PATH"); + env.remove("LIBVA_DRIVERS_PATH"); + env.remove("VK_LAYER_PATH"); + env.remove("XLOCALEDIR"); + env.remove("GDK_PIXBUF_MODULEDIR"); + env.remove("GDK_PIXBUF_MODULE_FILE"); + env.remove("GTK_PATH"); + } + if (self.container.window()) |window| { // On some window protocols we might want to add specific // environment variables to subprocesses, such as WINDOWID on X11.