diff --git a/nixos/modules/programs/sway.nix b/nixos/modules/programs/sway.nix index d685a5259324..e2a4018e9023 100644 --- a/nixos/modules/programs/sway.nix +++ b/nixos/modules/programs/sway.nix @@ -4,27 +4,32 @@ with lib; let cfg = config.programs.sway; - swayPackage = pkgs.sway; - swayWrapped = pkgs.writeShellScriptBin "sway" '' - set -o errexit + wrapperOptions = types.submodule { + options = + let + mkWrapperFeature = default: description: mkOption { + type = types.bool; + inherit default; + example = !default; + description = "Whether to make use of the ${description}"; + }; + in { + base = mkWrapperFeature true '' + base wrapper to execute extra session commands and prepend a + dbus-run-session to the sway command. + ''; + gtk = mkWrapperFeature false '' + wrapGAppsHook wrapper to execute sway with required environment + variables for GTK applications. + ''; + }; + }; - if [ ! "$_SWAY_WRAPPER_ALREADY_EXECUTED" ]; then - export _SWAY_WRAPPER_ALREADY_EXECUTED=1 - ${cfg.extraSessionCommands} - fi - - if [ "$DBUS_SESSION_BUS_ADDRESS" ]; then - export DBUS_SESSION_BUS_ADDRESS - exec ${swayPackage}/bin/sway "$@" - else - exec ${pkgs.dbus}/bin/dbus-run-session ${swayPackage}/bin/sway "$@" - fi - ''; - swayJoined = pkgs.symlinkJoin { - name = "sway-joined"; - paths = [ swayWrapped swayPackage ]; - passthru.providedSessions = [ "sway" ]; + swayPackage = pkgs.sway.override { + extraSessionCommands = cfg.extraSessionCommands; + withBaseWrapper = cfg.wrapperFeatures.base; + withGtkWrapper = cfg.wrapperFeatures.gtk; }; in { options.programs.sway = { @@ -36,6 +41,15 @@ in { Please have a look at the "extraSessionCommands" example for running programs natively under Wayland''; + wrapperFeatures = mkOption { + type = wrapperOptions; + default = { }; + example = { gtk = true; }; + description = '' + Attribute set of features to enable in the wrapper. + ''; + }; + extraSessionCommands = mkOption { type = types.lines; default = ""; @@ -56,7 +70,7 @@ in { extraPackages = mkOption { type = with types; listOf package; default = with pkgs; [ - swaylock swayidle swaybg + swaylock swayidle xwayland rxvt_unicode dmenu ]; defaultText = literalExample '' @@ -76,8 +90,17 @@ in { }; config = mkIf cfg.enable { + assertions = [ + { + assertion = cfg.extraSessionCommands != "" -> cfg.wrapperFeatures.base; + message = '' + The extraSessionCommands for Sway will not be run if + wrapperFeatures.base is disabled. + ''; + } + ]; environment = { - systemPackages = [ swayJoined ] ++ cfg.extraPackages; + systemPackages = [ swayPackage ] ++ cfg.extraPackages; etc = { "sway/config".source = mkOptionDefault "${swayPackage}/etc/sway/config"; #"sway/security.d".source = mkOptionDefault "${swayPackage}/etc/sway/security.d/"; @@ -89,7 +112,7 @@ in { fonts.enableDefaultFonts = mkDefault true; programs.dconf.enable = mkDefault true; # To make a Sway session available if a display manager like SDDM is enabled: - services.xserver.displayManager.sessionPackages = [ swayJoined ]; + services.xserver.displayManager.sessionPackages = [ swayPackage ]; }; meta.maintainers = with lib.maintainers; [ gnidorah primeos colemickens ]; diff --git a/pkgs/applications/window-managers/sway/default.nix b/pkgs/applications/window-managers/sway/default.nix index 215a576a578c..6b4c33dc0771 100644 --- a/pkgs/applications/window-managers/sway/default.nix +++ b/pkgs/applications/window-managers/sway/default.nix @@ -3,11 +3,11 @@ , pkgconfig, scdoc , wayland, libxkbcommon, pcre, json_c, dbus, libevdev , pango, cairo, libinput, libcap, pam, gdk-pixbuf -, wlroots, wayland-protocols, swaybg +, wlroots, wayland-protocols }: stdenv.mkDerivation rec { - pname = "sway"; + pname = "sway-unwrapped"; version = "1.2"; src = fetchFromGitHub { @@ -22,7 +22,9 @@ stdenv.mkDerivation rec { ./load-configuration-from-etc.patch ]; - nativeBuildInputs = [ pkgconfig meson ninja scdoc makeWrapper ]; + nativeBuildInputs = [ + pkgconfig meson ninja scdoc + ]; buildInputs = [ wayland libxkbcommon pcre json_c dbus libevdev @@ -37,10 +39,6 @@ stdenv.mkDerivation rec { "-Dtray=enabled" "-Dman-pages=enabled" ]; - postInstall = '' - wrapProgram $out/bin/sway --prefix PATH : "${swaybg}/bin" - ''; - meta = with stdenv.lib; { description = "i3-compatible tiling Wayland compositor"; homepage = https://swaywm.org; diff --git a/pkgs/applications/window-managers/sway/wrapper.nix b/pkgs/applications/window-managers/sway/wrapper.nix new file mode 100644 index 000000000000..bd59ac5fa459 --- /dev/null +++ b/pkgs/applications/window-managers/sway/wrapper.nix @@ -0,0 +1,50 @@ +{ lib, stdenv +, sway-unwrapped, swaybg +, makeWrapper, symlinkJoin, writeShellScriptBin +, withBaseWrapper ? true, extraSessionCommands ? "", dbus +, withGtkWrapper ? false, wrapGAppsHook, gdk-pixbuf +}: + +assert extraSessionCommands != "" -> withBaseWrapper; + +with lib; + +let + baseWrapper = writeShellScriptBin "sway" '' + set -o errexit + if [ ! "$_SWAY_WRAPPER_ALREADY_EXECUTED" ]; then + export _SWAY_WRAPPER_ALREADY_EXECUTED=1 + ${extraSessionCommands} + fi + if [ "$DBUS_SESSION_BUS_ADDRESS" ]; then + export DBUS_SESSION_BUS_ADDRESS + exec ${sway-unwrapped}/bin/sway "$@" + else + exec ${dbus}/bin/dbus-run-session ${sway-unwrapped}/bin/sway "$@" + fi + ''; +in symlinkJoin { + name = "sway-${sway-unwrapped.version}"; + + paths = (optional withBaseWrapper baseWrapper) + ++ [ sway-unwrapped ]; + + nativeBuildInputs = [ makeWrapper ] + ++ (optional withGtkWrapper wrapGAppsHook); + + buildInputs = optional withGtkWrapper gdk-pixbuf; + + postBuild = '' + # We want to run wrapProgram manually to only wrap sway and add swaybg: + export dontWrapGApps=true + ${optionalString withGtkWrapper "wrapGAppsHook"} + wrapProgram $out/bin/sway \ + --prefix PATH : "${swaybg}/bin" ${optionalString withGtkWrapper ''\ + "''${gappsWrapperArgs[@]}" + ''} + ''; + + passthru.providedSessions = [ "sway" ]; + + inherit (sway-unwrapped) meta; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e89c6f596baa..4ac09a4e2b77 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -19373,7 +19373,8 @@ in wlroots = callPackage ../development/libraries/wlroots { }; - sway = callPackage ../applications/window-managers/sway { }; + sway-unwrapped = callPackage ../applications/window-managers/sway { }; + sway = callPackage ../applications/window-managers/sway/wrapper.nix { }; swaybg = callPackage ../applications/window-managers/sway/bg.nix { }; swayidle = callPackage ../applications/window-managers/sway/idle.nix { }; swaylock = callPackage ../applications/window-managers/sway/lock.nix { };