From 9895ce24b454980fbbebe90694d4317ec7ff2233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sat, 4 Aug 2018 15:38:01 +0200 Subject: [PATCH 1/7] nixos/displayManager: Install wayland sessions from extraSessionFilePackages --- nixos/modules/services/x11/display-managers/default.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 26b79730dd3..cb3c0c7a843 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -78,8 +78,7 @@ let # This is required by user units using the session bus. ${config.systemd.package}/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS - # Load X defaults. - # FIXME: Check XDG_SESSION_TYPE against x11 + # Load X defaults. This should probably be safe on wayland too. ${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft} if test -e ~/.Xresources; then ${xorg.xrdb}/bin/xrdb -merge ~/.Xresources @@ -194,6 +193,11 @@ let ${concatMapStrings (pkg: '' ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions '') cfg.displayManager.extraSessionFilePackages} + + mkdir -p "$out/share/wayland-sessions" + ${concatMapStrings (pkg: '' + ${xorg.lndir}/bin/lndir ${pkg}/share/wayland-sessions $out/share/wayland-sessions + '') cfg.displayManager.extraSessionFilePackages} ''; in From d54bfa8f4114a64747a6165c21599a5cc036e91a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sat, 4 Aug 2018 15:17:32 +0200 Subject: [PATCH 2/7] gnome3.gnome-session: prevent crash when launching wayland sessions gnome-session inherits GDMS PATH, which is at the moment non-functional. In X11 this didn't matter as the `Xsession` wrapper would populate the environment beforehand. Wayland sessions doesn't source `Xesssion` (duh), so we patch `bin/gnome-session` to use absolute paths for `grep` and `bash`. In addition `bin/gnome-session` is a simple wrapper around `libexec/gnome-session-binary` mostly responsible for sourcing the users profile before launching the binary. This made our wrapping of `bin/gnome-session` ineffective on wayland as the profile would reset the environment. Simply wrap `libexec/gnome-session-binary` instead. --- .../gnome-3/core/gnome-session/default.nix | 9 +++++++-- .../gnome-3/core/gnome-session/fix-paths.patch | 18 +++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/pkgs/desktops/gnome-3/core/gnome-session/default.nix b/pkgs/desktops/gnome-3/core/gnome-session/default.nix index ceda3dfd56f..2f44a4e168d 100644 --- a/pkgs/desktops/gnome-3/core/gnome-session/default.nix +++ b/pkgs/desktops/gnome-3/core/gnome-session/default.nix @@ -1,6 +1,6 @@ { fetchurl, stdenv, substituteAll, meson, ninja, pkgconfig, gnome3, glib, gtk, gsettings-desktop-schemas , gnome-desktop, dbus, json-glib, libICE, xmlto, docbook_xsl, docbook_xml_dtd_412, python3 -, libxslt, gettext, makeWrapper, systemd, xorg, epoxy }: +, libxslt, gettext, makeWrapper, systemd, xorg, epoxy, gnugrep, bash }: stdenv.mkDerivation rec { name = "gnome-session-${version}"; @@ -16,6 +16,8 @@ stdenv.mkDerivation rec { src = ./fix-paths.patch; gsettings = "${glib.bin}/bin/gsettings"; dbusLaunch = "${dbus.lib}/bin/dbus-launch"; + grep = "${gnugrep}/bin/grep"; + bash = "${bash}/bin/bash"; }) ]; @@ -37,8 +39,11 @@ stdenv.mkDerivation rec { patchShebangs meson_post_install.py ''; + # `bin/gnome-session` will reset the environment when run in wayland, we + # therefor wrap `libexec/gnome-session-binary` instead which is the actual + # binary needing wrapping preFixup = '' - wrapProgram "$out/bin/gnome-session" \ + wrapProgram "$out/libexec/gnome-session-binary" \ --prefix GI_TYPELIB_PATH : "$GI_TYPELIB_PATH" \ --suffix XDG_DATA_DIRS : "$out/share:$GSETTINGS_SCHEMAS_PATH" \ --suffix XDG_DATA_DIRS : "${gnome3.gnome-shell}/share"\ diff --git a/pkgs/desktops/gnome-3/core/gnome-session/fix-paths.patch b/pkgs/desktops/gnome-3/core/gnome-session/fix-paths.patch index c1b5ebe842f..fe4feaf7085 100644 --- a/pkgs/desktops/gnome-3/core/gnome-session/fix-paths.patch +++ b/pkgs/desktops/gnome-3/core/gnome-session/fix-paths.patch @@ -1,6 +1,22 @@ --- a/gnome-session/gnome-session.in +++ b/gnome-session/gnome-session.in -@@ -13,7 +13,7 @@ if [ "x$XDG_SESSION_TYPE" = "xwayland" ] && +@@ -3,11 +3,11 @@ + if [ "x$XDG_SESSION_TYPE" = "xwayland" ] && + [ "x$XDG_SESSION_CLASS" != "xgreeter" ] && + [ -n "$SHELL" ] && +- grep -q "$SHELL" /etc/shells && +- ! (echo "$SHELL" | grep -q "false") && +- ! (echo "$SHELL" | grep -q "nologin"); then ++ @grep@ -q "$SHELL" /etc/shells && ++ ! (echo "$SHELL" | @grep@ -q "false") && ++ ! (echo "$SHELL" | @grep@ -q "nologin"); then + if [ "$1" != '-l' ]; then +- exec bash -c "exec -l '$SHELL' -c '$0 -l $*'" ++ exec @bash@ -c "exec -l '$SHELL' -c '$0 -l $*'" + else + shift + fi +@@ -13,7 +13,7 @@ fi fi From 48a9a24910669f07ca158789fcf92ccf13a97db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sat, 4 Aug 2018 15:51:55 +0200 Subject: [PATCH 3/7] nixos/sddm: Enable wayland-sessions LightDM is unable to separate between `wayland-sessions/gnome.desktop` and `xsessions/gnome.desktop` so I ommitted adding this to LightDM. --- nixos/modules/services/x11/display-managers/sddm.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/services/x11/display-managers/sddm.nix b/nixos/modules/services/x11/display-managers/sddm.nix index b7511dfd5a8..d5f98874b6e 100644 --- a/nixos/modules/services/x11/display-managers/sddm.nix +++ b/nixos/modules/services/x11/display-managers/sddm.nix @@ -59,6 +59,7 @@ let [Wayland] EnableHidpi=${if cfg.enableHidpi then "true" else "false"} + SessionDir=${dmcfg.session.desktops}/share/wayland-sessions ${optionalString cfg.autoLogin.enable '' [Autologin] From cdd266c73bee26b6cd7e092da9a4cc0f34237434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sun, 5 Aug 2018 16:49:00 +0200 Subject: [PATCH 4/7] nixos/gnome3: Implement `sessionPath` through `environment.extraInit` This will simply make the `sessionPath` more likely to work. --- .../services/x11/desktop-managers/gnome3.nix | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix index 72109cf31af..ba6d333b534 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome3.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -136,19 +136,17 @@ in { services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ]; - services.xserver.displayManager.sessionCommands = '' - if test "$XDG_CURRENT_DESKTOP" = "GNOME"; then - ${concatMapStrings (p: '' - if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then - export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name} - fi + environment.extraInit = '' + ${concatMapStrings (p: '' + if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then + export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name} + fi - if [ -d "${p}/lib/girepository-1.0" ]; then - export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0 - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib - fi - '') cfg.sessionPath} - fi + if [ -d "${p}/lib/girepository-1.0" ]; then + export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0 + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib + fi + '') cfg.sessionPath} ''; environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1"; From 3c0e70402f54aa05f47cf2b4266f70b4a10d3aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Mon, 6 Aug 2018 13:45:42 +0200 Subject: [PATCH 5/7] nixos/displayManager: Note that `sessionCommands` aren't run on Wayland --- nixos/modules/services/x11/display-managers/default.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index cb3c0c7a843..035029150c8 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -244,7 +244,10 @@ in '' xmessage "Hello World!" & ''; - description = "Shell commands executed just before the window or desktop manager is started."; + description = '' + Shell commands executed just before the window or desktop manager is + started. These commands are not currently sourced for Wayland sessions. + ''; }; hiddenUsers = mkOption { From 116c16d9e234a4f1c3ef3bfa29f46a105eef8f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sun, 9 Dec 2018 13:19:42 +0100 Subject: [PATCH 6/7] nixos/tests/gnome3: select X11 gnome shell explicitely This isn't strictly necessary yet as LightDM doesn't read the wayland sessions, but there's no harm in being explicit. --- nixos/tests/gnome3.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix index 3f0368592b8..32c6ab226e3 100644 --- a/nixos/tests/gnome3.nix +++ b/nixos/tests/gnome3.nix @@ -16,7 +16,7 @@ import ./make-test.nix ({ pkgs, ...} : { services.xserver.displayManager.lightdm.autoLogin.enable = true; services.xserver.displayManager.lightdm.autoLogin.user = "alice"; services.xserver.desktopManager.gnome3.enable = true; - services.xserver.desktopManager.default = "gnome"; + services.xserver.desktopManager.default = "gnome-xorg"; virtualisation.memorySize = 1024; }; From 75e223bf7ac358bcf4320bb80b386d7cfddc90d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Hedin=20Br=C3=B8nner?= Date: Sun, 9 Dec 2018 16:35:51 +0100 Subject: [PATCH 7/7] nixos/tests/gnome3-gdm: port to wayland The test now runs wayland, which means we can no longer use X11 style testing. Instead we get gnome shell to execute javascript through its dbus interface. --- nixos/tests/gnome3-gdm.nix | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/nixos/tests/gnome3-gdm.nix b/nixos/tests/gnome3-gdm.nix index 959030d5988..c2808d87d99 100644 --- a/nixos/tests/gnome3-gdm.nix +++ b/nixos/tests/gnome3-gdm.nix @@ -23,11 +23,21 @@ import ./make-test.nix ({ pkgs, ...} : { virtualisation.memorySize = 1024; }; - testScript = - '' - # wait for gdm to start and bring up X + testScript = let + # Keep line widths somewhat managable + bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"; + gdbus = "${bus} gdbus"; + # Call javascript in gnome shell, returns a tuple (success, output), where + # `success` is true if the dbus call was successful and output is what the + # javascript evaluates to. + eval = "call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval"; + # False when startup is done + startingUp = "${gdbus} ${eval} Main.layoutManager._startingUp"; + # Hopefully gnome-terminal's wm class + wmClass = "${gdbus} ${eval} global.display.focus_window.wm_class"; + in '' + # wait for gdm to start $machine->waitForUnit("display-manager.service"); - $machine->waitForX; # wait for alice to be logged in $machine->waitForUnit("default.target","alice"); @@ -35,10 +45,16 @@ import ./make-test.nix ({ pkgs, ...} : { # Check that logging in has given the user ownership of devices. $machine->succeed("getfacl /dev/snd/timer | grep -q alice"); - # open a terminal and check it's there - $machine->succeed("su - alice -c 'DISPLAY=:0.0 XAUTHORITY=/run/user/\$UID/gdm/Xauthority gnome-terminal'"); - $machine->succeed("xauth merge /run/user/1000/gdm/Xauthority"); - $machine->waitForWindow(qr/Terminal/); + # Wait for the wayland server + $machine->waitForFile("/run/user/1000/wayland-0"); + + # Wait for gnome shell, correct output should be "(true, 'false')" + $machine->waitUntilSucceeds("su - alice -c '${startingUp} | grep -q true,..false'"); + + # open a terminal + $machine->succeed("su - alice -c '${bus} gnome-terminal'"); + # and check it's there + $machine->waitUntilSucceeds("su - alice -c '${wmClass} | grep -q gnome-terminal-server'"); # wait to get a nice screenshot $machine->sleep(20);