Files
nixos-configs/roles/kodi/default.nix
T

164 lines
6.0 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.roles.kodi;
in
{
options.roles.kodi = {
enable = mkEnableOption "Enable Kodi";
autologin = mkOption {
default = false;
};
wayland = mkOption {
default = true;
};
jellyfinScaleFactor = mkOption {
type = types.nullOr types.float;
default = null;
description = "Scale factor for Jellyfin Media Player UI (e.g., 1.5 for 150% scaling)";
};
stremioScaleFactor = mkOption {
type = types.nullOr types.float;
default = null;
description = "Scale factor for Stremio UI via GDK_BACKEND=x11 + GDK_SCALE (e.g., 2.0 for 200% scaling). Forces XWayland mode since GTK4 ignores GDK_SCALE on native Wayland.";
};
appLauncherServer = {
enable = mkOption {
type = types.bool;
default = false;
description = "Enable HTTP app launcher server for remote control";
};
port = mkOption {
type = types.int;
default = 8081;
description = "Port for the app launcher HTTP server";
};
};
};
config = let
kodiBasePkg = if cfg.wayland then pkgs.kodi-wayland else pkgs.kodi;
kodiPkg = kodiBasePkg.withPackages (pkgs: with pkgs; [
jellyfin
steam-launcher
steam-library
youtube
]);
jellyfinMediaPlayerPkg =
if cfg.jellyfinScaleFactor != null
then pkgs.symlinkJoin {
name = "jellyfin-media-player-scaled";
paths = [ pkgs.qt-pinned.jellyfin-media-player ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
mkdir -p $out/bin
rm -f $out/bin/jellyfin-desktop
makeWrapper ${pkgs.qt-pinned.jellyfin-media-player}/bin/jellyfin-desktop $out/bin/jellyfin-desktop \
--add-flags "--tv --scale-factor ${toString cfg.jellyfinScaleFactor}"
# Update .desktop file to include scale factor and TV mode arguments
mkdir -p $out/share/applications
rm -f $out/share/applications/org.jellyfin.JellyfinDesktop.desktop
substitute ${pkgs.qt-pinned.jellyfin-media-player}/share/applications/org.jellyfin.JellyfinDesktop.desktop \
$out/share/applications/org.jellyfin.JellyfinDesktop.desktop \
--replace-fail "Exec=jellyfin-desktop" "Exec=jellyfin-desktop --tv --scale-factor ${toString cfg.jellyfinScaleFactor}"
'';
}
else pkgs.qt-pinned.jellyfin-media-player;
# stremio-linux-shell is a GTK4/libadwaita + WebKitGTK app (not Electron/CEF).
# --force-device-scale-factor is a Chromium flag that it ignores entirely.
# On Wayland, GTK4 reads scale from the compositor via wp_fractional_scale_v1.
# To force a specific scale, we use GDK_BACKEND=x11 + GDK_SCALE which works
# reliably under XWayland. On native Wayland, GDK_SCALE is ignored.
# Format floats cleanly: 2.0 -> "2", 1.5 -> "1.5"
stremioScaleStr = let
sf = cfg.stremioScaleFactor;
intPart = builtins.floor sf;
s = builtins.toString sf;
m = builtins.match "([0-9]+)\\.([0-9]*[1-9])0*" s;
gdkScale = builtins.toString intPart;
in if sf == intPart then builtins.toString intPart
else if m != null then (builtins.elemAt m 0) + "." + (builtins.elemAt m 1)
else s;
stremioPkg =
if cfg.stremioScaleFactor != null
then pkgs.symlinkJoin {
name = "stremio-scaled";
paths = [ pkgs.stremio-linux-shell ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
mkdir -p $out/bin
rm -f $out/bin/stremio
makeWrapper ${pkgs.stremio-linux-shell}/bin/stremio $out/bin/stremio \
--set GDK_BACKEND x11 \
--set GDK_SCALE ${builtins.toString (builtins.floor cfg.stremioScaleFactor)}
# Update .desktop file to force XWayland + GDK_SCALE for scaling
mkdir -p $out/share/applications
rm -f $out/share/applications/com.stremio.Stremio.desktop
substitute ${pkgs.stremio-linux-shell}/share/applications/com.stremio.Stremio.desktop \
$out/share/applications/com.stremio.Stremio.desktop \
--replace-fail "Exec=sh -c " "Exec=env GDK_BACKEND=x11 GDK_SCALE=${builtins.toString (builtins.floor cfg.stremioScaleFactor)} sh -c "
'';
}
else pkgs.stremio-linux-shell;
in mkIf cfg.enable
{
users.extraUsers.kodi = {
isNormalUser = true;
extraGroups = [ "wheel" "networkmanager" "audio" "video" ];
};
networking.firewall = {
allowedTCPPorts = [ 8080 ] ++ optional cfg.appLauncherServer.enable cfg.appLauncherServer.port;
allowedUDPPorts = [ 8080 ];
};
environment.systemPackages = with pkgs; [
firefox
jellyfinMediaPlayerPkg
kodiPkg
stremioPkg
# qt-pinned.stremio # Replaced by stremio-linux-shell (Rust/CEF-based)
wget
] ++ optional cfg.appLauncherServer.enable pkgs.custom.app-launcher-server;
nixpkgs.config.permittedInsecurePackages = lib.warn
"Allowing insecure package qtwebengine-5.15.19 as a jellyfin-media-player dependency. These are pinned to nixpkgs-qt to avoid rebuilds - update that input separately when you have time."
[
"qtwebengine-5.15.19"
];
programs.kdeconnect.enable = true;
systemd.user.services = mkIf cfg.appLauncherServer.enable {
app-launcher-server = {
description = "HTTP App Launcher Server";
wantedBy = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.custom.app-launcher-server}/bin/app-launcher-server ${toString cfg.appLauncherServer.port}";
Restart = "always";
RestartSec = "5s";
Environment = [
"PATH=${pkgs.firefox}/bin:${kodiPkg}/bin:/run/current-system/sw/bin"
];
};
};
};
services.displayManager = mkIf cfg.autologin {
autoLogin.enable = true;
autoLogin.user = "kodi";
defaultSession = "plasma";
};
};
}