Files
psysonic/nixos-install.md
cucadmuh 70c2fdfbf9 Linux: session-native GDK/WebKit mitigations and in-page browse scroll (#731)
* feat(linux): session GDK defaults, nvidia-quirk, optional x11-legacy wrap

Ship PSYSONIC_ALLOW_NATIVE_GDK from Nix/AUR instead of pinning WEBKIT_DISABLE_*
and GDK x11. Add flake psysonic-x11-legacy for the old wrap; alias gdk-session
to psysonic. Startup uses webkit2gtk-nvidia-quirk and Wayland-aware compositing;
refresh Help (a45) and nixos-install docs.

* fix(linux): session GDK and nvidia-quirk only; drop wrapper env heuristics

Remove PSYSONIC_ALLOW_NATIVE_GDK and devShell GDK/WEBKIT exports; stop
synthesizing GDK/WebKit vars in main.rs. Update Nix/AUR wrappers, install
docs, CHANGELOG, and help FAQ with practical user-facing workarounds.

* fix(linux): X11-pinned GDK uses DMABUF quirk path, not Wayland explicit-sync

When GDK_BACKEND is forced to x11 on a wayland user session, webkit2gtk-nvidia-quirk
would still apply __NV_DISABLE_EXPLICIT_SYNC and gray out the webview. Map that case
to WEBKIT_DISABLE_DMABUF_RENDERER like native X11.

* fix(ui): stabilize WebKitGTK/Wayland hover paint for nav and media cards

Sidebar nav links avoid transition:all and promote icons with translateZ(0).
Artist rows and album/artist/song cards use compositing hints; card shadows
and borders no longer interpolate so cover zoom can stay smooth without jitter.

* fix(ui): isolate artist/album card text and cover paint on WebKitGTK

Promote cover blocks with contain/paint and text stacks with translateZ(0);
use artist-card-info on the artists grid for the same layout as other cards.

* feat(artists): in-page overlay scroll and locked main viewport

Move list/grid into an inner OverlayScrollArea, stop sticky toolbar from
owning the route scroll, align the rail with the main panel edge, and skip
the main-route overlay thumb when the viewport cannot scroll vertically.

* feat(browse): extend in-page overlay scroll to more library routes

Reuse the locked main viewport pattern from Artists for Albums, Composers,
Lossless albums, and New releases; wire VirtualCardGrid and scroll chrome
to the matching in-page viewport ids.

* fix(linux): improve Wayland GPU compositing text clarity in WebKitGTK

Use on-demand hardware acceleration on main and mini webviews when the
session is Wayland and compositing stays on; gate subpixel body AA on the
same conditions via new Tauri probes. Document PSYSONIC_SKIP_WAYLAND_FONT_TUNING
for opt-out and changelog.

* fix(rust): satisfy clippy needless_return in Linux webkit helpers

* fix(linux): tune Wayland text rendering with HW policy env and CSS

Allow PSYSONIC_WEBKIT_WAYLAND_HW_POLICY to select WebKit hardware
acceleration policy (never/always vs default on-demand). Extend Wayland
font CSS to #root with geometricPrecision and text-size-adjust on html.

* feat(linux): Wayland text presets in settings, safe WebKit apply, CPU default

Persist profile to app config; apply WebKit policy at startup/mini only to
avoid WebKitGTK hangs on live toggles. UI + CSS preview stays live; default
preset is sharp (CPU-friendly).

* fix(linux): map Wayland sharp preset to OnDemand WebKit policy

HardwareAccelerationPolicy::Never at startup broke main-viewport wheel
scrolling on WebKitGTK+Wayland; sharp vs balanced remains a CSS AA path.
Use PSYSONIC_WEBKIT_WAYLAND_HW_POLICY for a true Never policy.

* fix(rust): gate Linux-only Wayland WebKit helpers for Windows builds

Re-export startup helpers only under cfg(linux) and drop non-Linux stubs so
Windows compiles without unused-import and dead-code warnings.

* chore(release): CHANGELOG + credits for Linux session/WebKit work (PR #731)

Consolidate scattered incremental changelog notes into two [1.47.0]
entries with PR link; remove duplicate Linux blocks from [1.46.0] Fixed.
Append settings credit line for cucadmuh.
2026-05-18 21:00:46 +03:00

8.5 KiB
Raw Permalink Blame History

Installing Psysonic on NixOS (flake)

This guide is for NixOS users who want Psysonic from the upstream Git flake (github:Psychotoxical/psysonic). Supported systems match the flake: x86_64-linux and aarch64-linux.

Stability: The project is in very active development. For production or everyday use, prefer released builds: pin the flake input to a stable app-v* tag, or track the release branch (?ref=release). Following main or next is better suited to contributors and early testers.

Prerequisites

Flakes enabled (e.g. in configuration.nix):

nix.settings.experimental-features = [ "nix-command" "flakes" ];

Binary cache (Cachix)

The project publishes store paths to a public Cachix cache so you can substitute binaries instead of compiling Psysonic locally on every machine.

  • Cache page: psysonic.cachix.org

  • Substituter URL: https://psysonic.cachix.org

  • Public key (trust this only if it matches what you expect from the cache owners):

    psysonic.cachix.org-1:M9cQyQ7tgvUWOQ5Pyt8ozlMoPLtOZir6MfRuTH9/VYA=
    

NixOS (configuration.nix or a flake module)

Add the substituter and its signing key under nix.settings. Keep cache.nixos.org in the list so ordinary nixpkgs binaries still resolve:

{
  nix.settings = {
    substituters = [
      "https://psysonic.cachix.org"
      "https://cache.nixos.org/"
    ];
    trusted-public-keys = [
      "psysonic.cachix.org-1:M9cQyQ7tgvUWOQ5Pyt8ozlMoPLtOZir6MfRuTH9/VYA="
      "cache.nixos.org-1:6NCHdSuAYQQOxGEKTGXLN9WWRXoSBT8GRiSnR6IdfGW="
    ];
  };
}

After nixos-rebuild switch, builds that hit the cache will download from Cachix. More background: Cachix — Getting started.

Install on NixOS (flake configuration)

Add the repo as an input, then reference packages.<system>.psysonic (or default, which is the same package).

Example: top-level flake.nix + nixosConfigurations

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    psysonic.url = "github:Psychotoxical/psysonic";
  };

  outputs = { self, nixpkgs, ... }@inputs: let
    system = "x86_64-linux";
  in {
    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
      inherit system;
      modules = [
        ./configuration.nix
        {
          environment.systemPackages = [
            inputs.psysonic.packages.${system}.psysonic
          ];
        }
      ];
    };
  };
}

Inside a module where you already have pkgs and flake inputs in scope, a common pattern is:

environment.systemPackages = with pkgs; [
  # …
  inputs.psysonic.packages.${pkgs.stdenv.hostPlatform.system}.psysonic
];

Linux wrapper (default vs legacy X11)

The flake exposes three Linux attributes (two are the same derivation):

Flake attribute Wrapper behaviour
psysonic, default, psysonic-gdk-session Wrappers prefix libraries only (GStreamer, AppIndicator); GDK_BACKEND is not pinned. The binary invokes webkit2gtk-nvidia-quirk early on Linux (unless PSYSONIC_WEBKIT_GPU_ACCEL is set); no extra WEBKIT_DISABLE_* heuristics in main.rs. Override with GDK_BACKEND, WEBKIT_DISABLE_*, etc. whenever you want.
psysonic-x11-legacy Former default: GDK_BACKEND=x11 pinned in the wrapper. Use if you relied on XWayland-ish stability on messy stacks. Same binary as psysonic.

psysonic-gdk-session remains a back-compat alias for psysonic (identical store path).

Example: legacy X11 wrap

inputs.psysonic.packages.${system}.psysonic-x11-legacy

Or one-shot (quote the URL in zsh? / # are special):

nix run 'github:Psychotoxical/psysonic#psysonic-x11-legacy' -- --help

Pinning a revision, branch, or tag

  • main (default in the examples above) follows upstream development.

  • Channel branches (next, release) exist for pre-release / release automation. For operational installs, prefer release (or an app-v* tag) over next or main; use ?ref=next only if you want pre-release channel builds.

    psysonic.url = "github:Psychotoxical/psysonic?ref=release";
    
  • Tags (app-v*) match published GitHub releases and are the usual choice for a reproducible install aligned with a shipped version:

    psysonic.url = "github:Psychotoxical/psysonic?ref=app-v1.44.0";  # example; pick a tag that exists on GitHub
    

Use a ref (branch, tag, or commit SHA) that exists on GitHub.

How flake.lock and nix/upstream-sources.json stay in sync

CI runs a verify-nix job (Nix build, npmDepsHash refresh, flake.lock refresh, Cachix push) from .github/workflows/reusable-channel-publish.yml, invoked by:

  • .github/workflows/next.yml (Next channel, branch next)
  • .github/workflows/release.yml (Release channel, branch release)

So the lock and nix/upstream-sources.json (npmDepsHash) are updated as part of channel publishing, not only from a single legacy “tag-only” path. On main, nix-npm-deps-hash-sync.yml can also open PRs when package-lock.json changes so the Nix npm hash does not drift.

End users who pin main should run nix flake update psysonic (or equivalent) periodically if they want the latest lock inputs from upstream.

One-shot run (no system install)

From any machine with flakes:

nix run 'github:Psychotoxical/psysonic'

Same as nix build / packages.<system>.default (session-native GDK); uses the flake apps output. For an X11-pinned launcher (old default), use 'github:Psychotoxical/psysonic#psysonic-x11-legacy' (see Linux wrapper above). psysonic-gdk-session is an alias—same as psysonic. With a branch pin, keep the whole github:…?ref=…#… string in single quotes under zsh.

Apply configuration

  • NixOS flake host

    sudo nixos-rebuild switch --flake .#my-host
    
  • Home Manager (if used separately)

    home-manager switch --flake .#my-user@my-host
    

Home Manager

If you manage packages with Home Manager, add the same package to home.packages:

home.packages = [
  inputs.psysonic.packages.${pkgs.stdenv.hostPlatform.system}.psysonic
];

(Adjust how inputs / pkgs are passed into your Home Manager module.)

Development shell (contributors)

From a flake-enabled clone of the repo:

  • nix develop — enters the upstream devShell (Rust, Node 22, WebKitGTK, GStreamer plugins for the webview, env hooks aligned with package.json / Tauri dev).
  • nix shell .#devShells.default — same packages and hooks without nix develops subshell semantics.

The flake devShell uses the same nixpkgs input as packages.psysonic (see flake.nix).

Desktop entry

The flake package installs a .desktop file and icon via copyDesktopItems; after nixos-rebuild switch (or a Home Manager activation that includes the package), Psysonic should appear in your application launcher like any other desktop app.

Troubleshooting (Linux / WebKit)

Some GPU / compositor setups show a black window or broken scrolling under Wayland/EGL. The upstream Help / FAQ documents workarounds (e.g. running under X11 and compositor-related env vars). Those apply to the Nix-built binary as well as other Linux builds.

More detail in-repo

  • flake.nixpackages, apps, devShells, supported systems; inline comments for nix build / nix develop / nix run.
  • nix/psysonic.nix — how the app is built from this source tree (npmDepsHash from nix/upstream-sources.json).
  • .github/workflows/reusable-channel-publish.ymlverify-nix job (prefetch npm deps hash, nix flake update, nix build .#psysonic, Cachix push, optional lock refresh PR).
  • .github/workflows/next.yml / .github/workflows/release.yml — channel workflows that call the reusable publish workflow with verify_nix: true.
  • .github/workflows/nix-npm-deps-hash-sync.yml — keeps nix/upstream-sources.json aligned with package-lock.json on main via PRs.

For the full promotion and release picture (branches, tags, automation), see RELEASE_PROCESS.md.