theming: stop the server repainting SSH clients' terminal palette

base16-fish and stylix's btop theme were only disabled on desktops, so a
login shell on Mediaserver printf'd OSC 4/10/11 back down the SSH pipe and
overwrote the client's wallpaper palette. Off everywhere, server TUIs draw
in the client's 16 ANSI colours instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-20 17:52:54 +01:00
parent f55f97481c
commit 3651c7ee2c

View file

@ -541,40 +541,49 @@ in
apply = lib.mkOption { internal = true; type = lib.types.path; }; apply = lib.mkOption { internal = true; type = lib.types.path; };
}; };
config = lib.mkIf isDesktop { config = lib.mkMerge [{
# EVERY host, servers included. stylix ships fish as BOTH a NixOS and a
# home-manager target, and this is the NixOS half —
# programs.fish.interactiveShellInit in /etc/fish. Turning off only the
# home-manager one left this still sourcing base16-fish, which printf's
# OSC 4 / OSC 10 / OSC 11 at every shell start and repaints the build-time
# palette over whatever ghostty just reloaded. Both halves have to go or
# the terminal never changes colour.
#
# Why this is not desktop-only: OSC escapes repaint the terminal that
# DISPLAYS the shell, not the machine running it. A login shell on the
# server sends them straight back down the SSH pipe, so sshing into
# Mediaserver from a themed ghostty repainted the local window in the
# server's build-time wallpaper colours. Off, the server touches nothing
# and every TUI over SSH just uses the client's 16 ANSI colours — which
# theme-apply already keeps in sync with the wallpaper. No theme state
# has to cross the wire at all.
stylix.targets.fish.enable = false;
home-manager.users.fred.stylix.targets.fish.enable = false;
# Same story for btop, one app instead of the whole palette: stylix would
# write a hex theme baked from the host's own wallpaper. On a desktop
# theme-apply owns that file (color_theme points at the state symlink
# below); on the server there is no wallpaper worth following, so leaving
# color_theme unset lands on btop's built-in Default, which draws in the
# terminal's 16 ANSI colours and therefore in the client's theme.
home-manager.users.fred.stylix.targets.btop.enable = false;
}
(lib.mkIf isDesktop {
fred.theming = { fred.theming = {
inherit walls defaultWall; inherit walls defaultWall;
apply = themeApply; apply = themeApply;
}; };
# stylix ships fish as BOTH a NixOS and a home-manager target, and this is
# the NixOS half — programs.fish.interactiveShellInit in /etc/fish. Turning
# off only the home-manager one left this still sourcing base16-fish, which
# printf's OSC 4 / OSC 10 / OSC 11 at every shell start and repaints the
# build-time palette over whatever ghostty just reloaded. Both halves have
# to go or the terminal never changes colour.
stylix.targets.fish.enable = false;
home-manager.users.fred = { config, lib, pkgs, osConfig, ... }: { home-manager.users.fred = { config, lib, pkgs, osConfig, ... }: {
# These four targets write build-time files that theme-apply replaces # These targets write build-time files that theme-apply replaces at
# at runtime; leaving them on means stylix and the switcher fight over # runtime; leaving them on means stylix and the switcher fight over the
# the same paths on every rebuild. # same paths on every rebuild. (btop's is off for every host above.)
stylix.targets.gtk.enable = false; stylix.targets.gtk.enable = false;
stylix.targets.ghostty.enable = false; stylix.targets.ghostty.enable = false;
stylix.targets.btop.enable = false;
# The one that made ghostty look unthemeable. stylix's fish target # (fish's two targets are killed for every host above — base16-fish is
# sources base16-fish, which is a base16-SHELL script: at every shell # what made ghostty look unthemeable, locally and over SSH alike.)
# start it printf's OSC 4 (palette 0-15) and OSC 10/11 (fg/bg) with the
# BUILD-TIME colours, overwriting whatever ghostty just loaded. So a
# wallpaper switch reloaded ghostty correctly and fish immediately
# painted the old scheme back over it — and opening a new window ran
# fish again, which is why reopening never helped either. Only
# selection-background, which base16-fish does not touch, got through.
#
# Off, fish leaves the palette alone and inherits the terminal's, so
# every ANSI-coloured program in a ghostty window follows a switch live.
stylix.targets.fish.enable = false;
# Same reasoning, one layer up: stylix's yazi target writes a theme in # Same reasoning, one layer up: stylix's yazi target writes a theme in
# hex, which would pin yazi to the build-time scheme. home-manager/ # hex, which would pin yazi to the build-time scheme. home-manager/
@ -622,5 +631,5 @@ in
programs.ghostty.settings.keybind = [ "ctrl+shift+alt+f12=reload_config" ]; programs.ghostty.settings.keybind = [ "ctrl+shift+alt+f12=reload_config" ];
programs.btop.settings.color_theme = "${stateLink}/btop.theme"; programs.btop.settings.color_theme = "${stateLink}/btop.theme";
}; };
}; })];
} }