Giter VIP home page Giter VIP logo

niri-flake's Introduction

This flake contains nix packages for niri, a scrollable-tiling Wayland compositor. You can try it right now: add the binary cache with cachix use niri and then nix run github:sodiboo/niri-flake. You can also try the latest commit to the main branch with nix run github:sodiboo/niri-flake#niri-unstable.

This flake also contains NixOS and home-manager modules to install all necessary components of a working Wayland environment, and to let you manage your configuration declaratively, validating it at build-time. This ensures that your config's schema is always in sync with the installed version of niri.

The main location for documentation is docs.md. The most important outputs are overlays.niri and nixosModules.niri. You may also use my configuration as a reference at github:sodiboo/nix-config

The rest of this README covers miscellaneous topics related to this flake or repo as a whole.

Feel free to contact me at @sodiboo:arcticfoxes.net in the #niri:matrix.org channel or through GitHub issues if you have any questions or concerns.

A note on the automated pull requests in this repository

This repository uses automated pull requests extensively in order to automatically update the lockfile. If you wish to view pull requests made by humans, you can filter for is:pr -label:automated.

This is done in order to keep the niri-unstable version up-to-date. Niri doesn't have an inherent "unstable" versioning scheme (like e.g. Rust or NixOS does) and that terminology is specific to this flake. It is just the latest commit to main. It's equivalent to niri-git on the AUR.

Previously, this was done by telling you to override the niri-src input with the latest version (which puts it in your lockfile), but doing it here has two main benefits:

  1. I can run various hooks to automatically update documentation with, at the very least, the niri version, but also other generated items such as listing the available actions (parsed from source code and enumerated in docs.md).
  2. I can perform checks on the updated lockfile to ensure that nothing breaks with new niri updates.

There are two less obvious benefits:

  1. By requiring the build job to succeed, i can ensure that the latest niri versions are always in my binary cache before the pull request is merged. This means you won't need to build it locally.
  2. By also automatically updating nixpkgs, i can run checks to ensure the modules keep working with the latest nixpkgs.

Currently, there is no home-manager input to this flake since i felt it was unnecessary for just checks, and therefore configurations involving home-manager are not automatically tested at this time.

Binary Cache

I have a binary cache for this flake's outputs. niri.cachix.org hosts builds of niri-stable and niri-unstable for nixos-unstable and nixos-24.05. It only contains builds for x86_64-linux for the time being, mainly because GitHub Actions doesn't support other platforms. (and i do not wish to use qemu for this)

Note

This binary cache is managed by me, sodiboo. By using it, you are trusting me to not serve you malicious software. Using a binary cache is entirely optional.

If you do not wish to use my binary cache, but still want the convenience of one, you could set programs.niri.package = pkgs.niri;, which is provided by nixpkgs. This package will receive updates slower.

If you use NixOS, add the niri.nixosModules.niri module and don't enable niri yet. Rebuild your system once to enable the binary cache, then enable niri. You can set niri-flake.cache.enable = false; to prevent this from happening.

If you're not using the NixOS module, you can add the cache to your system by running cachix use niri. This works on any system with nix installed, not just NixOS.

Using niri-unstable

Both niri.nixosModules.niri and niri.homeModules.niri provide the option to use a custom version of niri. This is done by setting programs.niri.package to the desired derivation. If you want to use the unstable version of niri, you can set it like so:

{pkgs, ...}: {
  nixpkgs.overlays = [ inputs.niri.overlays.niri ];
  programs.niri.package = pkgs.niri-unstable;
}

You can also set the package to the one from nixpkgs (pkgs.niri), which will likely receive updates slower than the niri-stable provided here.

niri.homeModules.config also provides the option to set the package. This won't install niri by itself, but it does set the package version used for build-time validation.

Configuration of niri

programs.niri.settings is the preferred way to configure niri. This is provided by niri.homeModules.config, which is automatically imported when using home-manager as a NixOS module. All options are documented in docs.md.

{
  programs.niri.settings = {
    outputs."eDP-1".scale = 2.0;
  };
}

If for whatever reason you want or need to override this, you can set programs.niri.config. You should give this option structured output from niri.lib.kdl.

{
  programs.niri.config = with inputs.niri.lib.kdl; [
    (node "output" "eDP-1" [
      (leaf "scale" 2.0)
    ])
  ];
}

But you can also pass it a string:

{
  programs.niri.config = ''
    output "eDP-1" {
      scale 2.0
    }
  '';
}

or set programs.niri.config = null; to prevent this module from generating a config file. By default, it will generate a config file based on programs.niri.settings if it is not null.

For debugging (primarily development of this flake i guess), there is also programs.niri.finalConfig which is always a string (or null) and represents the final config file that will be end up in your config directory.

Note

programs.niri.settings is not guaranteed to be compatible with niri versions other than the two provided by this flake.
In particular, this means that i do not guarantee compatibility with the one from nixpkgs at all times (i.e. when nixpkgs is lagging behind due to build failures or other reasons).
In practice, you will not have an issue with this unless you are running old versions of niri that are 2 or more releases behind. I will try my best not to break compatibility with nixpkgs.

This does not apply to programs.niri.config as it is inherently version-agnostic and still provides build-time validation.

Stylix

A module is provided to integrate with Stylix. To use this, the main prerequisite is that you don't ever set programs.niri.config; this will override everything from programs.niri.settings, which is where the stylix module places config.

If you've installed home-manager and stylix as a NixOS module, then this will be automatically imported. Else, you'll have to import niri.homeModules.stylix yourself.

The stylix module provides the option to disable it: stylix.targets.niri.enable = false;. Note that it is already disabled by default if you have stylix.autoEnable set to false.

When enabled, the stylix module will set the active/inactive border colors, and set layout.border to be on by default. It also sets the xcursor theme and size.

Additional notes

When installing niri using the modules provided by this flake:

  • The niri package will be installed, including its systemd units and the niri-session binary.
  • xdg-desktop-portal-gnome will be installed, as it is necessary for screencasting.
  • The GNOME keyring will be enabled. You probably want a keyring installed.

Specifically the NixOS module provides the following additional functionality:

  • It will enable polkit, and run the KDE polkit agent.
  • If you prefer a different polkit authentication agent, you can set systemd.user.services.niri-flake-polkit.enable = false;
  • It enables various other features that Wayland compositors may need, such as dconf, opengl and default fonts. It also adds a pam entry for swaylock, which is necessary if you wish to use swaylock.

Some additional software you may want to install to get a full desktop experience:

  • A notification daemon such as mako
  • A bar such as waybar
  • A launcher such as fuzzel

These will usually be installed through home-manager. No particular configuration is necessary for them to work with niri specifically, as they generally start on graphical-session.target which includes niri.

If using waybar, you'll want to set programs.waybar.settings.mainBar.layer = "top";, to ensure it is visible over applications running in niri. You'll also wanna set programs.waybar.systemd.enable = true; which i've found seems to exceed the default restart limit of 5, so you may want to run systemctl --user reset-failed waybar.service in spawn-at-startup to get it to start.

For electron applications such as vscode, you will want to set programs.niri.environment."NIXOS_OZONE_WL" = 1. Several packages in nixpkgs look for this variable, and pass some ozone flags in that case. Note that you must use niri-session to start niri for this to have any effect, because running just niri will not set the neccecary environment variables.

Visual Studio Code does not properly detect the correct keyring to use on my system. It works fine if you launch it with code --password-store="gnome-libsecret". You persist this flag in Preferences > Configure Runtime Arguments (argv.json), by setting "password-store": "gnome-libsecret".

niri-flake's People

Contributors

2639-unofficial avatar algernon avatar danth avatar github-actions[bot] avatar k0ral avatar logicaloverflow avatar mergify[bot] avatar pinkcreeper100 avatar sodiboo avatar twoneis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

niri-flake's Issues

systemd services that depend on niri don't work as expected

The systemd integration is quite a mess compared to the Sway and Hyprland modules.

The swayidle service won't start because it doesn't have access to the WAYLAND_DISPLAY variable, and the wbg and waybar services work erratically when binded to graphical-session.target.

I've seen that in your personal configuration, some hacks had to be implemented to get around these problems, but this is far from desirable...

A solution using a session target would be much better integrated with NixOS/Home Manager, as most modules that need integration provide a systemdTarget parameter to set the relevant one. It can also be easily integrated into custom services.

I'm not sure whether these changes can be made directly in the NixOS module or whether they need to be made on the niri side, as the author seems to be leaning towards a different solution for systemd integration that uses a session script and no target.

programs.niri.settings.spawn-at-startup usage

How can I use programs.niri.settings.spawn-at-startup? I tried

programs.niri.settings.spawn-at-startup = [ "waybar"]

and

programs.niri.settings.spawn-at-startup = [ ["waybar"] ]

The docs aren't really clear on the usage. Any help would be appreciated, thanks!

document nix-specific equivalents of topics from niri wiki (+ off-topic nix talk, vscode ozone)

niri's wiki documents a bunch of common tasks and how to achieve them using niri.
users of this flake repo will face the challenge of how to translate those solutions to the NixOS context, or may further wonder how much of those concerns will have been addressed by this repo out of the box already.
it would be nice to have perhaps the readme here explain tackling such related tasks for users of this repo as well, including which of those have been tackled by this flake and which ones should be handled manually (and if so, how).

add a NixOS module to nixpkgs

First of all, thank you for your work and effort on this!

So far i haven't used flakes and am thus a bit hesitant about it. That's why i am wondering why you havent't added a niri module to NixOS (like the one for hyprland for example)?

I understand that using your flake provides more flexibility but i don't need that and would be happy with a "vanilla" module.

Would you consider adding one (while continuing your flake of course)?

Question: running along sid egnome

Hi there, few quick questions.

  • Can I safely run this along side Gnome? I ask because of how it is described that Niri sets up a complete Wayland env.
  • If I was to run off of this flake, does this take care of the keyring, ssh-agents, etc? I ask because you have configured polkit, etc.
  • Do I need to configure the portals? I know that you noted needing the gnome one, but I was not sure if you already took care of that
  • Does this install a display manager, and does all of the appropriate hooks into PAM, etc?

Sorry if these are odd questions. When reading the Read Me, it "sounds" like it is "batteries included," with the exceptions of the bar, launcher, etc.

Thank you.

How to use this flake

I'm unable to understand where to start with this flake. I was able to follow https://wiki.hyprland.org/Nix/

Is there some explanation of simple clear ways you can add this to a nixos installation so it's available just like the other Compositors?

Nixpkgs 23.11 compatibility

Using niri-flake as a NixOS modulo seems to use the NixOS nixpkgs, which doesn't know about --replace-fail yet on 23.11:

error: builder for '/nix/store/kpcz07qm41dxi5x7lzkxmgmy59bxd5ds-rust_niri-config-0.1.2.drv' failed with exit code 1;
       last 6 log lines:
       > Running phase: unpackPhase
       > unpacking source archive /nix/store/mmczsxgmcidlpksshfw3gky7yw1rpwny-source/niri-config
       > source root is niri-config
       > Running phase: patchPhase
       > substituteStream(): ERROR: Invalid command line argument: --replace-fail
       > /nix/store/10i1kjjq5szjn1gp6418x8bc1hswqc90-stdenv-linux/setup: line 131: pop_var_context: head of shell_variables not a function context
       For full logs, run 'nix log /nix/store/kpcz07qm41dxi5x7lzkxmgmy59bxd5ds-rust_niri-config-0.1.2.drv'.

error: stack overflow (possible infinite recursion)

A new flake lock update, is making this error. I rolled back version for this flake and it works without any issue. I'm not sure what information I can give you that is relevant.

Error:

$ nix flake check
warning: Git tree '/home/nithin/nix' is dirty
evaluating flake...
error: stack overflow (possible infinite recursion)

This is my flake.nix

{
  description = "System Configuration";

  inputs = {
    nixpkgs.url = "nixpkgs/nixos-unstable";
    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";
    chaotic.url = "github:chaotic-cx/nyx/nyxpkgs-unstable";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    alejandra.url = "github:kamadorueda/alejandra/3.0.0";
    alejandra.inputs.nixpkgs.follows = "nixpkgs";
    nil.url = "github:oxalica/nil";
    niri.url = "github:sodiboo/niri-flake";
    ags.url = "github:Aylur/ags";
    lanzaboote = {
      url = "github:nix-community/lanzaboote/v0.4.1";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
    walker.url = "github:abenz1267/walker";
  };

  outputs = {
    alejandra,
    nixpkgs,
    nixpkgs-stable,
    home-manager,
    chaotic,
    lanzaboote,
    niri,
    ags,
    walker,
    ...
  } @ inputs: {
    nixosConfigurations = {
      ntsv = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        specialArgs = {
          pkgs-stable = import nixpkgs-stable {
            inherit system;
            config.allowUnfree = true;
          };
          inherit inputs;
        };
        modules = [
          niri.nixosModules.niri
          {
            environment.systemPackages = [alejandra.defaultPackage.${system}];
          }
          ./configuration.nix
          home-manager.nixosModules.home-manager
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;

            home-manager.extraSpecialArgs = {inherit inputs;};
            home-manager.users.nithin = import ./home.nix;

            home-manager.backupFileExtension = "bak"; # Optionally, use home-manager.extraSpecialArgs to pass
            # arguments to home.nix
          }
          chaotic.nixosModules.default
          lanzaboote.nixosModules.lanzaboote
          ./secureboot.nix
        ];
      };
    };
    formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.alejandra;
  };
}

and this is my niri.nix

{
  pkgs,
  config,
  lib,
  ...
}:
with lib; let
  binds = {
    suffixes,
    prefixes,
    substitutions ? {},
  }: let
    replacer = replaceStrings (attrNames substitutions) (attrValues substitutions);
    format = prefix: suffix: let
      actual-suffix =
        if isList suffix.action
        then {
          action = head suffix.action;
          args = tail suffix.action;
        }
        else {
          inherit (suffix) action;
          args = [];
        };

      action = replacer "${prefix.action}-${actual-suffix.action}";
    in {
      name = "${prefix.key}+${suffix.key}";
      value.action.${action} = actual-suffix.args;
    };
    pairs = attrs: fn:
      concatMap (key:
        fn {
          inherit key;
          action = attrs.${key};
        }) (attrNames attrs);
  in
    listToAttrs (pairs prefixes (prefix: pairs suffixes (suffix: [(format prefix suffix)])));
in {
  programs.niri = {
    settings = {
      input.keyboard.xkb.layout = "us";
      input.focus-follows-mouse = {
        enable = true;
        max-scroll-amount = "10%";
      };
      input.mouse.accel-speed = 1.0;
      input.touchpad = {
        tap = true;
        dwt = true;
        natural-scroll = true;
        click-method = "clickfinger";
      };

      input.tablet.map-to-output = "eDP-1";
      input.touch.map-to-output = "eDP-1";

      prefer-no-csd = true;

      layout = {
        gaps = 10;
        struts.left = 0;
        struts.right = 0;
        focus-ring.enable = false;
        border = {
          enable = true;
          width = 2;
          active.gradient = {
            from = "#ADEFD1";
            to = "#00203F";
            angle = 45;
            relative-to = "workspace-view";
          };
          inactive.gradient = {
            from = "#00203F";
            to = "#ADEFD1";
            angle = 45;
            relative-to = "workspace-view";
          };
        };
      };

      hotkey-overlay.skip-at-startup = true;

      binds = with config.lib.niri.actions; let
        sh = spawn "sh" "-c";
      in
        lib.attrsets.mergeAttrsList [
          {
            "Mod+T".action = spawn "wezterm";
            "Mod+D".action = spawn "walker";
            # "Mod+W".action = sh (builtins.concatStringsSep "; " [
            #   "systemctl --user restart waybar.service"
            #   "systemctl --user restart swaybg.service"
            # ]);

            "Mod+L".action = spawn "blurred-locker";
            "Print".action = sh "flameshot gui";
            "Mod+Print".action = sh "flameshot full --clipboard";
            "Mod+Shift+Print".action = sh "flameshot full";
            "XF86AudioRaiseVolume".action = sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1+";
            "XF86AudioLowerVolume".action = sh "wpctl set-volume @DEFAULT_AUDIO_SINK@ 0.1-";
            "XF86AudioMute".action = sh "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";

            "XF86MonBrightnessUp".action = sh "brightnessctl set 10%+";
            "XF86MonBrightnessDown".action = sh "brightnessctl set 10%-";

            "Mod+Q".action = close-window;

            "XF86AudioNext".action = focus-column-right;
            "XF86AudioPrev".action = focus-column-left;

            "Mod+Tab".action = focus-window-down-or-column-right;
            "Mod+Shift+Tab".action = focus-window-up-or-column-left;
          }
          (binds {
            suffixes."Left" = "column-left";
            suffixes."Down" = "window-down";
            suffixes."Up" = "window-up";
            suffixes."Right" = "column-right";
            prefixes."Mod" = "focus";
            prefixes."Mod+Ctrl" = "move";
            prefixes."Mod+Shift" = "focus-monitor";
            prefixes."Mod+Shift+Ctrl" = "move-window-to-monitor";
            substitutions."monitor-column" = "monitor";
            substitutions."monitor-window" = "monitor";
          })
          (binds {
            suffixes."Home" = "first";
            suffixes."End" = "last";
            prefixes."Mod" = "focus-column";
            prefixes."Mod+Ctrl" = "move-column-to";
          })
          (binds {
            suffixes."U" = "workspace-down";
            suffixes."I" = "workspace-up";
            prefixes."Mod" = "focus";
            prefixes."Mod+Ctrl" = "move-window-to";
            prefixes."Mod+Shift" = "move";
          })
          (binds {
            suffixes = builtins.listToAttrs (map (n: {
              name = toString n;
              value = ["workspace" n];
            }) (range 1 9));
            prefixes."Mod" = "focus";
            prefixes."Mod+Ctrl" = "move-window-to";
          })
          {
            "Mod+Comma".action = consume-window-into-column;
            "Mod+Period".action = expel-window-from-column;

            "Mod+R".action = switch-preset-column-width;
            "Mod+F".action = maximize-column;
            "Mod+Shift+F".action = fullscreen-window;
            "Mod+C".action = center-column;

            "Mod+Minus".action = set-column-width "-10%";
            "Mod+Plus".action = set-column-width "+10%";
            "Mod+Shift+Minus".action = set-window-height "-10%";
            "Mod+Shift+Plus".action = set-window-height "+10%";

            "Mod+Shift+E".action = quit;
            "Mod+Shift+P".action = power-off-monitors;

            "Mod+Shift+Ctrl+T".action = toggle-debug-tint;
          }
        ];

      # examples:

      spawn-at-startup = [
        {command = ["xwayland-satellite"];}
        {command = ["swaybg"];}
        {command = ["variety"];}
        {command = ["ags"];}
      ];

      animations.shaders.window-resize = ''
        vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) {
            vec3 coords_next_geo = niri_curr_geo_to_next_geo * coords_curr_geo;

            vec3 coords_stretch = niri_geo_to_tex_next * coords_curr_geo;
            vec3 coords_crop = niri_geo_to_tex_next * coords_next_geo;

            // We can crop if the current window size is smaller than the next window
            // size. One way to tell is by comparing to 1.0 the X and Y scaling
            // coefficients in the current-to-next transformation matrix.
            bool can_crop_by_x = niri_curr_geo_to_next_geo[0][0] <= 1.0;
            bool can_crop_by_y = niri_curr_geo_to_next_geo[1][1] <= 1.0;

            vec3 coords = coords_stretch;
            if (can_crop_by_x)
                coords.x = coords_crop.x;
            if (can_crop_by_y)
                coords.y = coords_crop.y;

            vec4 color = texture2D(niri_tex_next, coords.st);

            // However, when we crop, we also want to crop out anything outside the
            // current geometry. This is because the area of the shader is unspecified
            // and usually bigger than the current geometry, so if we don't fill pixels
            // outside with transparency, the texture will leak out.
            //
            // When stretching, this is not an issue because the area outside will
            // correspond to client-side decoration shadows, which are already supposed
            // to be outside.
            if (can_crop_by_x && (coords_curr_geo.x < 0.0 || 1.0 < coords_curr_geo.x))
                color = vec4(0.0);
            if (can_crop_by_y && (coords_curr_geo.y < 0.0 || 1.0 < coords_curr_geo.y))
                color = vec4(0.0);

            return color;
        }
      '';

      window-rules = [
        {
          draw-border-with-background = false;
          geometry-corner-radius = let
            r = 8.0;
          in {
            top-left = r;
            top-right = r;
            bottom-left = r;
            bottom-right = r;
          };
          clip-to-geometry = true;
        }
        {
          matches = [{is-focused = false;}];
          opacity = 0.95;
        }
        {
          # the terminal is already transparent from stylix
          matches = [{app-id = "^foot$";}];
          opacity = 1.0;
        }
        {
          matches = [
            {
              app-id = "^firefox$";
              title = "Private Browsing";
            }
          ];
          border.active.color = "purple";
        }
      ];
    };
  };
  programs.wezterm.enable = true;
  programs.foot = {
    enable = true;
    settings = {
      environment = {
        VK_DRIVER_FILES = "/run/opengl-driver/share/vulkan/icd.d/intel_icd.x86_64.json";
        QT_QPA_PLATFORM = "wayland";
        DISPLAY = ":0";
        EDITOR = "nvim";
        WLR_NO_HARDWARE_CURSORS = "1";
        NIXOS_OZONE_WL = "1";
      };
      csd.preferred = "none";
      main = let
        withSize = "size=${toString size}";
        size = "11";
        font = "Iosevka Term";
      in {
        term = "xterm-256color";
        font = "${font}:${withSize}";
        font-bold = "${font}:style=Bold:${withSize}";
        font-italic = "${font}:style=Italic:${withSize}";
        font-bold-italic = "${font}:style=BoldItalic:${withSize}";
        box-drawings-uses-font-glyphs = true;
        initial-window-size-pixels = "800x600";
      };

      scrollback = {
        lines = 10000;
      };

      url = {
        launch = "xdg-open \${url}";
        protocols = "http, https, ftp, ftps, file";
      };

      colors = {
        alpha = 0.75;
        foreground = "ADEFD1";
        background = "00203F";
      };
    };
  };

  programs.fuzzel = {
    enable = true;
    settings.main.terminal = "foot";
  };
  services.swaync = {
    enable = true;
  };

  home.packages = with pkgs; [
    brightnessctl
    flameshot
    xwayland
    xwayland-satellite
    variety
    swaybg
  ];
}

The niri config is mostly copied from yours.

cannot run xwayland-satellite: Xwayland not in PATH

going by 1944dcb, i tried installing xwayland-satellite.
as per https://github.com/Supreeeme/xwayland-satellite?tab=readme-ov-file#usage and https://github.com/YaLTeR/niri/wiki/Xwayland#using-xwayland-satellite, it seems invoking it should be a matter of just running xwayland-satellite, but that seemed to get me an error as follows:

thread 'main' panicked at /source/src/lib.rs:80:10:
called Result::unwrap() on an Err value: Os { code: 2, kind:
NotFound, message: "No such file or directory" }

(RUST_BACKTRACE=1 xwayland-satellite appeared to not actually yield a stack trace.)

before diffing nixpkgs versions and the like, this does seem to be how the package would be invoked, right?

document using xdg-portal?

on nixos, using the niri service my services.flatpak.enable = true; would error:

To use Flatpak you must enable XDG Desktop Portals with xdg.portal.enable.

while i see this mentioned in code here and at niri-src, i haven't figured out how to make this work yet.

following the approach i used on hyprland, i tried e.g.:

    xdg.portal = {
      enable = true;
      wlr.enable = true;
      extraPortals = with pkgs; [
        xdg-desktop-portal-gnome
      ];
    };

this appeared not to satisfy the flatpak service yet tho so far.

Screensharing possible

Do I have to add some config to enable screensharing? According to niri's README, screensharing should work. But I can't get it working. I saw you've added the gnome xdg-portal but still there is probably something missing in my config.

It seems like stylix and niri-flake not doing well

error: The option `home-manager.users.lennylizowzskiy.programs.niri.finalConfig' in `/nix/store/a7idmrymwccm7gnssm2hb04f6yk2mz9c-source/nixos/common.nix' is already declared in `/nix/store/hixvzv8fr9k5dp9fvrxyhjvij9f6r84p-hx7fxaip5vqk92y05rjsyf25hfb5vhph-source/home-manager/presets/per-user/lennylizowzskiy/configs/gui/de/niri'.

Config:

# home-manager
{
  imports = [
    inputs.niri-flake.homeModules.config

    # ...
  ];

  home.packages = with pkgs; [
    # ...
  ];

  programs.niri = {
    settings = {
      prefer-no-csd = true;

      output = {
        "DP-2".mode = "[email protected]";
      };
  # ...

I'm running NixOS unstable with stylix and home-manager both enabled

Feature Request: Generate config without home-manager

I'd really like to be able to use this module to generate my niri config, but I don't use home manager... I currently am doing this with: ```
nixpkgs.overlays = [
niri.overlays.niri

				(_final: _prev: {
					# Modify the niri startup command to point it to the
					# config file
					niri-unstable = _prev.niri-unstable.overrideAttrs (final: prev: {
						postFixup = ''
							${prev.postFixup}

							substituteInPlace $out/share/systemd/user/niri.service --replace "--session" "--session -c ${./niri.kdl}"
							'';
					});
				})
			];

			programs.niri.enable			= true;
			programs.niri.package			= pkgs.niri-unstable;

I'd like to be able to use this flake to generate my `niri.kdl` file though. That would make it a lot easier to make tweaks for specific machines, etc.

Is it possible to do that, and then use the output in my overlay to point to that derivation?

allow-when-locked=false is being added to every bind

This may be user error, I'm setting this up for the first time.

It appears that allow-when-locked=false is being added to every keybind, and niri is complaining that this field may only be set on spawn binds.

Here are my binds:

      binds = {
        "Mod+Shift+Slash".action.show-hotkey-overlay = [];
      
        "Mod+Return".action.spawn = ["kitty"];
        "Mod+D".action.spawn = ["rofi" "-show" "run"];
        "Super+Alt+L".action.spawn = ["swaylock"];
      
	"XF86AudioRaiseVolume".action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1+"];
	"XF86AudioLowerVolume".action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.1-"];
      
        "Mod+Q".action.close-window = [];
      
        "Mod+Left".action.focus-column-left = [];
        "Mod+H".action.focus-column-left = [];
        "Mod+Down".action.focus-window-down = [];
        "Mod+J".action.focus-window-down = [];
        "Mod+Up".action.focus-window-up = [];
        "Mod+K".action.focus-window-up = [];
        "Mod+Right".action.focus-column-right = [];
        "Mod+L".action.focus-column-right = [];
      
        "Mod+Ctrl+Left".action.move-column-left = [];
        "Mod+Ctrl+H".action.move-column-left = [];
        "Mod+Ctrl+Down".action.move-window-down = [];
        "Mod+Ctrl+J".action.move-window-down = [];
        "Mod+Ctrl+Up".action.move-window-up = [];
        "Mod+Ctrl+K".action.move-window-up = [];
        "Mod+Ctrl+Right".action.move-column-right = [];
        "Mod+Ctrl+L".action.move-column-right = [];
      
        "Mod+Home".action.focus-column-first = [];
        "Mod+End".action.focus-column-last = [];
        "Mod+Ctrl+Home".action.move-column-to-first = [];
        "Mod+Ctrl+End".action.move-column-to-last = [];
      
        "Mod+Shift+Left".action.focus-monitor-left = [];
        "Mod+Shift+H".action.focus-monitor-left = [];
        "Mod+Shift+Down".action.focus-monitor-down = [];
        "Mod+Shift+J".action.focus-monitor-down = [];
        "Mod+Shift+Up".action.focus-monitor-up = [];
        "Mod+Shift+K".action.focus-monitor-up = [];
        "Mod+Shift+Right".action.focus-monitor-right = [];
        "Mod+Shift+L".action.focus-monitor-right = [];
      
        "Mod+Shift+Ctrl+Left".action.move-column-to-monitor-left = [];
        "Mod+Shift+Ctrl+H".action.move-column-to-monitor-left = [];
        "Mod+Shift+Ctrl+Down".action.move-column-to-monitor-down = [];
        "Mod+Shift+Ctrl+J".action.move-column-to-monitor-down = [];
        "Mod+Shift+Ctrl+Up".action.move-column-to-monitor-up = [];
        "Mod+Shift+Ctrl+K".action.move-column-to-monitor-up = [];
        "Mod+Shift+Ctrl+Right".action.move-column-to-monitor-right = [];
        "Mod+Shift+Ctrl+L".action.move-column-to-monitor-right = [];
      
        "Mod+Page_Down".action.focus-workspace-down = [];
        "Mod+Page_Up".action.focus-workspace-up = [];
        "Mod+U".action.focus-workspace-down = [];
        "Mod+I".action.focus-workspace-up = [];
        "Mod+Ctrl+Page_Down".action.move-column-to-workspace-down = [];
        "Mod+Ctrl+Page_Up".action.move-column-to-workspace-up = [];
        "Mod+Ctrl+U".action.move-column-to-workspace-down = [];
        "Mod+Ctrl+I".action.move-column-to-workspace-up = [];
      
        "Mod+Shift+Page_Down".action.move-workspace-down = [];
        "Mod+Shift+Page_Up".action.move-workspace-up = [];
        "Mod+Shift+U".action.move-workspace-down = [];
        "Mod+Shift+I".action.move-workspace-up = [];
      
        "Mod+WheelScrollDown" = {
  	 cooldown-ms = 150;
  	 action.focus-workspace-down = [];
  	};
        "Mod+WheelScrollUp" = {
  	 cooldown-ms = 150;
  	 action.focus-workspace-up = [];
  	};
        "Mod+Ctrl+WheelScrollDown" = {
  	 cooldown-ms = 150;
  	 action.move-column-to-workspace-down = [];
  	};
        "Mod+Ctrl+WheelScrollUp" = {
  	 cooldown-ms = 150;
  	 action.move-column-to-workspace-up = [];
  	};
  
        "Mod+WheelScrollRight".action.focus-column-right = [];
        "Mod+WheelScrollLeft".action.focus-column-left = [];
        "Mod+Ctrl+WheelScrollRight".action.move-column-right = [];
        "Mod+Ctrl+WheelScrollLeft".action.move-column-left = [];
      
        "Mod+Shift+WheelScrollDown".action.focus-column-right = [];
        "Mod+Shift+WheelScrollUp".action.focus-column-left = [];
        "Mod+Ctrl+Shift+WheelScrollDown".action.move-column-right = [];
        "Mod+Ctrl+Shift+WheelScrollUp".action.move-column-left = [];
      
        #Mod+1 { focus-workspace 1; }
        #Mod+2 { focus-workspace 2; }
        #Mod+3 { focus-workspace 3; }
        #Mod+4 { focus-workspace 4; }
        #Mod+5 { focus-workspace 5; }
        #Mod+6 { focus-workspace 6; }
        #Mod+7 { focus-workspace 7; }
        #Mod+8 { focus-workspace 8; }
        #Mod+9 { focus-workspace 9; }
        #Mod+Ctrl+1 { move-column-to-workspace 1; }
        #Mod+Ctrl+2 { move-column-to-workspace 2; }
        #Mod+Ctrl+3 { move-column-to-workspace 3; }
        #Mod+Ctrl+4 { move-column-to-workspace 4; }
        #Mod+Ctrl+5 { move-column-to-workspace 5; }
        #Mod+Ctrl+6 { move-column-to-workspace 6; }
        #Mod+Ctrl+7 { move-column-to-workspace 7; }
        #Mod+Ctrl+8 { move-column-to-workspace 8; }
        #Mod+Ctrl+9 { move-column-to-workspace 9; }
      
        "Mod+Comma".action.consume-window-into-column = [];
        "Mod+Period".action.expel-window-from-column = [];
      
        "Mod+R".action.switch-preset-column-width = [];
        "Mod+F".action.maximize-column = [];
        "Mod+Shift+F".action.fullscreen-window = [];
        "Mod+C".action.center-column = [];
      
        "Mod+Minus".action.set-column-width = "-10%";
        "Mod+Equal".action.set-column-width = "+10%";
      
        "Mod+Shift+Minus".action.set-window-height = "-10%";
        "Mod+Shift+Equal".action.set-window-height = "+10%";
      
        "Mod+Space".action.switch-layout = "next";
        "Mod+Shift+Space".action.switch-layout = "prev";
      
        "Print".action.screenshot = [];
        "Ctrl+Print".action.screenshot-screen = [];
        "Alt+Print".action.screenshot-window = [];
      
        "Mod+Shift+E".action.quit = [];
      
        "Mod+Shift+P".action.power-off-monitors = [];
      };

Running home-manager switch gives me:

error: builder for '/nix/store/8hr5hmkm207jyh7zigpdhgr1hl9s1kzl-config.kdl.drv' failed with exit code 1;
       last 10 log lines:
       > Error: allow-when-locked can only be set on spawn binds
       >     Diagnostic severity: error
       >
       > Begin snippet for .attr-041r6j70w6v6dakqkzmwb899h71g2hibch7d14bbv9gy7bxhd5mp starting at line 133, column 1
       >
       > snippet line 133:     Mod+WheelScrollUp allow-when-locked=false cooldown-ms=150 { focus-workspace-up; }
       > snippet line 134:     Print allow-when-locked=false { screenshot; }
       >     label at line 134, columns 11 to 27: unexpected property
       > snippet line 135:     Super+Alt+L allow-when-locked=false { spawn "swaylock"; }
       >
       For full logs, run 'nix log /nix/store/8hr5hmkm207jyh7zigpdhgr1hl9s1kzl-config.kdl.drv'.
error: 1 dependencies of derivation '/nix/store/mr66jb6g3v8qp9bdmgsirzk38hzb988j-home-manager-files.drv' failed to build
error: 1 dependencies of derivation '/nix/store/5hv1da881bnmbxfh143ky5k7gvlvm5pa-home-manager-generation.drv' failed to build

And checking out the requested log file shows me many lines as above, one for each bind (not reproduced here due to length).

Again, this may be error on my end, but not sure what I could be doing wrong.

caching nix builds

i wonder if we could maybe alleviate local builds by say having a cachix user for niri.
if so, would it be best if this were done from niri-flake, from the upstream niri repo, or from both?

niri cannot use

really sorry to bother you, i'm new to nixos and i wanna try niri, i'm using vmware to do this but after sddm it's just purely dark screen.

systemctl niri.service log:

3.29 23:49:19 nixos niri[1121]: 2024-03-29T15:49:19.738679Z  WARN niri::niri: error starting PipeWire: error creating Core
3.29 23:49:19 nixos niri[1121]: Caused by:
3.29 23:49:19 nixos niri[1121]:     Creation failed
3.29 23:49:19 nixos niri[1121]: 2024-03-29T15:49:19.738816Z DEBUG niri::backend::tty: device added: 57856 "/dev/dri/card0"
3.29 23:49:19 nixos niri[1121]: VMware: No 3D enabled (0, Success).
3.29 23:49:19 nixos niri[1121]: 2024-03-29T15:49:19.763147Z  WARN niri::backend::tty: error adding device: None of the following EGL extensions is supported by the underlying EGL implementation, at least one is required>
3.29 23:49:19 nixos niri[1121]: 2024-03-29T15:49:19.763180Z  INFO niri: listening on Wayland socket: wayland-1
3.29 23:49:19 nixos niri[1121]: 2024-03-29T15:49:19.763186Z  INFO niri: IPC listening on: /run/user/1000/niri.wayland-1.1121.sock
3.29 23:49:19 nixos systemd[1078]: Started A scrollable-tiling Wayland compositor.
3.29 23:50:26 nixos niri[1121]: 2024-03-29T15:50:26.477927Z DEBUG niri::backend::tty: pausing session

my nix config:

configuration.nix

{ config, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Bootloader.
  boot.loader.grub.enable = true;
  boot.loader.grub.device = "/dev/sda";
  boot.loader.grub.useOSProber = true;

  networking.hostName = "nixos"; # Define your hostname.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Enable networking
  networking.networkmanager.enable = true;

  # Set your time zone.
  time.timeZone = "Asia/Shanghai";

  # Select internationalisation properties.
  i18n.defaultLocale = "en_US.UTF-8";

  i18n.extraLocaleSettings = {
    LC_ADDRESS = "zh_CN.UTF-8";
    LC_IDENTIFICATION = "zh_CN.UTF-8";
    LC_MEASUREMENT = "zh_CN.UTF-8";
    LC_MONETARY = "zh_CN.UTF-8";
    LC_NAME = "zh_CN.UTF-8";
    LC_NUMERIC = "zh_CN.UTF-8";
    LC_PAPER = "zh_CN.UTF-8";
    LC_TELEPHONE = "zh_CN.UTF-8";
    LC_TIME = "zh_CN.UTF-8";
  };

  # Configure keymap in X11
  #services.xserver = {
  #  layout = "us";
  #  xkbVariant = "";
  #};
  services.xserver = {
    enable = true;
    libinput.enable = true;

    # Display Manager
    displayManager = {
      defaultSession = "niri";

      # SDDM
      sddm = {
        enable = true;
        wayland.enable = true;
        theme = "catppuccin";
      };
    };
  };

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.ogios = {
    isNormalUser = true;
    description = "ogios";
    extraGroups = [ "networkmanager" "wheel" ];
    packages = with pkgs; [];
  };

  # Allow unfree packages
  nixpkgs.config.allowUnfree = true;

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
    git
  ];

  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  programs.neovim.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  networking.firewall.enable = false;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "23.11"; # Did you read the comment?
}

hardware-configuration.nix (didn't change)

{ config, lib, pkgs, modulesPath, ... }:

{
  imports = [ ];

  boot.initrd.availableKernelModules = [ "ata_piix" "mptspi" "uhci_hcd" "ehci_pci" "ahci" "sd_mod" "sr_mod" ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    { device = "/dev/disk/by-uuid/950e55c2-fab1-409e-95b7-313288e68f5a";
      fsType = "ext4";
    };

  swapDevices = [ ];

  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
  # (the default) this is the recommended approach. When using systemd-networkd it's
  # still possible to use this option, but it's recommended to use it in conjunction
  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
  networking.useDHCP = lib.mkDefault true;
  # networking.interfaces.ens33.useDHCP = lib.mkDefault true;

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

flake.nix

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

    niri.url = "github:sodiboo/niri-flake";
  };

  outputs = { self, nixpkgs, niri, ... }: {
    nixosConfigurations.ogios = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ./configuration.nix
        niri.nixosModules.niri
        {
          programs.niri.enable = true;
        }
        #{ # If you wish to use the unstable version of niri, you can set it like so:
        #  nixpkgs.overlays = [ niri.overlays.niri ];
        #  programs.niri.package = pkgs.niri-unstable;
        #}
      ];
    };
  };
}

Question: Why is this not merged with the main repo?

Why hasn't this repository been merged with the main one that contains the source code? Keeping the repositories separate makes it more difficult to find. All nix modules, with the exception of flake.nix and flake.lock, could be moved to a nix directory.

rofi-wayland does not register keyboard input

Steps to reproduce:

$ rofi -show drun -no-config | wl-copy 

(process:9501): libnkutils-bindings-CRITICAL **: 10:39:42.553: nk_bindings_seat_handle_key: assertion 'self->keymap != NULL' failed

Using default niri configuration.

`error: undefined variable 'mergeAttrsList'` when trying to set binds

Hello! Just trying this out but got stuck when trying to create binds. I have (in my Home Manager configuration):

    niri.settings = {
      binds = {
        "Mod+Left".action = config.lib.niri.actions.focus-left;
      };
      
      outputs."DP-3".mode = {
        width = 2560;
        height = 1440;
        refresh = 165.0;
      };
    };

But this produces the error:

error:
       … while calling the 'head' builtin

         at /nix/store/qwcxqcxfmf6nifz3yqg6rkn2h6mf65x9-source/lib/attrsets.nix:922:11:

          921|         || pred here (elemAt values 1) (head values) then
          922|           head values
             |           ^
          923|         elsewhile evaluating the attribute 'value'

         at /nix/store/qwcxqcxfmf6nifz3yqg6rkn2h6mf65x9-source/lib/modules.nix:807:9:

          806|     in warnDeprecation opt //
          807|       { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          808|         inherit (res.defsFinal') highestPrio;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: undefined variable 'mergeAttrsList'

       at /nix/store/35l35rk7ximl9zlqqqrk9crccbhbrzx2-source/flake.nix:353:25:

          352|             config.lib.niri = {
          353|               actions = mergeAttrsList (map ({
             |                         ^
          354|                 name,

Can you see anything I'm doing wrong?

Desktop Session

I've got the flake working and I can launch niri manually, but I was wondering if there's a magic trick to get niri as an option with gdm or sddm?

services.xserver.displayManager got renamed over to services.displayManager

As of this commit there was a tree-wide change in nixos-unstable that moves services.xserver.displayManager to services.displayManager, making it so no NixOS config can be built if niri-flake is enabled now :(

The affected file is as as of 1fd2e47

services.xserver.displayManager.sessionPackages = [cfg.package];

By editing this file so it has some check like this, this issue may be fixed.

if (system.stateVersion != "24.05") then services.displayManager.sessionPackages = [cfg.package]; 
else services.xserver.displayManager.sessionPackages = [cfg.package]; 

Amazing job with this project!

error "The option `hardware.graphics` does not exist" on stable `nixosSystem` with unstable `pkgs`

i'm currently running nixpkgs versions separated between my nixosSystem call vs my packages (no minimum repro yet), which i hoped would help keep my system stable while giving the flexibility of trying new stuff.
niri-flake now uses config.system.nixos.release to determine whether it can use graphics.enable, which seemed to under my setup fail.
i'm not sure this is worth investigating as we're all bound to update system, but i figured i'd at least file this here in case others also run into this (and we'd get closer to a repro).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.