From be1545fc17a672a14bb6bc66bd4ecfc7fa2833ff Mon Sep 17 00:00:00 2001 From: Gurjaka Date: Fri, 23 May 2025 19:19:52 +0400 Subject: [PATCH] nixos/dwl: init module --- .../manual/release-notes/rl-2511.section.md | 2 + nixos/modules/module-list.nix | 1 + nixos/modules/programs/wayland/dwl.nix | 104 ++++++++++++++++++ nixos/tests/all-tests.nix | 1 + nixos/tests/dwl.nix | 43 ++++++++ 5 files changed, 151 insertions(+) create mode 100644 nixos/modules/programs/wayland/dwl.nix create mode 100644 nixos/tests/dwl.nix diff --git a/nixos/doc/manual/release-notes/rl-2511.section.md b/nixos/doc/manual/release-notes/rl-2511.section.md index 4bd4cc7ec152..fe8a05a32946 100644 --- a/nixos/doc/manual/release-notes/rl-2511.section.md +++ b/nixos/doc/manual/release-notes/rl-2511.section.md @@ -19,6 +19,8 @@ - [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable). +[dwl](https://codeberg.org/dwl/dwl), a compact, hackable compositor for Wayland based on wlroots. Available as [programs.dwl](#opt-programs.dwl.enable). + ## Backward Incompatibilities {#sec-release-25.11-incompatibilities} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f53efee6a4a9..45004f0e307c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -330,6 +330,7 @@ ./programs/vivid.nix ./programs/wavemon.nix ./programs/wayland/cardboard.nix + ./programs/wayland/dwl.nix ./programs/wayland/gtklock.nix ./programs/wayland/hyprland.nix ./programs/wayland/hyprlock.nix diff --git a/nixos/modules/programs/wayland/dwl.nix b/nixos/modules/programs/wayland/dwl.nix new file mode 100644 index 000000000000..5e3ac932b212 --- /dev/null +++ b/nixos/modules/programs/wayland/dwl.nix @@ -0,0 +1,104 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.programs.dwl; +in +{ + options.programs.dwl = { + enable = lib.mkEnableOption '' + Dwl is a compact, hackable compositor for Wayland based on wlroots. + You can manually launch Dwl by executing "exec dwl" on a TTY. + ''; + + package = lib.mkPackageOption pkgs "dwl" { + example = '' + # Lets apply bar patch from: + # https://codeberg.org/dwl/dwl-patches/src/branch/main/patches/bar + (pkgs.dwl.override { + configH = ./dwl-config.h; + }).overrideAttrs (oldAttrs: { + buildInputs = + oldAttrs.buildInputs or [] + ++ [ + pkgs.libdrm + pkgs.fcft + ]; + patches = oldAttrs.patches or [] ++ [ + ./bar-0.7.patch + ]; + }); + ''; + }; + + extraSessionCommands = lib.mkOption { + default = ""; + type = lib.types.lines; + description = '' + Shell commands executed just before dwl is started. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + # Create systemd target for dwl session + systemd.user.targets.dwl-session = { + description = "dwl compositor session"; + documentation = [ "man:systemd.special(7)" ]; + bindsTo = [ "graphical-session.target" ]; + wants = [ "graphical-session-pre.target" ]; + after = [ "graphical-session-pre.target" ]; + }; + + # Create wrapper script for dwl + environment.etc."xdg/dwl-session" = { + text = '' + #!${pkgs.runtimeShell} + # Import environment variables + ${cfg.extraSessionCommands} + # Setup systemd user environment + systemctl --user import-environment DISPLAY WAYLAND_DISPLAY + systemctl --user start dwl-session.target + # Start dwl + exec ${lib.getExe cfg.package} + ''; + mode = "0755"; # Make it executable + }; + + # Create desktop entry for display managers + services.displayManager.sessionPackages = + let + dwlDesktopFile = pkgs.writeTextFile { + name = "dwl-desktop-entry"; + destination = "/share/wayland-sessions/dwl.desktop"; + text = '' + [Desktop Entry] + Name=dwl + Comment=Dynamic window manager for Wayland + Exec=/etc/xdg/dwl-session + Type=Application + ''; + }; + + dwlSession = pkgs.symlinkJoin { + name = "dwl-session"; + paths = [ dwlDesktopFile ]; + passthru.providedSessions = [ "dwl" ]; + }; + in + [ dwlSession ]; + + # Configure XDG portal for dwl (minimal configuration) + xdg.portal.config.dwl.default = lib.mkDefault [ + "wlr" + "gtk" + ]; + }; + + meta.maintainers = with lib.maintainers; [ gurjaka ]; +} diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index a91b390baa91..43957c03a791 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -412,6 +412,7 @@ in druid = handleTestOn [ "x86_64-linux" ] ./druid { }; drbd-driver = runTest ./drbd-driver.nix; dublin-traceroute = runTest ./dublin-traceroute.nix; + dwl = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./dwl.nix; earlyoom = handleTestOn [ "x86_64-linux" ] ./earlyoom.nix { }; early-mount-options = handleTest ./early-mount-options.nix { }; ec2-config = (handleTestOn [ "x86_64-linux" ] ./ec2.nix { }).boot-ec2-config or { }; diff --git a/nixos/tests/dwl.nix b/nixos/tests/dwl.nix new file mode 100644 index 000000000000..6398ebeba5cf --- /dev/null +++ b/nixos/tests/dwl.nix @@ -0,0 +1,43 @@ +{ lib, ... }: +{ + name = "dwl_test_vm"; + + meta = { + maintainers = with lib.maintainers; [ gurjaka ]; + }; + + nodes.machine = + { + pkgs, + lib, + ... + }: + { + imports = [ + ./common/user-account.nix + ./common/wayland-cage.nix + ]; + + environment.systemPackages = [ pkgs.foot ]; + + services.displayManager.defaultSession = lib.mkForce "dwl"; + + programs.dwl.enable = true; + }; + + testScript = '' + with subtest("ensure dwl starts"): + machine.wait_for_file("/run/user/1000/wayland-0") + + with subtest("ensure foot is installed"): + machine.succeed("which foot") + + with subtest("ensure we can open a new terminal"): + # sleep 3 is required to make sure dwl has started + # TODO: find better way to identify dwl session + machine.sleep(3) + machine.send_key("alt-shift-ret") + machine.sleep(3) + machine.screenshot("terminal") + ''; +}