diff mbox series

[bug#50563,2/2] gnu: gdm: Add Wayland session wrapper script.

Message ID _O63PhtCI8ZiwBgDZppLf6SqqIgEm3Y0iFYKUIsuLOeAM4yMfbqumjltWSuHKl8tfgUdL0yAC2TVR4nqKvLNJ18Rgs7iImwzPAztAEvIcmM=@jpoiret.xyz
State Accepted
Headers show
Series gnu: GDM: Add Wayland support | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue

Commit Message

Josselin Poiret Sept. 13, 2021, 8:15 a.m. UTC
* Patch GDM to support launching a wrapper script for Wayland sessions.
* Add `wayland-session` in `gdm-configuration` to specify the wrapper to use.
* Add default wrapper that runs non-GDM sessions through a login shell (based
on the `xinitrc`).
* Update the documentation with those changes.
---
 doc/guix.texi                                 |  4 +++
 gnu/packages/gnome.scm                        |  3 +-
 ...gdm-wayland-session-wrapper-from-env.patch | 35 +++++++++++++++++++
 gnu/services/xorg.scm                         | 21 +++++++++--
 4 files changed, 60 insertions(+), 3 deletions(-)
 create mode 100644 gnu/packages/patches/gdm-wayland-session-wrapper-from-env.patch

--
2.33.0

Comments

M Sept. 13, 2021, 6:14 p.m. UTC | #1
Josselin Poiret schreef op ma 13-09-2021 om 08:15 [+0000]:
> * Patch GDM to support launching a wrapper script for Wayland sessions.
> * Add `wayland-session` in `gdm-configuration` to specify the wrapper to use.
> * Add default wrapper that runs non-GDM sessions through a login shell (based
> on the `xinitrc`).
> * Update the documentation with those changes.
> ---
>  doc/guix.texi                                 |  4 +++
>  gnu/packages/gnome.scm                        |  3 +-
>  ...gdm-wayland-session-wrapper-from-env.patch | 35 +++++++++++++++++++
>  gnu/services/xorg.scm                         | 21 +++++++++--
>  4 files changed, 60 insertions(+), 3 deletions(-)
>  create mode 100644 gnu/packages/patches/gdm-wayland-session-wrapper-from-env.patch
> 
> diff --git a/doc/guix.texi b/doc/guix.texi
> index 93ea4a321f..3e6157c8ab 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -18098,6 +18098,10 @@ The GDM package to use.
> 
>  @item @code{wayland?} (default: @code{#f})
>  When true, enables Wayland in GDM, necessary to use Wayland sessions.
> +
> +@item @code{wayland-session} (default: @code{gdm-wayland-session-wrapper})
> +The Wayland session wrapper to use, needed to setup the
> +environment.

‘needed to setup the environment’ --> this sounds like sometimes, the session
wrapper needs to be changed such that the environment variables are correct.
However, gdm-wayland-session-wrapper doesn't actually set any environment variables,
and the X equivalent 'xsession' doesn't need to be modified (at least on my system,
when I last used gdm), so I presume the default is quite reasonable for most users.

So to reduce confusion, I would drop the ‘needed to set up the environment’.

A ‘real-world’ example of a custom 'wayland-session' would be helpful to illustrate
matters.

Greetings,
Maxime
Mathieu Othacehe Oct. 1, 2021, 7:37 a.m. UTC | #2
Hello,

> +;; Wrapper script for Wayland sessions, similar to Xsession.
> +;; Used to setup the environment.
> +(define gdm-wayland-session-wrapper
> +  (program-file
> +   "gdm-wayland-session-wrapper"
> +   #~((let* ((user (getpw (getuid)))
> +	    (name (passwd:name user))
> +	    (shell (passwd:shell user))
> +	    (args (cdr (command-line))))
> +        (if (string=? name "gdm")
> +	    (apply execl (cons (car args) args))
> +	    (execl shell shell "--login" "-c" (string-join args)))))))

I'm not sure to get perfectly the role of this wrapper, could you
please clarify it?

It looks like nix is dealing differently with the session starting,
without using a dedicated script:

https://github.com/NixOS/nixpkgs/blob/master/pkgs/desktops/gnome/core/gdm/fix-paths.patch

Thanks,

Mathieu
Josselin Poiret Oct. 1, 2021, 8:56 a.m. UTC | #3
Hello,

On Friday, October 1st, 2021 at 9:37 AM, Mathieu Othacehe <othacehe@gnu.org> wrote:
> I'm not sure to get perfectly the role of this wrapper, could you
> please clarify it?

Simply put, when display managers (on Guix) start an X session, they are all configured to use a generic Guix-specific wrapper script, a `xinitrc`.
This feature predates Guix of course, and is supported by all display managers afaik. `xinitrc` is defined in `gnu/services/xorg.scm` and is the generic Guix wrapper.
Notice that most importantly, it runs the window manager inside a login shell, which thus inherits the right environment variables that are set by default in `/etc/profile` (unless of course `/etc/profile` isn't sourced by the login shell, but then the user is on his own).

So we would like to do the same with Wayland, however since Wayland compositors are just single programs that need to be launched, most display managers used to simply start the compositors without doing anything else. This is still the behaviour of GDM, whereas for example SDDM or Slim (at least in Guix) already support wrapping those in some scripts. Here, I just define a generic script that launches sessions inside a login shell, akin to the default `xinitrc`. The check for the `gdm` user is that the GDM graphical display is launched through... GDM itself, and thus is handled like the other Wayland sessions; but since the `gdm` user doesn't have a login shell, this wouldn't work.

> It looks like nix is dealing differently with the session starting,
> without using a dedicated script:
> https://github.com/NixOS/nixpkgs/blob/master/pkgs/desktops/gnome/core/gdm/fix-paths.patch

From my understanding of https://github.com/NixOS/nixpkgs/issues/109546, they're still trying to deal with this generic issue (ie. they haven't patched in wrapper support in GDM).
See https://github.com/NixOS/nixpkgs/issues/109542 for an example of a bug that stems from it.

Josselin
Mathieu Othacehe Oct. 1, 2021, 9:16 a.m. UTC | #4
> the default `xinitrc`. The check for the `gdm` user is that the GDM graphical
> display is launched through... GDM itself, and thus is handled like the other
> Wayland sessions; but since the `gdm` user doesn't have a login shell, this
> wouldn't work.

I see that for explaining! This would deserve a comment I think, could
you please send a v2 for the second patch?

That's unrelated, but what's your take on enabling wayland by default on
GDM, like some other distributions? Just ran a quick search and it looks
like it could be problematic for Nvidia users.

Thanks,

Mathieu
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index 93ea4a321f..3e6157c8ab 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -18098,6 +18098,10 @@  The GDM package to use.

 @item @code{wayland?} (default: @code{#f})
 When true, enables Wayland in GDM, necessary to use Wayland sessions.
+
+@item @code{wayland-session} (default: @code{gdm-wayland-session-wrapper})
+The Wayland session wrapper to use, needed to setup the
+environment.
 @end table
 @end deftp

diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 2da0b3791f..36d58e4c42 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -8112,7 +8112,8 @@  library.")
                (base32
                 "1lyqvcwxhwxklbxn4xjswjzr6fhjix6h28mi9ypn34wdm9bzcpg8"))
               (patches (search-patches "gdm-default-session.patch"
-                                       "gdm-remove-hardcoded-xwayland-path.patch"))))
+                                       "gdm-remove-hardcoded-xwayland-path.patch"
+                                       "gdm-wayland-session-wrapper-from-env.patch"))))
     (build-system glib-or-gtk-build-system)
     (arguments
      '(#:configure-flags
diff --git a/gnu/packages/patches/gdm-wayland-session-wrapper-from-env.patch b/gnu/packages/patches/gdm-wayland-session-wrapper-from-env.patch
new file mode 100644
index 0000000000..ca1af557ef
--- /dev/null
+++ b/gnu/packages/patches/gdm-wayland-session-wrapper-from-env.patch
@@ -0,0 +1,35 @@ 
+Get wayland-session wrapper from environment
+
+---
+ daemon/gdm-session.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
+index 4e303e70..1deca4e9 100644
+--- a/daemon/gdm-session.c
++++ b/daemon/gdm-session.c
+@@ -2888,8 +2888,9 @@ gdm_session_start_session (GdmSession *self,
+                                                            allow_remote_connections? "--allow-remote-connections " : "",
+                                                            command);
+                         } else {
+-                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
++                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s %s\"",
+                                                            register_session ? "--register-session " : "",
++                                                           g_getenv ("GDM_WAYLAND_SESSION"),
+                                                            command);
+                         }
+                 } else if (run_xsession_script) {
+@@ -2906,8 +2907,9 @@ gdm_session_start_session (GdmSession *self,
+                                                            register_session ? "--register-session " : "",
+                                                            self->selected_program);
+                         } else {
+-                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s\"",
++                                program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"%s %s\"",
+                                                            register_session ? "--register-session " : "",
++                                                           g_getenv ("GDM_WAYLAND_SESSION"),
+                                                            self->selected_program);
+                         }
+                 } else {
+--
+2.33.0
+
diff --git a/gnu/services/xorg.scm b/gnu/services/xorg.scm
index fe25168a58..a9b2a1a1c6 100644
--- a/gnu/services/xorg.scm
+++ b/gnu/services/xorg.scm
@@ -869,6 +869,19 @@  the GNOME desktop environment.")
        (apply execl (string-append #$dbus "/bin/dbus-daemon")
               (program-arguments)))))

+;; Wrapper script for Wayland sessions, similar to Xsession.
+;; Used to setup the environment.
+(define gdm-wayland-session-wrapper
+  (program-file
+   "gdm-wayland-session-wrapper"
+   #~((let* ((user (getpw (getuid)))
+	    (name (passwd:name user))
+	    (shell (passwd:shell user))
+	    (args (cdr (command-line))))
+        (if (string=? name "gdm")
+	    (apply execl (cons (car args) args))
+	    (execl shell shell "--login" "-c" (string-join args)))))))
+
 (define-record-type* <gdm-configuration>
   gdm-configuration make-gdm-configuration
   gdm-configuration?
@@ -884,7 +897,8 @@  the GNOME desktop environment.")
                       (default (xorg-configuration)))
   (x-session gdm-configuration-x-session
              (default (xinitrc)))
-  (wayland? gdm-configuration-wayland? (default #f)))
+  (wayland? gdm-configuration-wayland? (default #f))
+  (wayland-session gdm-configuration-wayland-session (default gdm-wayland-session-wrapper)))

 (define (gdm-configuration-file config)
   (mixed-text-file "gdm-custom.conf"
@@ -982,7 +996,10 @@  the GNOME desktop environment.")
                            ;; Add XCURSOR_PATH so that mutter can find its cursors.
                            ;; gdm doesn't login so doesn't source the corresponding
                            ;; line in /etc/profile
-                           "XCURSOR_PATH=/run/current-system/profile/share/icons"))))
+                           "XCURSOR_PATH=/run/current-system/profile/share/icons"
+                           (string-append
+                            "GDM_WAYLAND_SESSION="
+                            #$(gdm-configuration-wayland-session config))))))
          (stop #~(make-kill-destructor))
          (respawn? #t))))