nixpkgs/nixos/modules/programs/wayland/uwsm.nix
John Titor 93343775bd
nixos/uwsm: init
[UWSM](https://github.com/Vladimir-csp/uwsm) is a session manager that wraps a wayland
window compositor with useful systemd units like `graphical-session-pre.target`,
`graphical-session.target`, `xdg-desktop-autostart.target`.

This is useful for Wayland Compositors that do not start
these units on these own.

Example for Hyprland:
```nix
programs.hyprland.enable = true;
programs.uwsm.enable = true;
programs.uwsm.waylandCompositors = {
  hyprland = {
    compositorPrettyName = "Hyprland";
    compositorComment = "Hyprland compositor managed by UWSM";
    compositorBinPath = "/run/current-system/sw/bin/Hyprland";
  };
};
```

Co-authored-by: Kai Norman Clasen <k.clasen@protonmail.com>
2024-08-21 16:09:54 +05:30

130 lines
4.1 KiB
Nix

{
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
];
}