Unverified Commit b8024284 authored by Masum Reza's avatar Masum Reza Committed by GitHub
Browse files

Merge pull request #335625 from JohnRTitor/uwsm-module

nixos/uwsm: init
parents 1fb03d03 93343775
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@

- [Goatcounter](https://www.goatcounter.com/), Easy web analytics. No tracking of personal data. Available as [services.goatcounter](options.html#opt-services.goatcocunter.enable).

- [UWSM](https://github.com/Vladimir-csp/uwsm), a wayland session manager to wrap Wayland Compositors into useful systemd units such as `graphical-session.target`. Available as [programs.uwsm](#opt-programs.uwsm.enable).

- [Open-WebUI](https://github.com/open-webui/open-webui), a user-friendly WebUI
  for LLMs. Available as [services.open-webui](#opt-services.open-webui.enable)
  service.
+1 −0
Original line number Diff line number Diff line
@@ -310,6 +310,7 @@
  ./programs/wayland/miracle-wm.nix
  ./programs/wayland/river.nix
  ./programs/wayland/sway.nix
  ./programs/wayland/uwsm.nix
  ./programs/wayland/waybar.nix
  ./programs/wayland/wayfire.nix
  ./programs/weylus.nix
+129 −0
Original line number Diff line number Diff line
{
  config,
  lib,
  pkgs,
  ...
}:
let
  cfg = config.programs.uwsm;

  # Helper function to create desktop entry files for UWSM-managed compositors
  mk_uwsm_desktop_entry =
    opts:
    (pkgs.writeTextFile {
      name = "${opts.name}-uwsm";
      text = ''
        [Desktop Entry]
        Name=${opts.prettyName} (UWSM)
        Comment=${opts.comment}
        Exec=${lib.getExe cfg.package} start -S -F ${opts.binPath}
        Type=Application
      '';
      destination = "/share/wayland-sessions/${opts.name}-uwsm.desktop";
      derivationArgs = {
        passthru.providedSessions = [ "${opts.name}-uwsm" ];
      };
    });
in
{
  options.programs.uwsm = {
    enable = lib.mkEnableOption ''
      uwsm, which wraps standalone Wayland compositors with a set
      of Systemd units on the fly. This essentially
      binds the wayland compositor into `graphical-session-pre.target`,
      `graphical-session.target`, `xdg-desktop-autostart.target`.

      This is useful for Wayland compositors like Hyprland, Sway, Wayfire,
      etc. that do not start these targets and services on their own.

      ::: {.note}
      You must configure `waylandCompositors` suboptions as well
      so that UWSM knows which compositors to manage.

      Additionally, this by default uses `dbus-broker` as the dbus
      implementation for better compatibility. If you dislike this behavior
      you can set `services.dbus.implementation = lib.mkForce "dbus"`
      in your configuration.
      :::

      If you are having trouble starting a service that depends on
      `graphical-session.target`, while using a WM, enabling this option
      might help
    '';
    package = lib.mkPackageOption pkgs "uwsm" { };

    waylandCompositors = lib.mkOption {
      description = ''
        Configuration for UWSM-managed Wayland Compositors. This
        creates a desktop entry file which will be used by Display
        Managers like GDM, to allow starting the UWSM managed session.
      '';
      type = lib.types.attrsOf (
        lib.types.submodule (
          { ... }:
          {
            options = {
              prettyName = lib.mkOption {
                type = lib.types.str;
                description = "The full name of the desktop entry file.";
                example = "ExampleWaylandCompositor";
              };
              comment = lib.mkOption {
                type = lib.types.str;
                description = "The comment field of the desktop entry file.";
                default = "An intelligent Wayland compositor managed by UWSM.";
              };
              binPath = lib.mkOption {
                type = lib.types.path;
                description = ''
                  The wayland-compositor binary path that will be called by UWSM.

                  It is recommended to use the `/run/current-system/sw/bin/` path
                  instead of `lib.getExe pkgs.<compositor>` to avoid version mismatch
                  of the compositor used by UWSM and the one installed in the system.
                '';
                example = "/run/current-system/sw/bin/ExampleCompositor";
              };
            };
          }
        )
      );
      example = lib.literalExpression ''
        hyprland = {
          prettyName = "Hyprland";
          comment = "Hyprland compositor managed by UWSM";
          binPath = "/run/current-system/sw/bin/Hyprland";
        };
        sway = {
          prettyName = "Sway";
          comment = "Sway compositor managed by UWSM";
          binPath = "/run/current-system/sw/bin/sway";
        };
      '';
    };
  };

  config = lib.mkIf cfg.enable {
    environment.systemPackages = [ cfg.package ];
    systemd.packages = [ cfg.package ];
    environment.pathsToLink = [ "/share/uwsm" ];

    services.graphical-desktop.enable = true;

    # UWSM recommends dbus broker for better compatibility
    services.dbus.implementation = "broker";

    services.displayManager.sessionPackages = lib.mapAttrsToList (
      name: value:
      mk_uwsm_desktop_entry {
        inherit name;
        inherit (value) prettyName comment binPath;
      }
    ) cfg.waylandCompositors;
  };

  meta.maintainers = with lib.maintainers; [
    johnrtitor
    kai-tub
  ];
}