From 456e599f9101ed153dde268b4401c5d294ba6c8c Mon Sep 17 00:00:00 2001 From: 1444 <54070204+0x5a4@users.noreply.github.com> Date: Wed, 8 Jan 2025 16:18:57 +0100 Subject: [PATCH] wayfire: add module (#6066) Adds a Module for the Wayfire Compositor. Also allows managing the wf-shell configuration. --- modules/misc/news.nix | 15 +- modules/modules.nix | 1 + modules/services/window-managers/wayfire.nix | 200 ++++++++++++++++++ tests/default.nix | 1 + .../window-managers/wayfire/configuration.ini | 10 + .../window-managers/wayfire/configuration.nix | 22 ++ .../window-managers/wayfire/default.nix | 4 + .../window-managers/wayfire/wf-shell.ini | 3 + .../window-managers/wayfire/wf-shell.nix | 25 +++ 9 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 modules/services/window-managers/wayfire.nix create mode 100644 tests/modules/services/window-managers/wayfire/configuration.ini create mode 100644 tests/modules/services/window-managers/wayfire/configuration.nix create mode 100644 tests/modules/services/window-managers/wayfire/default.nix create mode 100644 tests/modules/services/window-managers/wayfire/wf-shell.ini create mode 100644 tests/modules/services/window-managers/wayfire/wf-shell.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 699398de..7a3604be 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -1861,7 +1861,6 @@ in { Some plugins require this to be set to 'false' to function correctly. ''; } - { time = "2024-12-08T17:22:13+00:00"; condition = let @@ -1947,6 +1946,20 @@ in { speed, features, or native UIs. Ghostty provides all three. ''; } + { + time = "2025-01-04T15:00:00+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'wayland.windowManager.wayfire'. + + Wayfire is a 3D Wayland compositor, inspired by Compiz and based on + wlroots. It aims to create a customizable, extendable and lightweight + environment without sacrificing its appearance. + + This Home Manager module allows you to configure both wayfire itself, + as well as wf-shell. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 3c422eb5..2aae09eb 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -405,6 +405,7 @@ let ./services/window-managers/i3-sway/swaynag.nix ./services/window-managers/river.nix ./services/window-managers/spectrwm.nix + ./services/window-managers/wayfire.nix ./services/window-managers/xmonad.nix ./services/wlsunset.nix ./services/wob.nix diff --git a/modules/services/window-managers/wayfire.nix b/modules/services/window-managers/wayfire.nix new file mode 100644 index 00000000..c551eb05 --- /dev/null +++ b/modules/services/window-managers/wayfire.nix @@ -0,0 +1,200 @@ +{ lib, pkgs, config, ... }: { + meta.maintainers = [ lib.maintainers._0x5a4 ]; + + options.wayland.windowManager.wayfire = let + types = lib.types; + + configIniType = with types; + let + primitiveType = either str (either bool number); + sectionType = attrsOf primitiveType; + in attrsOf sectionType; + in { + enable = + lib.mkEnableOption "Wayfire, a wayland compositor based on wlroots"; + + package = lib.mkPackageOption pkgs "wayfire" { + nullable = true; + extraDescription = '' + Set to `null` to not add any wayfire package to your path. + This should be done if you want to use the NixOS wayfire module to install wayfire. + ''; + }; + + plugins = lib.mkOption { + type = lib.types.listOf lib.types.package; + default = with pkgs.wayfirePlugins; [ wf-shell ]; + defaultText = + lib.literalExpression "with pkgs.wayfirePlugins; [ wf-shell ]"; + example = lib.literalExpression '' + with pkgs.wayfirePlugins; [ + wcm + wf-shell + wayfire-plugins-extra + ]; + ''; + description = '' + Additional plugins to use with wayfire + ''; + }; + + xwayland.enable = lib.mkEnableOption "XWayland" // { default = true; }; + + settings = lib.mkOption { + type = types.submodule { + freeformType = configIniType; + + options.core.plugins = lib.mkOption { + type = types.separatedString " "; + description = "Load the specified plugins"; + }; + }; + default = { }; + description = '' + Wayfire configuration written in Nix. + + See + ''; + example = lib.literalExpression '' + { + core.plugins = "command expo cube"; + command = { + binding_terminal = "alacritty"; + command_terminal = "alacritty"; + }; + } + ''; + }; + + wf-shell = { + enable = lib.mkEnableOption "Manage wf-shell Configuration"; + + package = lib.mkPackageOption pkgs.wayfirePlugins "wf-shell" { }; + + settings = lib.mkOption { + type = configIniType; + default = { }; + description = '' + Wf-shell configuration written in Nix. + + See + ''; + example = lib.literalExpression '' + { + panel = { + widgets_left = "menu spacing4 launchers window-list"; + autohide = true; + }; + } + ''; + }; + }; + + systemd = { + enable = lib.mkEnableOption null // { + default = true; + description = '' + Whether to enable {file}`wayfire-session.target` on + wayfire startup. This links to {file}`graphical-session.target`}. + Some important environment variables will be imported to systemd + and D-Bus user environment before reaching the target, including + - `DISPLAY` + - `WAYLAND_DISPLAY` + - `XDG_CURRENT_DESKTOP` + - `NIXOS_OZONE_WL` + - `XCURSOR_THEME` + - `XCURSOR_SIZE` + ''; + }; + + variables = lib.mkOption { + type = types.listOf types.str; + default = [ + "DISPLAY" + "WAYLAND_DISPLAY" + "XDG_CURRENT_DESKTOP" + "NIXOS_OZONE_WL" + "XCURSOR_THEME" + "XCURSOR_SIZE" + ]; + example = [ "-all" ]; + description = '' + Environment variables to be imported in the systemd & D-Bus user + environment. + ''; + }; + + extraCommands = lib.mkOption { + type = types.listOf types.str; + default = [ + "systemctl --user stop wayfire-session.target" + "systemctl --user start wayfire-session.target" + ]; + description = "Extra commands to be run after D-Bus activation."; + }; + }; + }; + + config = let + cfg = config.wayland.windowManager.wayfire; + + variables = builtins.concatStringsSep " " cfg.systemd.variables; + extraCommands = builtins.concatStringsSep " " + (map (f: "&& ${f}") cfg.systemd.extraCommands); + systemdActivation = + "${pkgs.dbus}/bin/dbus-update-activation-environment --systemd ${variables} ${extraCommands}"; + + finalPackage = pkgs.wayfire-with-plugins.override { + wayfire = cfg.package; + plugins = cfg.plugins; + }; + in lib.mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "wayland.windowManager.wayfire" pkgs + lib.platforms.linux) + ]; + + home.packages = lib.mkIf (cfg.package != null) (lib.concatLists [ + (lib.singleton finalPackage) + (lib.optional (cfg.xwayland.enable) pkgs.xwayland) + ]); + + wayland.windowManager.wayfire = { + settings = { + autostart = lib.mkIf cfg.systemd.enable { inherit systemdActivation; }; + core = { + plugins = lib.concatStringsSep " " (lib.concatLists [ + (lib.optional (cfg.systemd.enable) "autostart") + (lib.optional (cfg.wf-shell.enable) "wayfire-shell") + ]); + xwayland = cfg.xwayland.enable; + }; + }; + + plugins = lib.optional cfg.wf-shell.enable cfg.wf-shell.package; + }; + + xdg.configFile."wayfire.ini".text = lib.generators.toINI { } cfg.settings; + + xdg.configFile."wf-shell.ini" = lib.mkIf cfg.wf-shell.enable { + text = lib.generators.toINI { } cfg.wf-shell.settings; + }; + + systemd.user.targets.wayfire-session = lib.mkIf cfg.systemd.enable { + Unit = { + Description = "wayfire compositor session"; + Documentation = [ "man:systemd.special(7)" ]; + BindsTo = [ "graphical-session.target" ]; + Wants = [ "graphical-session-pre.target" ]; + After = [ "graphical-session-pre.target" ]; + }; + }; + + systemd.user.targets.tray = { + Unit = { + Description = "Home Manager System Tray"; + Requires = [ "graphical-session-pre.target" ]; + }; + }; + }; +} diff --git a/tests/default.nix b/tests/default.nix index 3530138d..b95cd16a 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -302,6 +302,7 @@ in import nmtSrc { ./modules/services/window-managers/river ./modules/services/window-managers/spectrwm ./modules/services/window-managers/sway + ./modules/services/window-managers/wayfire ./modules/services/wlsunset ./modules/services/wob ./modules/services/xsettingsd diff --git a/tests/modules/services/window-managers/wayfire/configuration.ini b/tests/modules/services/window-managers/wayfire/configuration.ini new file mode 100644 index 00000000..a4048041 --- /dev/null +++ b/tests/modules/services/window-managers/wayfire/configuration.ini @@ -0,0 +1,10 @@ +[autostart] +systemdActivation=/nix/store/00000000000000000000000000000000-dbus/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP NIXOS_OZONE_WL XCURSOR_THEME XCURSOR_SIZE && systemctl --user stop wayfire-session.target && systemctl --user start wayfire-session.target + +[command] +binding_terminal=alacritty +command_terminal=alacritty + +[core] +plugins=command expo cube autostart +xwayland=true diff --git a/tests/modules/services/window-managers/wayfire/configuration.nix b/tests/modules/services/window-managers/wayfire/configuration.nix new file mode 100644 index 00000000..07042329 --- /dev/null +++ b/tests/modules/services/window-managers/wayfire/configuration.nix @@ -0,0 +1,22 @@ +{ ... }: { + wayland.windowManager.wayfire = { + enable = true; + package = null; + settings = { + core.plugins = "command expo cube"; + command = { + binding_terminal = "alacritty"; + command_terminal = "alacritty"; + }; + }; + }; + + nmt.script = '' + wayfireConfig=home-files/.config/wayfire.ini + + assertFileExists "$wayfireConfig" + + normalizedConfig=$(normalizeStorePaths "$wayfireConfig") + assertFileContent "$normalizedConfig" "${./configuration.ini}" + ''; +} diff --git a/tests/modules/services/window-managers/wayfire/default.nix b/tests/modules/services/window-managers/wayfire/default.nix new file mode 100644 index 00000000..0e252bb1 --- /dev/null +++ b/tests/modules/services/window-managers/wayfire/default.nix @@ -0,0 +1,4 @@ +{ + wayfire-configuration = ./configuration.nix; + wayfire-wf-shell = ./wf-shell.nix; +} diff --git a/tests/modules/services/window-managers/wayfire/wf-shell.ini b/tests/modules/services/window-managers/wayfire/wf-shell.ini new file mode 100644 index 00000000..02472a68 --- /dev/null +++ b/tests/modules/services/window-managers/wayfire/wf-shell.ini @@ -0,0 +1,3 @@ +[panel] +autohide=true +widgets_left=menu spacing4 launchers window-list diff --git a/tests/modules/services/window-managers/wayfire/wf-shell.nix b/tests/modules/services/window-managers/wayfire/wf-shell.nix new file mode 100644 index 00000000..2c8221d8 --- /dev/null +++ b/tests/modules/services/window-managers/wayfire/wf-shell.nix @@ -0,0 +1,25 @@ +{ pkgs, ... }: { + wayland.windowManager.wayfire = { + enable = true; + package = null; + wf-shell = { + enable = true; + package = pkgs.mkStubPackage { }; + settings = { + panel = { + widgets_left = "menu spacing4 launchers window-list"; + autohide = true; + }; + }; + }; + }; + + nmt.script = '' + wfShellConfig=home-files/.config/wf-shell.ini + + assertFileExists "$wfShellConfig" + + normalizedConfig=$(normalizeStorePaths "$wfShellConfig") + assertFileContent "$normalizedConfig" "${./wf-shell.ini}" + ''; +}