diff options
Diffstat (limited to 'pkgs/desktops/gnome/core/gdm')
7 files changed, 393 insertions, 0 deletions
diff --git a/pkgs/desktops/gnome/core/gdm/default.nix b/pkgs/desktops/gnome/core/gdm/default.nix new file mode 100644 index 0000000000000..f304497734953 --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/default.nix @@ -0,0 +1,180 @@ +{ lib, stdenv +, fetchurl +, fetchpatch +, substituteAll +, meson +, ninja +, python3 +, rsync +, pkg-config +, glib +, itstool +, libxml2 +, xorg +, accountsservice +, libX11 +, gnome +, systemd +, dconf +, gtk3 +, libcanberra-gtk3 +, pam +, libselinux +, keyutils +, audit +, gobject-introspection +, plymouth +, librsvg +, coreutils +, xwayland +, dbus +, nixos-icons +}: + +let + + override = substituteAll { + src = ./org.gnome.login-screen.gschema.override; + icon = "${nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake-white.svg"; + }; + +in + +stdenv.mkDerivation rec { + pname = "gdm"; + version = "40.0"; + + outputs = [ "out" "dev" ]; + + src = fetchurl { + url = "mirror://gnome/sources/gdm/${lib.versions.major version}/${pname}-${version}.tar.xz"; + sha256 = "XtdLc506Iy/7HkoTK8+WW9/pVdmVtSh3NYh3WwLylQ4="; + }; + + mesonFlags = [ + "-Dgdm-xsession=true" + # TODO: Setup a default-path? https://gitlab.gnome.org/GNOME/gdm/-/blob/6fc40ac6aa37c8ad87c32f0b1a5d813d34bf7770/meson_options.txt#L6 + "-Dinitial-vt=${passthru.initialVT}" + "-Dudev-dir=${placeholder "out"}/lib/udev/rules.d" + "-Dsystemdsystemunitdir=${placeholder "out"}/lib/systemd/system" + "-Dsystemduserunitdir=${placeholder "out"}/lib/systemd/user" + "--sysconfdir=/etc" + "--localstatedir=/var" + ]; + + nativeBuildInputs = [ + dconf + glib # for glib-compile-schemas + itstool + meson + ninja + pkg-config + python3 + rsync + ]; + + buildInputs = [ + accountsservice + audit + glib + gobject-introspection + gtk3 + keyutils + libX11 + libcanberra-gtk3 + libselinux + pam + plymouth + systemd + xorg.libXdmcp + ]; + + patches = [ + # GDM fails to find g-s with the following error in the journal. + # gdm-x-session[976]: dbus-run-session: failed to exec 'gnome-session': No such file or directory + # https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/92 + (fetchpatch { + url = "https://gitlab.gnome.org/GNOME/gdm/-/commit/ccecd9c975d04da80db4cd547b67a1a94fa83292.patch"; + sha256 = "5hKS9wjjhuSAYwXct5vS0dPbmPRIINJoLC0Zm1naz6Q="; + revert = true; + }) + + # Change hardcoded paths to nix store paths. + (substituteAll { + src = ./fix-paths.patch; + inherit coreutils plymouth xwayland dbus; + }) + + # The following patches implement certain environment variables in GDM which are set by + # the gdm configuration module (nixos/modules/services/x11/display-managers/gdm.nix). + + ./gdm-x-session_extra_args.patch + + # Allow specifying a wrapper for running the session command. + ./gdm-x-session_session-wrapper.patch + + # Forwards certain environment variables to the gdm-x-session child process + # to ensure that the above two patches actually work. + ./gdm-session-worker_forward-vars.patch + + # Set up the environment properly when launching sessions + # https://github.com/NixOS/nixpkgs/issues/48255 + ./reset-environment.patch + ]; + + postPatch = '' + patchShebangs build-aux/meson_post_install.py + + # Upstream checks some common paths to find an `X` binary. We already know it. + echo #!/bin/sh > build-aux/find-x-server.sh + echo "echo ${lib.getBin xorg.xorgserver}/bin/X" >> build-aux/find-x-server.sh + patchShebangs build-aux/find-x-server.sh + ''; + + preInstall = '' + install -D ${override} ${DESTDIR}/$out/share/glib-2.0/schemas/org.gnome.login-screen.gschema.override + ''; + + postInstall = '' + # Move stuff from DESTDIR to proper location. + # We use rsync to merge the directories. + rsync --archive "${DESTDIR}/etc" "$out" + rm --recursive "${DESTDIR}/etc" + for o in $outputs; do + rsync --archive "${DESTDIR}/''${!o}" "$(dirname "''${!o}")" + rm --recursive "${DESTDIR}/''${!o}" + done + # Ensure the DESTDIR is removed. + rmdir "${DESTDIR}/nix/store" "${DESTDIR}/nix" "${DESTDIR}" + + # We are setting DESTDIR so the post-install script does not compile the schemas. + glib-compile-schemas "$out/share/glib-2.0/schemas" + ''; + + # HACK: We want to install configuration files to $out/etc + # but GDM should read them from /etc on a NixOS system. + # With autotools, it was possible to override Make variables + # at install time but Meson does not support this + # so we need to convince it to install all files to a temporary + # location using DESTDIR and then move it to proper one in postInstall. + DESTDIR = "${placeholder "out"}/dest"; + + passthru = { + updateScript = gnome.updateScript { + packageName = "gdm"; + attrPath = "gnome.gdm"; + }; + + # Used in GDM NixOS module + # Don't remove. + initialVT = "7"; + }; + + meta = with lib; { + description = "A program that manages graphical display servers and handles graphical user logins"; + homepage = "https://wiki.gnome.org/Projects/GDM"; + license = licenses.gpl2Plus; + maintainers = teams.gnome.members; + platforms = platforms.linux; + }; +} diff --git a/pkgs/desktops/gnome/core/gdm/fix-paths.patch b/pkgs/desktops/gnome/core/gdm/fix-paths.patch new file mode 100644 index 0000000000000..d649556fe9e62 --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/fix-paths.patch @@ -0,0 +1,82 @@ +--- a/daemon/gdm-local-display-factory.c ++++ b/daemon/gdm-local-display-factory.c +@@ -201,7 +201,7 @@ + #ifdef ENABLE_WAYLAND_SUPPORT + gboolean wayland_enabled = FALSE; + if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { +- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) ++ if (wayland_enabled && g_file_test ("@xwayland@/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) + return TRUE; + } + #endif +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -145,7 +145,7 @@ + GError *error; + + error = NULL; +- res = g_spawn_command_line_sync ("plymouth --ping", ++ res = g_spawn_command_line_sync ("@plymouth@/bin/plymouth --ping", + NULL, NULL, &status, &error); + if (! res) { + g_debug ("Could not ping plymouth: %s", error->message); +@@ -163,7 +163,7 @@ + GError *error; + + error = NULL; +- res = g_spawn_command_line_sync ("plymouth deactivate", ++ res = g_spawn_command_line_sync ("@plymouth@/bin/plymouth deactivate", + NULL, NULL, NULL, &error); + if (! res) { + g_warning ("Could not deactivate plymouth: %s", error->message); +@@ -178,7 +178,7 @@ + GError *error; + + error = NULL; +- res = g_spawn_command_line_async ("plymouth quit --retain-splash", &error); ++ res = g_spawn_command_line_async ("@plymouth@/bin/plymouth quit --retain-splash", &error); + if (! res) { + g_warning ("Could not quit plymouth: %s", error->message); + g_error_free (error); +@@ -194,7 +194,7 @@ + GError *error; + + error = NULL; +- res = g_spawn_command_line_async ("plymouth quit", &error); ++ res = g_spawn_command_line_async ("@plymouth@/bin/plymouth quit", &error); + if (! res) { + g_warning ("Could not quit plymouth: %s", error->message); + g_error_free (error); +--- a/data/gdm.service.in ++++ b/data/gdm.service.in +@@ -26,7 +26,7 @@ Restart=always + IgnoreSIGPIPE=no + BusName=org.gnome.DisplayManager + EnvironmentFile=-${LANG_CONFIG_FILE} +-ExecReload=/bin/kill -SIGHUP $MAINPID ++ExecReload=@coreutils@/bin/kill -SIGHUP $MAINPID + KeyringMode=shared + + [Install] +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -2916,16 +2916,16 @@ gdm_session_start_session (GdmSession *self, + */ + if (run_launcher) { + if (is_x11) { +- program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"dbus-run-session -- %s\"", ++ program = g_strdup_printf (LIBEXECDIR "/gdm-x-session %s\"@dbus@/bin/dbus-run-session --dbus-daemon=@dbus@/bin/dbus-daemon -- %s\"", + register_session ? "--register-session " : "", + self->selected_program); + } else { +- program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"dbus-run-session -- %s\"", ++ program = g_strdup_printf (LIBEXECDIR "/gdm-wayland-session %s\"@dbus@/bin/dbus-run-session --dbus-daemon=@dbus@/bin/dbus-daemon -- %s\"", + register_session ? "--register-session " : "", + self->selected_program); + } + } else { +- program = g_strdup_printf ("dbus-run-session -- %s", ++ program = g_strdup_printf ("@dbus@/bin/dbus-run-session --dbus-daemon=@dbus@/bin/dbus-daemon -- %s", + self->selected_program); + } + } diff --git a/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch b/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch new file mode 100644 index 0000000000000..401b6aea0c28e --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch @@ -0,0 +1,31 @@ +diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c +index 9ef4c5b..94da834 100644 +--- a/daemon/gdm-session-worker.c ++++ b/daemon/gdm-session-worker.c +@@ -1515,6 +1515,16 @@ gdm_session_worker_load_env_d (GdmSessionWorker *worker) + g_object_unref (dir); + } + ++static void ++gdm_session_worker_forward_var (GdmSessionWorker *worker, char const *var) ++{ ++ char const *value = g_getenv(var); ++ if (value != NULL) { ++ g_debug ("forwarding %s= %s", var, value); ++ gdm_session_worker_set_environment_variable(worker, var, value); ++ } ++} ++ + static gboolean + gdm_session_worker_accredit_user (GdmSessionWorker *worker, + GError **error) +@@ -1559,6 +1569,9 @@ gdm_session_worker_accredit_user (GdmSessionWorker *worker, + goto out; + } + ++ gdm_session_worker_forward_var(worker, "GDM_X_SERVER_EXTRA_ARGS"); ++ gdm_session_worker_forward_var(worker, "GDM_X_SESSION_WRAPPER"); ++ + gdm_session_worker_update_environment_from_passwd_info (worker, + uid, + gid, diff --git a/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch b/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch new file mode 100644 index 0000000000000..66071aa4af805 --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch @@ -0,0 +1,38 @@ +diff --git a/daemon/gdm-x-session.c.orig b/daemon/gdm-x-session.c +index d835b34..1f4b7f1 100644 +--- a/daemon/gdm-x-session.c.orig ++++ b/daemon/gdm-x-session.c +@@ -211,6 +211,7 @@ spawn_x_server (State *state, + char *vt_string = NULL; + char *display_number; + gsize display_number_size; ++ gchar **xserver_extra_args = NULL; + + auth_file = prepare_auth_file (); + +@@ -285,6 +286,17 @@ spawn_x_server (State *state, + if (state->debug_enabled) { + g_ptr_array_add (arguments, "-core"); + } ++ ++ if (g_getenv ("GDM_X_SERVER_EXTRA_ARGS") != NULL) { ++ g_debug ("using GDM_X_SERVER_EXTRA_ARGS: %s", g_getenv("GDM_X_SERVER_EXTRA_ARGS")); ++ xserver_extra_args = g_strsplit(g_getenv("GDM_X_SERVER_EXTRA_ARGS"), " ", -1); ++ for (gchar **extra_arg = xserver_extra_args; *extra_arg; extra_arg++) { ++ if (strlen(*extra_arg) < 1) continue; ++ g_debug ("adding: %s", *extra_arg); ++ g_ptr_array_add (arguments, *extra_arg); ++ } ++ } ++ + g_ptr_array_add (arguments, NULL); + + subprocess = g_subprocess_launcher_spawnv (launcher, +@@ -332,6 +344,7 @@ spawn_x_server (State *state, + + is_running = TRUE; + out: ++ g_strfreev(xserver_extra_args); + g_clear_pointer (&auth_file, g_free); + g_clear_object (&data_stream); + g_clear_object (&subprocess); diff --git a/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch b/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch new file mode 100644 index 0000000000000..58481f0730fae --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch @@ -0,0 +1,40 @@ +diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c +index 88fe96f..b1b140a 100644 +--- a/daemon/gdm-x-session.c ++++ b/daemon/gdm-x-session.c +@@ -664,18 +664,34 @@ spawn_session (State *state, + state->session_command, + NULL); + } else { ++ char const *session_wrapper; ++ char *eff_session_command; + int ret; + char **argv; + +- ret = g_shell_parse_argv (state->session_command, ++ session_wrapper = g_getenv("GDM_X_SESSION_WRAPPER"); ++ if (session_wrapper != NULL) { ++ char *quoted_wrapper = g_shell_quote(session_wrapper); ++ eff_session_command = g_strjoin(" ", quoted_wrapper, state->session_command, NULL); ++ g_free(quoted_wrapper); ++ } else { ++ eff_session_command = state->session_command; ++ } ++ ++ ret = g_shell_parse_argv (eff_session_command, + NULL, + &argv, + &error); + ++ if (session_wrapper != NULL) { ++ g_free(eff_session_command); ++ } ++ + if (!ret) { + g_debug ("could not parse session arguments: %s", error->message); + goto out; + } ++ + subprocess = g_subprocess_launcher_spawnv (launcher, + (const char * const *) argv, + &error); diff --git a/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override b/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override new file mode 100644 index 0000000000000..8c17f494b0f2a --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override @@ -0,0 +1,2 @@ +[org.gnome.login-screen] +logo='@icon@' diff --git a/pkgs/desktops/gnome/core/gdm/reset-environment.patch b/pkgs/desktops/gnome/core/gdm/reset-environment.patch new file mode 100644 index 0000000000000..61defd9c4bc20 --- /dev/null +++ b/pkgs/desktops/gnome/core/gdm/reset-environment.patch @@ -0,0 +1,20 @@ +--- a/daemon/gdm-wayland-session.c ++++ b/daemon/gdm-wayland-session.c +@@ -285,6 +285,7 @@ spawn_session (State *state, + "WAYLAND_DISPLAY", + "WAYLAND_SOCKET", + "GNOME_SHELL_SESSION_MODE", ++ "__NIXOS_SET_ENVIRONMENT_DONE", + NULL }; + + g_debug ("Running wayland session"); +--- a/daemon/gdm-x-session.c ++++ b/daemon/gdm-x-session.c +@@ -610,6 +610,7 @@ spawn_session (State *state, + "WAYLAND_DISPLAY", + "WAYLAND_SOCKET", + "GNOME_SHELL_SESSION_MODE", ++ "__NIXOS_SET_ENVIRONMENT_DONE", + NULL }; + + g_debug ("Running X session"); |