diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 2c9d1aa568bf..6ef1d8d53798 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -867,6 +867,7 @@ in { swap-partition = handleTest ./swap-partition.nix {}; swap-random-encryption = handleTest ./swap-random-encryption.nix {}; sway = handleTest ./sway.nix {}; + swayfx = handleTest ./swayfx.nix {}; switchTest = handleTest ./switch-test.nix {}; sympa = handleTest ./sympa.nix {}; syncthing = handleTest ./syncthing.nix {}; diff --git a/nixos/tests/swayfx.nix b/nixos/tests/swayfx.nix new file mode 100644 index 000000000000..77844ec80ae1 --- /dev/null +++ b/nixos/tests/swayfx.nix @@ -0,0 +1,207 @@ +import ./make-test-python.nix ( + { pkgs, lib, ... }: + { + name = "swayfx"; + meta = { + maintainers = with lib.maintainers; [ eclairevoyant ]; + }; + + # testScriptWithTypes:49: error: Cannot call function of unknown type + # (machine.succeed if succeed else machine.execute)( + # ^ + # Found 1 error in 1 file (checked 1 source file) + skipTypeCheck = true; + + nodes.machine = + { config, ... }: + { + # Automatically login on tty1 as a normal user: + imports = [ ./common/user-account.nix ]; + services.getty.autologinUser = "alice"; + + environment = { + # For glinfo and wayland-info: + systemPackages = with pkgs; [ + mesa-demos + wayland-utils + alacritty + ]; + # Use a fixed SWAYSOCK path (for swaymsg): + variables = { + "SWAYSOCK" = "/tmp/sway-ipc.sock"; + # TODO: Investigate if we can get hardware acceleration to work (via + # virtio-gpu and Virgil). We currently have to use the Pixman software + # renderer since the GLES2 renderer doesn't work inside the VM (even + # with WLR_RENDERER_ALLOW_SOFTWARE): + # "WLR_RENDERER_ALLOW_SOFTWARE" = "1"; + "WLR_RENDERER" = "pixman"; + }; + # For convenience: + shellAliases = { + test-x11 = "glinfo | tee /tmp/test-x11.out && touch /tmp/test-x11-exit-ok"; + test-wayland = "wayland-info | tee /tmp/test-wayland.out && touch /tmp/test-wayland-exit-ok"; + }; + + # To help with OCR: + etc."xdg/foot/foot.ini".text = lib.generators.toINI { } { + main = { + font = "inconsolata:size=14"; + }; + colors = rec { + foreground = "000000"; + background = "ffffff"; + regular2 = foreground; + }; + }; + + etc."gpg-agent.conf".text = '' + pinentry-timeout 86400 + ''; + }; + + fonts.packages = [ pkgs.inconsolata ]; + + # Automatically configure and start Sway when logging in on tty1: + programs.bash.loginShellInit = '' + if [ "$(tty)" = "/dev/tty1" ]; then + set -e + + mkdir -p ~/.config/sway + sed s/Mod4/Mod1/ /etc/sway/config > ~/.config/sway/config + + sway --validate + sway && touch /tmp/sway-exit-ok + fi + ''; + + programs.sway = { + enable = true; + package = pkgs.swayfx.override { isNixOS = true; }; + }; + + # To test pinentry via gpg-agent: + programs.gnupg.agent.enable = true; + + # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch: + virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci" ]; + }; + + testScript = + { nodes, ... }: + '' + import shlex + import json + + q = shlex.quote + NODE_GROUPS = ["nodes", "floating_nodes"] + + + def swaymsg(command: str = "", succeed=True, type="command"): + assert command != "" or type != "command", "Must specify command or type" + shell = q(f"swaymsg -t {q(type)} -- {q(command)}") + with machine.nested( + f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed) + ): + ret = (machine.succeed if succeed else machine.execute)( + f"su - alice -c {shell}" + ) + + # execute also returns a status code, but disregard. + if not succeed: + _, ret = ret + + if not succeed and not ret: + return None + + parsed = json.loads(ret) + return parsed + + + def walk(tree): + yield tree + for group in NODE_GROUPS: + for node in tree.get(group, []): + yield from walk(node) + + + def wait_for_window(pattern): + def func(last_chance): + nodes = (node["name"] for node in walk(swaymsg(type="get_tree"))) + + if last_chance: + nodes = list(nodes) + machine.log(f"Last call! Current list of windows: {nodes}") + + return any(pattern in name for name in nodes) + + retry(func) + + start_all() + machine.wait_for_unit("multi-user.target") + + # To check the version: + print(machine.succeed("sway --version")) + + # Wait for Sway to complete startup: + machine.wait_for_file("/run/user/1000/wayland-1") + machine.wait_for_file("/tmp/sway-ipc.sock") + + # Test XWayland (foot does not support X): + swaymsg("exec WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY= alacritty") + wait_for_window("alice@machine") + machine.send_chars("test-x11\n") + machine.wait_for_file("/tmp/test-x11-exit-ok") + print(machine.succeed("cat /tmp/test-x11.out")) + machine.copy_from_vm("/tmp/test-x11.out") + machine.screenshot("alacritty_glinfo") + machine.succeed("pkill alacritty") + + # Start a terminal (foot) on workspace 3: + machine.send_key("alt-3") + machine.sleep(3) + machine.send_key("alt-ret") + wait_for_window("alice@machine") + machine.send_chars("test-wayland\n") + machine.wait_for_file("/tmp/test-wayland-exit-ok") + print(machine.succeed("cat /tmp/test-wayland.out")) + machine.copy_from_vm("/tmp/test-wayland.out") + machine.screenshot("foot_wayland_info") + machine.send_key("alt-shift-q") + machine.wait_until_fails("pgrep foot") + + # Test gpg-agent starting pinentry-gnome3 via D-Bus (tests if + # $WAYLAND_DISPLAY is correctly imported into the D-Bus user env): + swaymsg("exec mkdir -p ~/.gnupg") + swaymsg("exec cp /etc/gpg-agent.conf ~/.gnupg") + + swaymsg("exec DISPLAY=INVALID gpg --no-tty --yes --quick-generate-key test", succeed=False) + machine.wait_until_succeeds("pgrep --exact gpg") + wait_for_window("gpg") + machine.succeed("pgrep --exact gpg") + machine.screenshot("gpg_pinentry") + machine.send_key("alt-shift-q") + machine.wait_until_fails("pgrep --exact gpg") + + # Test swaynag: + def get_height(): + return [node['rect']['height'] for node in walk(swaymsg(type="get_tree")) if node['focused']][0] + + before = get_height() + machine.send_key("alt-shift-e") + retry(lambda _: get_height() < before) + machine.screenshot("sway_exit") + + swaymsg("exec swaylock") + machine.wait_until_succeeds("pgrep -x swaylock") + machine.sleep(3) + machine.send_chars("${nodes.machine.config.users.users.alice.password}") + machine.send_key("ret") + machine.wait_until_fails("pgrep -x swaylock") + + # Exit Sway and verify process exit status 0: + swaymsg("exit", succeed=False) + machine.wait_until_fails("pgrep -x sway") + machine.wait_for_file("/tmp/sway-exit-ok") + ''; + } +) diff --git a/pkgs/by-name/sc/scenefx/package.nix b/pkgs/by-name/sc/scenefx/package.nix new file mode 100644 index 000000000000..c9b50e5af047 --- /dev/null +++ b/pkgs/by-name/sc/scenefx/package.nix @@ -0,0 +1,64 @@ +{ + lib, + stdenv, + fetchFromGitHub, + meson, + ninja, + wlroots, + scdoc, + pkg-config, + wayland, + libdrm, + libxkbcommon, + pixman, + wayland-protocols, + libGL, + mesa, + validatePkgConfig, + testers, +}: + +stdenv.mkDerivation (finalAttrs: { + pname = "scenefx"; + version = "0.1"; + + src = fetchFromGitHub { + owner = "wlrfx"; + repo = "scenefx"; + rev = "refs/tags/${finalAttrs.version}"; + hash = "sha256-vBmunqXwGbMNiGRd372TdMU4siWhIVYn5RVYne9C7uQ="; + }; + + strictDeps = true; + + nativeBuildInputs = [ + meson + ninja + pkg-config + scdoc + validatePkgConfig + ]; + + buildInputs = [ + libdrm + libGL + libxkbcommon + mesa + pixman + wayland + wayland-protocols + wlroots + ]; + + passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; + + meta = { + description = "A drop-in replacement for the wlroots scene API that allows wayland compositors to render surfaces with eye-candy effects"; + homepage = "https://github.com/wlrfx/scenefx"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ eclairevoyant ]; + mainProgram = "scenefx"; + pkgConfigModules = [ "scenefx" ]; + platforms = lib.platforms.all; + }; +}) diff --git a/pkgs/by-name/sw/sway-unwrapped/package.nix b/pkgs/by-name/sw/sway-unwrapped/package.nix index 04563b800ba9..8a747f8e1947 100644 --- a/pkgs/by-name/sw/sway-unwrapped/package.nix +++ b/pkgs/by-name/sw/sway-unwrapped/package.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, fetchFromGitHub, fetchpatch, substituteAll, swaybg +{ lib, stdenv, fetchFromGitHub, substituteAll, swaybg , meson, ninja, pkg-config, wayland-scanner, scdoc , libGL, wayland, libxkbcommon, pcre2, json_c, libevdev , pango, cairo, libinput, gdk-pixbuf, librsvg @@ -60,6 +60,8 @@ stdenv.mkDerivation (finalAttrs: { ]; mesonFlags = let + inherit (lib.strings) mesonEnable mesonOption; + # The "sd-bus-provider" meson option does not include a "none" option, # but it is silently ignored iff "-Dtray=disabled". We use "basu" # (which is not in nixpkgs) instead of "none" to alert us if this @@ -67,15 +69,15 @@ stdenv.mkDerivation (finalAttrs: { # assert trayEnabled -> systemdSupport && dbusSupport; sd-bus-provider = if systemdSupport then "libsystemd" else "basu"; - in - [ "-Dsd-bus-provider=${sd-bus-provider}" ] - ++ lib.optional (!finalAttrs.enableXWayland) "-Dxwayland=disabled" - ++ lib.optional (!finalAttrs.trayEnabled) "-Dtray=disabled" - ; + in [ + (mesonOption "sd-bus-provider" sd-bus-provider) + (mesonEnable "xwayland" finalAttrs.enableXWayland) + (mesonEnable "tray" finalAttrs.trayEnabled) + ]; passthru.tests.basic = nixosTests.sway; - meta = with lib; { + meta = { description = "An i3-compatible tiling Wayland compositor"; longDescription = '' Sway is a tiling Wayland compositor and a drop-in replacement for the i3 @@ -88,9 +90,9 @@ stdenv.mkDerivation (finalAttrs: { ''; homepage = "https://swaywm.org"; changelog = "https://github.com/swaywm/sway/releases/tag/${finalAttrs.version}"; - license = licenses.mit; - platforms = platforms.linux; - maintainers = with maintainers; [ primeos synthetica ]; + license = lib.licenses.mit; + platforms = lib.platforms.linux; + maintainers = with lib.maintainers; [ primeos synthetica ]; mainProgram = "sway"; }; }) diff --git a/pkgs/by-name/sw/sway/package.nix b/pkgs/by-name/sw/sway/package.nix index 3e9ed51613f8..2ae6d3ed0154 100644 --- a/pkgs/by-name/sw/sway/package.nix +++ b/pkgs/by-name/sw/sway/package.nix @@ -13,9 +13,12 @@ assert extraSessionCommands != "" -> withBaseWrapper; -with lib; - let + inherit (builtins) replaceStrings; + inherit (lib.lists) optional optionals; + inherit (lib.meta) getExe; + inherit (lib.strings) concatMapStrings optionalString; + sway = sway-unwrapped.overrideAttrs (oa: { inherit isNixOS enableXWayland; }); baseWrapper = writeShellScriptBin sway.meta.mainProgram '' set -o errexit @@ -26,13 +29,13 @@ let fi if [ "$DBUS_SESSION_BUS_ADDRESS" ]; then export DBUS_SESSION_BUS_ADDRESS - exec ${lib.getExe sway} "$@" + exec ${getExe sway} "$@" else - exec ${lib.optionalString dbusSupport "${dbus}/bin/dbus-run-session"} ${lib.getExe sway} "$@" + exec ${optionalString dbusSupport "${dbus}/bin/dbus-run-session"} ${getExe sway} "$@" fi ''; in symlinkJoin rec { - pname = lib.replaceStrings ["-unwrapped"] [""] sway.pname; + pname = replaceStrings ["-unwrapped"] [""] sway.pname; inherit (sway) version; name = "${pname}-${version}"; diff --git a/pkgs/by-name/sw/swayfx-unwrapped/fix-paths.patch b/pkgs/by-name/sw/swayfx-unwrapped/fix-paths.patch new file mode 100644 index 000000000000..c52f65b146b7 --- /dev/null +++ b/pkgs/by-name/sw/swayfx-unwrapped/fix-paths.patch @@ -0,0 +1,11 @@ +--- a/sway/config.c ++++ b/sway/config.c +@@ -276,7 +276,7 @@ + + if (!(config->active_bar_modifiers = create_list())) goto cleanup; + +- if (!(config->swaybg_command = strdup("swaybg"))) goto cleanup; ++ if (!(config->swaybg_command = strdup("@swaybg@/bin/swaybg"))) goto cleanup; + + if (!(config->config_chain = create_list())) goto cleanup; + config->current_config_path = NULL; diff --git a/pkgs/by-name/sw/swayfx-unwrapped/load-configuration-from-etc.patch b/pkgs/by-name/sw/swayfx-unwrapped/load-configuration-from-etc.patch new file mode 100644 index 000000000000..46a170abc04a --- /dev/null +++ b/pkgs/by-name/sw/swayfx-unwrapped/load-configuration-from-etc.patch @@ -0,0 +1,48 @@ +From 92283df3acbffa5c1bb21f23cdd686113d905114 Mon Sep 17 00:00:00 2001 +From: Patrick Hilhorst +Date: Wed, 31 Mar 2021 21:14:13 +0200 +Subject: [PATCH] Load configs from /etc but fallback to /nix/store + +This change will load all configuration files from /etc, to make it easy +to override them, but fallback to /nix/store/.../etc/sway/config to make +Sway work out-of-the-box with the default configuration on non NixOS +systems. + +Original patch by Michael Weiss, updated for Sway 1.6 by Patrick Hilhorst + +Co-authored-by: Michael Weiss +--- + meson.build | 3 ++- + sway/config.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/meson.build b/meson.build +index b7a29660..8ae8ceb3 100644 +--- a/meson.build ++++ b/meson.build +@@ -164,7 +164,8 @@ if scdoc.found() + endforeach + endif + +-add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c') ++add_project_arguments('-DSYSCONFDIR="/@0@"'.format(sysconfdir), language : 'c') ++add_project_arguments('-DNIX_SYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir)), language : 'c') + + version = '"@0@"'.format(meson.project_version()) + git = find_program('git', native: true, required: false) +diff --git a/sway/config.c b/sway/config.c +index 76b9ec08..fb5b51aa 100644 +--- a/sway/config.c ++++ b/sway/config.c +@@ -374,7 +374,8 @@ static char *get_config_path(void) { + { .prefix = home, .config_folder = ".i3"}, + { .prefix = config_home, .config_folder = "i3"}, + { .prefix = SYSCONFDIR, .config_folder = "sway"}, +- { .prefix = SYSCONFDIR, .config_folder = "i3"} ++ { .prefix = SYSCONFDIR, .config_folder = "i3"}, ++ { .prefix = NIX_SYSCONFDIR, .config_folder = "sway"}, + }; + + size_t num_config_paths = sizeof(config_paths)/sizeof(config_paths[0]); +-- +2.30.1 diff --git a/pkgs/by-name/sw/swayfx-unwrapped/package.nix b/pkgs/by-name/sw/swayfx-unwrapped/package.nix index dfbb2e540c53..b90220a7c1ff 100644 --- a/pkgs/by-name/sw/swayfx-unwrapped/package.nix +++ b/pkgs/by-name/sw/swayfx-unwrapped/package.nix @@ -1,10 +1,33 @@ { lib, fetchFromGitHub, - sway-unwrapped, stdenv, systemd, - wlroots_0_16, + meson, + substituteAll, + swaybg, + ninja, + pkg-config, + gdk-pixbuf, + librsvg, + wayland-protocols, + libdrm, + libinput, + cairo, + pango, + wayland, + libGL, + libxkbcommon, + pcre2, + json_c, + libevdev, + scdoc, + scenefx, + wayland-scanner, + xcbutilwm, + wlroots, + testers, + nixosTests, # Used by the NixOS module: isNixOS ? false, enableXWayland ? true, @@ -12,32 +35,112 @@ trayEnabled ? systemdSupport, }: -(sway-unwrapped.override { +stdenv.mkDerivation (finalAttrs: { inherit - isNixOS enableXWayland + isNixOS systemdSupport trayEnabled ; - wlroots = wlroots_0_16; -}).overrideAttrs (oldAttrs: rec { pname = "swayfx-unwrapped"; - version = "0.3.2"; + version = "0.4"; src = fetchFromGitHub { owner = "WillPower3309"; repo = "swayfx"; - rev = version; - sha256 = "sha256-Gwewb0yDVhEBrefSSGDf1hLtpWcntzifPCPJQhqLqI0="; + rev = "refs/tags/${finalAttrs.version}"; + hash = "sha256-VT+JjQPqCIdtaLeSnRiZ3rES0KgDJR7j5Byxr+d6oRg="; }; - meta = with lib; { + patches = + [ + ./load-configuration-from-etc.patch + + (substituteAll { + src = ./fix-paths.patch; + inherit swaybg; + }) + ] + ++ lib.optionals (!finalAttrs.isNixOS) [ + # References to /nix/store/... will get GC'ed which causes problems when + # copying the default configuration: + ./sway-config-no-nix-store-references.patch + ] + ++ lib.optionals finalAttrs.isNixOS [ + # Use /run/current-system/sw/share and /etc instead of /nix/store + # references: + ./sway-config-nixos-paths.patch + ]; + + strictDeps = true; + depsBuildBuild = [ pkg-config ]; + + nativeBuildInputs = [ + meson + ninja + pkg-config + scdoc + wayland-scanner + ]; + + buildInputs = [ + cairo + gdk-pixbuf + json_c + libdrm + libevdev + libGL + libinput + librsvg + libxkbcommon + pango + pcre2 + scenefx + wayland + wayland-protocols + (wlroots.override { inherit (finalAttrs) enableXWayland; }) + ] ++ lib.optionals finalAttrs.enableXWayland [ xcbutilwm ]; + + mesonFlags = + let + inherit (lib.strings) mesonEnable mesonOption; + + # The "sd-bus-provider" meson option does not include a "none" option, + # but it is silently ignored iff "-Dtray=disabled". We use "basu" + # (which is not in nixpkgs) instead of "none" to alert us if this + # changes: https://github.com/swaywm/sway/issues/6843#issuecomment-1047288761 + # assert trayEnabled -> systemdSupport && dbusSupport; + + sd-bus-provider = if systemdSupport then "libsystemd" else "basu"; + in + [ + (mesonOption "sd-bus-provider" sd-bus-provider) + (mesonEnable "xwayland" finalAttrs.enableXWayland) + (mesonEnable "tray" finalAttrs.trayEnabled) + ]; + + passthru = { + tests = { + basic = nixosTests.swayfx; + version = testers.testVersion { + package = finalAttrs.finalPackage; + command = "sway --version"; + version = "swayfx version ${finalAttrs.version}"; + }; + }; + }; + + meta = { description = "Sway, but with eye candy!"; homepage = "https://github.com/WillPower3309/swayfx"; - license = licenses.mit; - maintainers = with maintainers; [ eclairevoyant ricarch97 ]; - platforms = platforms.linux; + changelog = "https://github.com/WillPower3309/swayfx/releases/tag/${finalAttrs.version}"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ + eclairevoyant + ricarch97 + ]; + platforms = lib.platforms.linux; mainProgram = "sway"; longDescription = '' diff --git a/pkgs/by-name/sw/swayfx-unwrapped/sway-config-nixos-paths.patch b/pkgs/by-name/sw/swayfx-unwrapped/sway-config-nixos-paths.patch new file mode 100644 index 000000000000..bbb0f722b8bc --- /dev/null +++ b/pkgs/by-name/sw/swayfx-unwrapped/sway-config-nixos-paths.patch @@ -0,0 +1,21 @@ +diff --git a/config.in b/config.in +index 08703bef..f3872730 100644 +--- a/config.in ++++ b/config.in +@@ -22,8 +22,8 @@ set $menu dmenu_path | dmenu | xargs swaymsg exec -- + + ### Output configuration + # +-# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/) +-output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill ++# Default wallpaper (more resolutions are available in /run/current-system/sw/share/backgrounds/sway/) ++output * bg /run/current-system/sw/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill + # + # Example configuration: + # +@@ -214,4 +214,4 @@ bar { + } + } + +-include @sysconfdir@/sway/config.d/* ++include /etc/sway/config.d/* diff --git a/pkgs/by-name/sw/swayfx-unwrapped/sway-config-no-nix-store-references.patch b/pkgs/by-name/sw/swayfx-unwrapped/sway-config-no-nix-store-references.patch new file mode 100644 index 000000000000..009c12959430 --- /dev/null +++ b/pkgs/by-name/sw/swayfx-unwrapped/sway-config-no-nix-store-references.patch @@ -0,0 +1,21 @@ +diff --git a/config.in b/config.in +--- a/config.in ++++ b/config.in +@@ -21,8 +21,8 @@ set $menu dmenu_path | dmenu | xargs swaymsg exec + + ### Output configuration + # +-# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/) +-output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill ++# Default wallpaper ++#output * bg ~/.config/sway/backgrounds/Sway_Wallpaper_Blue_1920x1080.png fill + # + # Example configuration: + # +@@ -213,5 +213,3 @@ bar { + inactive_workspace #32323200 #32323200 #5c5c5c + } + } +- +-include @sysconfdir@/sway/config.d/* +