Files
nixpkgs/nixos/modules/programs/wayland/niri.nix
Samuel Ainsworth 7ce9753bd8 nixos/niri: pin defaultSession so GDM 50 stops bouncing to gnome-session
GDM 50 falls back to launching `gnome-session` as the user session
command when the AccountsService record has `Session=` empty and
`services.displayManager.defaultSession` is unset. On a Niri-only
machine the spawn fails with ENOENT and the user is bounced back to
the greeter — an indefinite login loop after a fresh install or after
the AccountsService record gets reset.

GDM 49 hit the same fallback path but happened to find gnome-session
on PATH; the user's first session pick then got stashed in
AccountsService and subsequent logins worked. GDM 50's tighter
environment removed the accidental save.

Setting `services.displayManager.defaultSession = lib.mkDefault "niri"`
inside `programs.niri` makes a Niri-only install boot straight into
the compositor. Users running multiple session packages can still
override via a plain assignment.

Refs https://github.com/NixOS/nixpkgs/issues/523332
2026-06-05 14:17:17 -04:00

96 lines
2.9 KiB
Nix

{
config,
lib,
pkgs,
...
}:
let
cfg = config.programs.niri;
in
{
options.programs.niri = {
enable = lib.mkEnableOption "Niri, a scrollable-tiling Wayland compositor";
package = lib.mkPackageOption pkgs "niri" { };
useNautilus = lib.mkEnableOption "Nautilus as file-chooser for xdg-desktop-portal-gnome" // {
default = true;
};
};
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
environment.systemPackages = [
cfg.package
];
# Required for xdg-desktop-portal-gnome's FileChooser to work properly
services.dbus.packages = lib.mkIf cfg.useNautilus [
pkgs.nautilus
];
services = {
displayManager.sessionPackages = [ cfg.package ];
# GDM 50 falls back to launching "gnome-session" as the user
# session command when neither AccountsService nor displayManager
# .defaultSession pins one. On Niri-only setups that produces a
# login loop because gnome-session isn't installed. Pin Niri as
# the default so it works out of the box; users with multiple
# sessions can still override.
displayManager.defaultSession = lib.mkDefault "niri";
# Recommended by upstream
# https://github.com/YaLTeR/niri/wiki/Important-Software#portals
gnome.gnome-keyring.enable = lib.mkDefault true;
};
systemd.packages = [ cfg.package ];
# Restarting the compositor kills the graphical session; same
# treatment as the display-manager modules.
systemd.user.services.niri = {
restartIfChanged = false;
# Defining the unit here generates a drop-in; without this it
# would carry the NixOS default Environment="PATH=coreutils:…",
# clobbering the PATH that niri-session imported into the user
# manager and breaking spawn actions that rely on it.
enableDefaultPath = false;
};
xdg.portal = {
enable = lib.mkDefault true;
# NOTE: `configPackages` is ignored when `xdg.portal.config.niri` is defined.
config.niri = {
default = [
"gnome"
"gtk"
];
"org.freedesktop.impl.portal.Access" = "gtk";
"org.freedesktop.impl.portal.FileChooser" = lib.mkIf (!cfg.useNautilus) "gtk";
"org.freedesktop.impl.portal.Notification" = "gtk";
"org.freedesktop.impl.portal.Secret" = "gnome-keyring";
};
# Recommended by upstream, required for screencast support
# https://github.com/YaLTeR/niri/wiki/Important-Software#portals
extraPortals = [ pkgs.xdg-desktop-portal-gnome ];
};
}
(import ./wayland-session.nix {
inherit lib pkgs;
enableWlrPortal = false;
enableXWayland = false;
})
]
);
meta.maintainers = with lib.maintainers; [
getchoo
sodiboo
];
}