about summary refs log tree commit diff
path: root/nixpkgs/pkgs/desktops/gnome/core
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/desktops/gnome/core')
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/adwaita-icon-theme/default.nix55
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/baobab/default.nix66
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/caribou/default.nix69
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/dconf-editor/default.nix79
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/dconf-editor/schema-override-variable.patch14
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/eog/default.nix123
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/eog/fix-gir-lib-path.patch13
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/epiphany/default.nix108
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/evince/default.nix145
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/default.nix192
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/drop-tentative-settings-constructor.patch40
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/fix-paths.patch11
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/hardcode-gsettings.patch652
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/default.nix194
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/fix-paths.patch93
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch31
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch38
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch40
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override2
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gdm/reset-environment.patch20
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/default.nix44
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/stable-dir.patch9
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/1.0/default.nix97
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/default.nix86
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-calculator/default.nix81
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/0001-Fix-build-with-Exiv2-0.28.patch73
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/default.nix70
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-common/default.nix21
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-contacts/default.nix80
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/default.nix215
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/paths.patch177
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-dictionary/default.nix85
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-disk-utility/default.nix81
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-font-viewer/default.nix66
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/0001-fix-paths.patch53
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/default.nix115
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/vendor.conf5
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-keyring/default.nix105
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-online-miners/default.nix116
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-remote-desktop/default.nix84
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-screenshot/default.nix82
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-session/ctl.nix42
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-session/default.nix141
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-session/fix-paths.patch35
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/default.nix128
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/fix-paths.patch15
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/add-gnome-session-ctl-option.patch58
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/default.nix126
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/fix-paths.patch15
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/default.nix78
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/fix_gmenu.patch22
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell/default.nix234
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell/fix-paths.patch71
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell/greeter-logo-size.patch21
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell/shew-gir-path.patch11
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-shell/wrap-services.patch57
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-software/default.nix125
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-software/fix-paths.patch11
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/default.nix79
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/fix-paths.patch12
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-terminal/default.nix103
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-themes-extra/default.nix35
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-tour/default.nix74
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gnome-user-share/default.nix70
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/gucharmap/default.nix113
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/libgnome-keyring/default.nix35
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/mutter/43/default.nix193
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/mutter/default.nix209
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/nautilus/default.nix134
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/nautilus/extension_dir.patch26
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/nautilus/fix-paths.patch13
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/rygel/add-option-for-installation-sysconfdir.patch35
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/rygel/default.nix108
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/simple-scan/default.nix88
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/sushi/default.nix85
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/totem/default.nix143
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/yelp-xsl/default.nix52
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/yelp/default.nix62
-rw-r--r--nixpkgs/pkgs/desktops/gnome/core/zenity/default.nix57
79 files changed, 6646 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/desktops/gnome/core/adwaita-icon-theme/default.nix b/nixpkgs/pkgs/desktops/gnome/core/adwaita-icon-theme/default.nix
new file mode 100644
index 000000000000..5d287f4e6fd9
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/adwaita-icon-theme/default.nix
@@ -0,0 +1,55 @@
+{ lib
+, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gnome
+, gtk3
+, gdk-pixbuf
+, librsvg
+, hicolor-icon-theme
+}:
+
+stdenv.mkDerivation rec {
+  pname = "adwaita-icon-theme";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/adwaita-icon-theme/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "JEK/sG9ObMlb9uJoL9/5j6Xt3GiHUbnWIVxiPLTkL/E=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gtk3
+  ];
+
+  buildInputs = [
+    gdk-pixbuf
+    librsvg
+  ];
+
+  propagatedBuildInputs = [
+    # For convenience, we can specify adwaita-icon-theme only in packages
+    hicolor-icon-theme
+  ];
+
+  dontDropIconThemeCache = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "adwaita-icon-theme";
+      attrPath = "gnome.adwaita-icon-theme";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/adwaita-icon-theme";
+    platforms = with platforms; linux ++ darwin;
+    maintainers = teams.gnome.members;
+    license = licenses.cc-by-sa-30;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/baobab/default.nix b/nixpkgs/pkgs/desktops/gnome/core/baobab/default.nix
new file mode 100644
index 000000000000..e813f5f591ab
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/baobab/default.nix
@@ -0,0 +1,66 @@
+{ stdenv
+, lib
+, gettext
+, fetchurl
+, vala
+, desktop-file-utils
+, meson
+, ninja
+, pkg-config
+, gtk4
+, libadwaita
+, glib
+, libxml2
+, wrapGAppsHook4
+, itstool
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "baobab";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "p9LPMIpsg57gsL8HT49f1g1iri8GSpSzxhDWVgt1joY=";
+  };
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    gettext
+    glib
+    itstool
+    libxml2
+    meson
+    ninja
+    pkg-config
+    vala
+    wrapGAppsHook4
+    # Prevents “error: Package `libadwaita-1' not found in specified Vala API
+    # directories or GObject-Introspection GIR directories” with strictDeps,
+    # even though it should only be a runtime dependency.
+    libadwaita
+  ];
+
+  buildInputs = [
+    gtk4
+    libadwaita
+    glib
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  meta = with lib; {
+    description = "Graphical application to analyse disk usage in any GNOME environment";
+    homepage = "https://wiki.gnome.org/Apps/DiskUsageAnalyzer";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/caribou/default.nix b/nixpkgs/pkgs/desktops/gnome/core/caribou/default.nix
new file mode 100644
index 000000000000..2afb65d528e1
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/caribou/default.nix
@@ -0,0 +1,69 @@
+{ fetchurl, lib, stdenv, pkg-config, gnome, glib, gtk3, clutter, dbus, python3, libxml2
+, libxklavier, libXtst, gtk2, intltool, libxslt, at-spi2-core, autoreconfHook
+, wrapGAppsHook, libgee, vala }:
+
+let
+  pname = "caribou";
+  version = "0.4.21";
+  pythonEnv = python3.withPackages ( ps: with ps; [ pygobject3 ] );
+in stdenv.mkDerivation rec {
+  name = "${pname}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${name}.tar.xz";
+    sha256 = "0mfychh1q3dx0b96pjz9a9y112bm9yqyim40yykzxx1hppsdjhww";
+  };
+
+  patches = [
+    # Fix crash in GNOME Flashback
+    # https://bugzilla.gnome.org/show_bug.cgi?id=791001
+    (fetchurl {
+      url = "https://bugzilla.gnome.org/attachment.cgi?id=364774";
+      sha256 = "15k1455grf6knlrxqbjnk7sals1730b0whj30451scp46wyvykvd";
+    })
+    # Stop patching the generated GIR, fixes build with latest vala
+    (fetchurl {
+      url = "https://gitlab.gnome.org/GNOME/caribou/-/commit/c52ce71c49dc8d6109a58d16cc8d491d7bd1d781.patch";
+      sha256 = "sha256-jbF1Ygp8Q0ENN/5aEpROuK5zkufIfn6cGW8dncl7ET4=";
+    })
+    (fetchurl {
+      name = "fix-build-modern-vala.patch";
+      url = "https://gitlab.gnome.org/GNOME/caribou/-/commit/76fbd11575f918fc898cb0f5defe07f67c11ec38.patch";
+      sha256 = "0qy27zk7889hg51nx40afgppcx9iaihxbg3aqz9w35d6fmhr2k2y";
+    })
+    (fetchurl {
+      name = "CVE-2021-3567.patch";
+      url = "https://gitlab.gnome.org/GNOME/caribou/-/commit/d41c8e44b12222a290eaca16703406b113a630c6.patch";
+      sha256 = "1vd2j3823k2p3msv7fq2437p3jvxzbd7hyh07i80g9754ylh92y8";
+    })
+  ];
+
+  nativeBuildInputs = [ pkg-config intltool libxslt libxml2 autoreconfHook wrapGAppsHook vala ];
+
+  buildInputs = [
+    glib gtk3 clutter at-spi2-core dbus pythonEnv python3.pkgs.pygobject3
+    libXtst gtk2
+  ];
+
+  propagatedBuildInputs = [ libgee libxklavier ];
+
+  postPatch = ''
+    patchShebangs .
+    substituteInPlace libcaribou/Makefile.am --replace "--shared-library=libcaribou.so.0" "--shared-library=$out/lib/libcaribou.so.0"
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "An input assistive technology intended for switch and pointer users";
+    homepage = "https://wiki.gnome.org/Projects/Caribou";
+    license = licenses.lgpl21;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/default.nix b/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/default.nix
new file mode 100644
index 000000000000..4da661748c95
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/default.nix
@@ -0,0 +1,79 @@
+{ lib
+, stdenv
+, fetchurl
+, fetchpatch
+, desktop-file-utils
+, meson
+, ninja
+, vala
+, libxslt
+, pkg-config
+, glib
+, gtk3
+, libhandy
+, gnome
+, dconf
+, libxml2
+, gettext
+, docbook-xsl-nons
+, wrapGAppsHook
+, gobject-introspection
+}:
+
+stdenv.mkDerivation rec {
+  pname = "dconf-editor";
+  version = "45.0.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-EYApdnju2uYhfMUUomOMGH0vHR7ycgy5B5t0DEKZQd0=";
+  };
+
+  patches = [
+    # Fix crash with GSETTINGS_SCHEMA_DIR env var.
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/dconf-editor/-/commit/baf183737d459dcde065c9f8f6fe5be7ed874de6.patch";
+      hash = "sha256-Vp0qjJChDr6IarUD+tZPLJhdI8v8r6EzWNfqFSnGvqQ=";
+    })
+
+    # Look for compiled schemas in NIX_GSETTINGS_OVERRIDES_DIR
+    # environment variable, to match what we patched GLib to do.
+    ./schema-override-variable.patch
+  ];
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    meson
+    ninja
+    vala
+    libxslt
+    pkg-config
+    wrapGAppsHook
+    gettext
+    docbook-xsl-nons
+    libxml2
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    glib
+    gtk3
+    libhandy
+    dconf
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "GSettings editor for GNOME";
+    homepage = "https://wiki.gnome.org/Apps/DconfEditor";
+    license = licenses.gpl3Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/schema-override-variable.patch b/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/schema-override-variable.patch
new file mode 100644
index 000000000000..06896d1aa4ee
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/dconf-editor/schema-override-variable.patch
@@ -0,0 +1,14 @@
+diff --git a/editor/source-manager.vala b/editor/source-manager.vala
+index 27b2b17a..87f7ba86 100644
+--- a/editor/source-manager.vala
++++ b/editor/source-manager.vala
+@@ -121,6 +121,9 @@ private class SourceManager : Object
+             source = try_prepend_dir (source, Path.build_filename (system_data_dirs [i], "glib-2.0", "schemas"));
+         string user_data_dir = GLib.Environment.get_user_data_dir ();
+         source = try_prepend_dir (source, Path.build_filename (user_data_dir, "glib-2.0", "schemas"));
++        string? nix_var_schema_dir = GLib.Environment.get_variable ("NIX_GSETTINGS_OVERRIDES_DIR");
++        if (nix_var_schema_dir != null)
++            source = try_prepend_dir (source, (!) nix_var_schema_dir);
+         string? var_schema_dir = GLib.Environment.get_variable ("GSETTINGS_SCHEMA_DIR");
+         if (var_schema_dir != null) {
+             string[] extra_schema_dirs = ((!) var_schema_dir).split (Path.SEARCHPATH_SEPARATOR_S);
diff --git a/nixpkgs/pkgs/desktops/gnome/core/eog/default.nix b/nixpkgs/pkgs/desktops/gnome/core/eog/default.nix
new file mode 100644
index 000000000000..1641fa5bbf60
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/eog/default.nix
@@ -0,0 +1,123 @@
+{ lib
+, stdenv
+, fetchurl
+, meson
+, ninja
+, gettext
+, itstool
+, pkg-config
+, libxml2
+, libjpeg
+, libpeas
+, libportal-gtk3
+, gnome
+, gtk3
+, libhandy
+, glib
+, gsettings-desktop-schemas
+, gnome-desktop
+, lcms2
+, gdk-pixbuf
+, exempi
+, shared-mime-info
+, wrapGAppsHook
+, librsvg
+, webp-pixbuf-loader
+, libheif
+, libexif
+, gobject-introspection
+, gi-docgen
+}:
+
+stdenv.mkDerivation rec {
+  pname = "eog";
+  version = "45.1";
+
+  outputs = [ "out" "dev" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-wX+GcExyKzbAGhaPHlFDm+C7J58sZkb0i2bp0POiTNI=";
+  };
+
+  patches = [
+    # Fix path to libeog.so in the gir file.
+    # We patch gobject-introspection to hardcode absolute paths but
+    # our Meson patch will only pass the info when install_dir is absolute as well.
+    ./fix-gir-lib-path.patch
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    itstool
+    wrapGAppsHook
+    libxml2 # for xmllint for xml-stripblanks
+    gobject-introspection
+    gi-docgen
+  ];
+
+  buildInputs = [
+    libjpeg
+    libportal-gtk3
+    gtk3
+    libhandy
+    gdk-pixbuf
+    glib
+    libpeas
+    librsvg
+    lcms2
+    gnome-desktop
+    libexif
+    exempi
+    gsettings-desktop-schemas
+    shared-mime-info
+  ];
+
+  mesonFlags = [
+    "-Dgtk_doc=true"
+  ];
+
+  postInstall = ''
+    # Pull in WebP support for gnome-backgrounds.
+    # In postInstall to run before gappsWrapperArgsHook.
+    export GDK_PIXBUF_MODULE_FILE="${gnome._gdkPixbufCacheBuilder_DO_NOT_USE {
+      extraLoaders = [
+        librsvg
+        webp-pixbuf-loader
+        libheif.out
+      ];
+    }}"
+  '';
+
+  preFixup = ''
+    gappsWrapperArgs+=(
+      # Thumbnailers
+      --prefix XDG_DATA_DIRS : "${gdk-pixbuf}/share"
+      --prefix XDG_DATA_DIRS : "${librsvg}/share"
+      --prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
+    )
+  '';
+
+  postFixup = ''
+    # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
+    moveToOutput "share/doc" "$devdoc"
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "GNOME image viewer";
+    homepage = "https://wiki.gnome.org/Apps/EyeOfGnome";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/eog/fix-gir-lib-path.patch b/nixpkgs/pkgs/desktops/gnome/core/eog/fix-gir-lib-path.patch
new file mode 100644
index 000000000000..eb087b58a317
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/eog/fix-gir-lib-path.patch
@@ -0,0 +1,13 @@
+diff --git a/src/meson.build b/src/meson.build
+index cc9d3856..f909836d 100644
+--- a/src/meson.build
++++ b/src/meson.build
+@@ -165,7 +165,7 @@ libeog = shared_library(
+   link_args: ldflags,
+   link_depends: symbol_map,
+   install: true,
+-  install_dir: eog_pkglibdir,
++  install_dir: eog_prefix / eog_pkglibdir,
+ )
+ 
+ libeog_dep = declare_dependency(
diff --git a/nixpkgs/pkgs/desktops/gnome/core/epiphany/default.nix b/nixpkgs/pkgs/desktops/gnome/core/epiphany/default.nix
new file mode 100644
index 000000000000..900b02bc3df6
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/epiphany/default.nix
@@ -0,0 +1,108 @@
+{ lib
+, stdenv
+, meson
+, ninja
+, gettext
+, fetchurl
+, pkg-config
+, gtk4
+, glib
+, icu
+, wrapGAppsHook4
+, gnome
+, libportal-gtk4
+, libxml2
+, itstool
+, webkitgtk_6_0
+, libsoup_3
+, glib-networking
+, libsecret
+, gnome-desktop
+, libarchive
+, p11-kit
+, sqlite
+, gcr_4
+, isocodes
+, desktop-file-utils
+, nettle
+, gdk-pixbuf
+, gst_all_1
+, json-glib
+, libadwaita
+, buildPackages
+, withPantheon ? false
+, pantheon
+}:
+
+stdenv.mkDerivation rec {
+  pname = "epiphany";
+  version = "45.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "fJlO807NYOkV3jMe4SPAiTj5YjzvrabVC5njycWtgTU=";
+  };
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    gettext
+    itstool
+    meson
+    ninja
+    pkg-config
+    wrapGAppsHook4
+    buildPackages.glib
+    buildPackages.gtk4
+  ];
+
+  buildInputs = [
+    gcr_4
+    gdk-pixbuf
+    glib
+    glib-networking
+    gnome-desktop
+    gst_all_1.gst-libav
+    gst_all_1.gst-plugins-bad
+    gst_all_1.gst-plugins-base
+    gst_all_1.gst-plugins-good
+    gst_all_1.gst-plugins-ugly
+    gst_all_1.gstreamer
+    gtk4
+    icu
+    isocodes
+    json-glib
+    libadwaita
+    libportal-gtk4
+    libarchive
+    libsecret
+    libsoup_3
+    libxml2
+    nettle
+    p11-kit
+    sqlite
+    webkitgtk_6_0
+  ] ++ lib.optionals withPantheon [
+    pantheon.granite7
+  ];
+
+  # Tests need an X display
+  mesonFlags = [
+    "-Dunit_tests=disabled"
+  ] ++ lib.optionals withPantheon [
+    "-Dgranite=enabled"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Epiphany";
+    description = "WebKit based web browser for GNOME";
+    maintainers = teams.gnome.members ++ teams.pantheon.members;
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/evince/default.nix b/nixpkgs/pkgs/desktops/gnome/core/evince/default.nix
new file mode 100644
index 000000000000..a2959626c837
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/evince/default.nix
@@ -0,0 +1,145 @@
+{ lib
+, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gettext
+, libxml2
+, appstream
+, desktop-file-utils
+, glib
+, gtk3
+, pango
+, atk
+, gdk-pixbuf
+, shared-mime-info
+, itstool
+, gnome
+, poppler
+, ghostscriptX
+, djvulibre
+, libspectre
+, libarchive
+, libhandy
+, libsecret
+, wrapGAppsHook
+, librsvg
+, gobject-introspection
+, yelp-tools
+, gspell
+, gsettings-desktop-schemas
+, gnome-desktop
+, dbus
+, texlive
+, gst_all_1
+, gi-docgen
+, supportMultimedia ? true # PDF multimedia
+, libgxps
+, supportXPS ? true # Open XML Paper Specification via libgxps
+, withLibsecret ? true
+}:
+
+stdenv.mkDerivation rec {
+  pname = "evince";
+  version = "45.0";
+
+  outputs = [ "out" "dev" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/evince/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "0YZH1Cdcvd8NMoF7HQTjBzQqhb6RTsTa0tgIKq+KpKg=";
+  };
+
+  depsBuildBuild = [
+    pkg-config
+  ];
+
+  nativeBuildInputs = [
+    appstream
+    desktop-file-utils
+    gettext
+    gobject-introspection
+    gi-docgen
+    itstool
+    meson
+    ninja
+    pkg-config
+    wrapGAppsHook
+    yelp-tools
+  ];
+
+  buildInputs = [
+    atk
+    dbus # only needed to find the service directory
+    djvulibre
+    gdk-pixbuf
+    ghostscriptX
+    glib
+    gnome-desktop
+    gsettings-desktop-schemas
+    gspell
+    gtk3
+    libarchive
+    libhandy
+    librsvg
+    libspectre
+    libxml2
+    pango
+    poppler
+    texlive.bin.core # kpathsea for DVI support
+  ] ++ lib.optionals withLibsecret [
+    libsecret
+  ] ++ lib.optionals supportXPS [
+    libgxps
+  ] ++ lib.optionals supportMultimedia (with gst_all_1; [
+    gstreamer
+    gst-plugins-base
+    gst-plugins-good
+    gst-plugins-bad
+    gst-plugins-ugly
+    gst-libav
+  ]);
+
+  mesonFlags = [
+    "-Dnautilus=false"
+    "-Dps=enabled"
+  ] ++ lib.optionals (!withLibsecret) [
+    "-Dkeyring=disabled"
+  ] ++ lib.optionals (!supportMultimedia) [
+    "-Dmultimedia=disabled"
+  ];
+
+  env.NIX_CFLAGS_COMPILE = "-I${glib.dev}/include/gio-unix-2.0";
+
+  preFixup = ''
+    gappsWrapperArgs+=(--prefix XDG_DATA_DIRS : "${shared-mime-info}/share")
+  '';
+
+  postFixup = ''
+    # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
+    moveToOutput "share/doc" "$devdoc"
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Evince";
+    description = "GNOME's document viewer";
+
+    longDescription = ''
+      Evince is a document viewer for multiple document formats.  It
+      currently supports PDF, PostScript, DjVu, TIFF and DVI.  The goal
+      of Evince is to replace the multiple document viewers that exist
+      on the GNOME Desktop with a single simple application.
+    '';
+
+    license = licenses.gpl2Plus;
+    platforms = platforms.unix;
+    maintainers = teams.gnome.members ++ teams.pantheon.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/default.nix b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/default.nix
new file mode 100644
index 000000000000..f372f688eabc
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/default.nix
@@ -0,0 +1,192 @@
+{ stdenv
+, lib
+, fetchurl
+, substituteAll
+, pkg-config
+, gnome
+, _experimental-update-script-combinators
+, python3
+, gobject-introspection
+, gettext
+, libsoup_3
+, libxml2
+, libsecret
+, icu
+, sqlite
+, tzdata
+, libcanberra-gtk3
+, p11-kit
+, db
+, nspr
+, nss
+, libical
+, gperf
+, wrapGAppsHook
+, glib-networking
+, gsettings-desktop-schemas
+, pcre
+, vala
+, cmake
+, ninja
+, libkrb5
+, openldap
+, enableOAuth2 ? stdenv.isLinux
+, webkitgtk_4_1
+, webkitgtk_6_0
+, libaccounts-glib
+, json-glib
+, glib
+, gtk3
+, gtk4
+, withGtk3 ? true
+, withGtk4 ? false
+, libphonenumber
+, gnome-online-accounts
+, libgweather
+, boost
+, protobuf
+, libiconv
+, makeHardcodeGsettingsPatch
+}:
+
+stdenv.mkDerivation rec {
+  pname = "evolution-data-server";
+  version = "3.50.1";
+
+  outputs = [ "out" "dev" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/evolution-data-server/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "kfT/w4objS/ok5g0RJrFQcC/9KObRE7cKpUpNEoo6Yo=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit tzdata;
+    })
+
+    # Avoid using wrapper function, which the hardcode gsettings
+    # patch generator cannot handle.
+    ./drop-tentative-settings-constructor.patch
+  ];
+
+  prePatch = ''
+    substitute ${./hardcode-gsettings.patch} hardcode-gsettings.patch \
+      --subst-var-by EDS ${glib.makeSchemaPath "$out" "${pname}-${version}"} \
+      --subst-var-by GDS ${glib.getSchemaPath gsettings-desktop-schemas}
+    patches="$patches $PWD/hardcode-gsettings.patch"
+  '';
+
+  nativeBuildInputs = [
+    cmake
+    ninja
+    pkg-config
+    gettext
+    python3
+    gperf
+    wrapGAppsHook
+    gobject-introspection
+    vala
+  ];
+
+  buildInputs = [
+    glib
+    libsecret
+    libsoup_3
+    gnome-online-accounts
+    p11-kit
+    libgweather
+    icu
+    sqlite
+    libkrb5
+    openldap
+    glib-networking
+    libcanberra-gtk3
+    pcre
+    libphonenumber
+    boost
+    protobuf
+  ] ++ lib.optionals stdenv.isLinux [
+    libaccounts-glib
+  ] ++ lib.optionals stdenv.isDarwin [
+    libiconv
+  ] ++ lib.optionals withGtk3 [
+    gtk3
+  ] ++ lib.optionals (withGtk3 && enableOAuth2) [
+    webkitgtk_4_1
+  ] ++ lib.optionals withGtk4 [
+    gtk4
+  ] ++ lib.optionals (withGtk4 && enableOAuth2) [
+    webkitgtk_6_0
+  ];
+
+  propagatedBuildInputs = [
+    db
+    nss
+    nspr
+    libical
+    libsoup_3
+    libxml2
+    json-glib
+  ];
+
+  cmakeFlags = [
+    "-DENABLE_UOA=OFF"
+    "-DENABLE_VALA_BINDINGS=ON"
+    "-DENABLE_INTROSPECTION=ON"
+    "-DINCLUDE_INSTALL_DIR=${placeholder "dev"}/include"
+    "-DWITH_PHONENUMBER=ON"
+    "-DENABLE_GTK=${lib.boolToString withGtk3}"
+    "-DENABLE_EXAMPLES=${lib.boolToString withGtk3}"
+    "-DENABLE_CANBERRA=${lib.boolToString withGtk3}"
+    "-DENABLE_GTK4=${lib.boolToString withGtk4}"
+    "-DENABLE_OAUTH2_WEBKITGTK=${lib.boolToString (withGtk3 && enableOAuth2)}"
+    "-DENABLE_OAUTH2_WEBKITGTK4=${lib.boolToString (withGtk4 && enableOAuth2)}"
+  ];
+
+  postPatch = lib.optionalString stdenv.isDarwin ''
+    substituteInPlace cmake/modules/SetupBuildFlags.cmake \
+      --replace "-Wl,--no-undefined" ""
+    substituteInPlace src/services/evolution-alarm-notify/e-alarm-notify.c \
+      --replace "G_OS_WIN32" "__APPLE__"
+  '';
+
+  postInstall = lib.optionalString stdenv.isDarwin ''
+    ln -s $out/lib/${pname}/*.dylib $out/lib/
+  '';
+
+  passthru = {
+    hardcodeGsettingsPatch = makeHardcodeGsettingsPatch {
+      schemaIdToVariableMapping = {
+        "org.gnome.Evolution.DefaultSources" = "EDS";
+        "org.gnome.evolution.shell.network-config" = "EDS";
+        "org.gnome.evolution-data-server.addressbook" = "EDS";
+        "org.gnome.evolution-data-server.calendar" = "EDS";
+        "org.gnome.evolution-data-server" = "EDS";
+        "org.gnome.desktop.interface" = "GDS";
+      };
+      inherit src patches;
+    };
+    updateScript =
+      let
+        updateSource = gnome.updateScript {
+          packageName = "evolution-data-server";
+          versionPolicy = "odd-unstable";
+        };
+        updatePatch = _experimental-update-script-combinators.copyAttrOutputToFile "evolution-data-server.hardcodeGsettingsPatch" ./hardcode-gsettings.patch;
+      in
+      _experimental-update-script-combinators.sequence [
+        updateSource
+        updatePatch
+      ];
+  };
+
+  meta = with lib; {
+    description = "Unified backend for programs that work with contacts, tasks, and calendar information";
+    homepage = "https://wiki.gnome.org/Apps/Evolution";
+    license = licenses.lgpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/drop-tentative-settings-constructor.patch b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/drop-tentative-settings-constructor.patch
new file mode 100644
index 000000000000..a86d1966eb6b
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/drop-tentative-settings-constructor.patch
@@ -0,0 +1,40 @@
+diff --git a/src/calendar/libecal/e-reminder-watcher.c b/src/calendar/libecal/e-reminder-watcher.c
+index f1614f2..c01e8b2 100644
+--- a/src/calendar/libecal/e-reminder-watcher.c
++++ b/src/calendar/libecal/e-reminder-watcher.c
+@@ -2609,26 +2609,6 @@ e_reminder_watcher_load_clock_format (EReminderWatcher *watcher)
+ 	g_free (clock_format);
+ }
+ 
+-static GSettings*
+-e_reminder_watcher_load_settings_tentative (const gchar *schema_id)
+-{
+-	GSettings *settings;
+-	GSettingsSchemaSource *schema_source;
+-	GSettingsSchema *schema;
+-
+-	schema_source = g_settings_schema_source_get_default ();
+-	schema = g_settings_schema_source_lookup (schema_source, schema_id, TRUE);
+-
+-	if (schema == NULL) {
+-		return NULL;
+-	}
+-
+-	settings = g_settings_new (schema_id);
+-	/* only unref after g_settings_new() to avoid needless realloc */
+-	g_settings_schema_unref (schema);
+-	return settings;
+-}
+-
+ static void
+ e_reminder_watcher_init (EReminderWatcher *watcher)
+ {
+@@ -2647,7 +2627,7 @@ e_reminder_watcher_init (EReminderWatcher *watcher)
+ 	watcher->priv = e_reminder_watcher_get_instance_private (watcher);
+ 	watcher->priv->cancellable = g_cancellable_new ();
+ 	watcher->priv->settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
+-	watcher->priv->desktop_settings = e_reminder_watcher_load_settings_tentative ("org.gnome.desktop.interface");
++	watcher->priv->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
+ 	if (watcher->priv->desktop_settings) {
+ 		g_signal_connect_object (
+ 			watcher->priv->desktop_settings,
diff --git a/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/fix-paths.patch
new file mode 100644
index 000000000000..334235516591
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/fix-paths.patch
@@ -0,0 +1,11 @@
+--- a/src/calendar/libecal/e-cal-system-timezone.c
++++ b/src/calendar/libecal/e-cal-system-timezone.c
+@@ -26,7 +26,7 @@
+ #ifdef HAVE_SOLARIS
+ #define SYSTEM_ZONEINFODIR "/usr/share/lib/zoneinfo/tab"
+ #else
+-#define SYSTEM_ZONEINFODIR "/usr/share/zoneinfo"
++#define SYSTEM_ZONEINFODIR "@tzdata@/share/zoneinfo"
+ #endif
+ 
+ #define ETC_TIMEZONE        "/etc/timezone"
diff --git a/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/hardcode-gsettings.patch b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/hardcode-gsettings.patch
new file mode 100644
index 000000000000..4857efc4c230
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/evolution-data-server/hardcode-gsettings.patch
@@ -0,0 +1,652 @@
+diff --git a/src/addressbook/libebook/e-book-client.c b/src/addressbook/libebook/e-book-client.c
+index bd479d8..bd049b3 100644
+--- a/src/addressbook/libebook/e-book-client.c
++++ b/src/addressbook/libebook/e-book-client.c
+@@ -1997,7 +1997,18 @@ e_book_client_get_self (ESourceRegistry *registry,
+ 
+ 	*out_client = book_client;
+ 
+-	settings = g_settings_new (SELF_UID_PATH_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	uid = g_settings_get_string (settings, SELF_UID_KEY);
+ 	g_object_unref (settings);
+ 
+@@ -2065,7 +2076,18 @@ e_book_client_set_self (EBookClient *client,
+ 	g_return_val_if_fail (
+ 		e_contact_get_const (contact, E_CONTACT_UID) != NULL, FALSE);
+ 
+-	settings = g_settings_new (SELF_UID_PATH_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	g_settings_set_string (
+ 		settings, SELF_UID_KEY,
+ 		e_contact_get_const (contact, E_CONTACT_UID));
+@@ -2101,8 +2123,18 @@ e_book_client_is_self (EContact *contact)
+ 	 * unfortunately the API doesn't allow that.
+ 	 */
+ 	g_mutex_lock (&mutex);
+-	if (!settings)
+-		settings = g_settings_new (SELF_UID_PATH_ID);
++	if (!settings) {
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	uid = g_settings_get_string (settings, SELF_UID_KEY);
+ 	g_mutex_unlock (&mutex);
+ 
+diff --git a/src/addressbook/libebook/e-book.c b/src/addressbook/libebook/e-book.c
+index e85a56b..59d3fe2 100644
+--- a/src/addressbook/libebook/e-book.c
++++ b/src/addressbook/libebook/e-book.c
+@@ -2587,7 +2587,18 @@ e_book_get_self (ESourceRegistry *registry,
+ 		return FALSE;
+ 	}
+ 
+-	settings = g_settings_new (SELF_UID_PATH_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	uid = g_settings_get_string (settings, SELF_UID_KEY);
+ 	g_object_unref (settings);
+ 
+@@ -2642,7 +2653,18 @@ e_book_set_self (EBook *book,
+ 	g_return_val_if_fail (E_IS_BOOK (book), FALSE);
+ 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
+ 
+-	settings = g_settings_new (SELF_UID_PATH_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	g_settings_set_string (
+ 		settings, SELF_UID_KEY,
+ 		e_contact_get_const (contact, E_CONTACT_UID));
+@@ -2670,7 +2692,18 @@ e_book_is_self (EContact *contact)
+ 
+ 	g_return_val_if_fail (E_IS_CONTACT (contact), FALSE);
+ 
+-	settings = g_settings_new (SELF_UID_PATH_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 SELF_UID_PATH_ID,
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	uid = g_settings_get_string (settings, SELF_UID_KEY);
+ 	g_object_unref (settings);
+ 
+diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c b/src/addressbook/libedata-book/e-book-meta-backend.c
+index 63e1016..0492756 100644
+--- a/src/addressbook/libedata-book/e-book-meta-backend.c
++++ b/src/addressbook/libedata-book/e-book-meta-backend.c
+@@ -144,7 +144,18 @@ ebmb_is_power_saver_enabled (void)
+ 	GSettings *settings;
+ 	gboolean enabled = FALSE;
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 
+ 	if (g_settings_get_boolean (settings, "limit-operations-in-power-saver-mode")) {
+ 		GPowerProfileMonitor *power_monitor;
+diff --git a/src/calendar/backends/contacts/e-cal-backend-contacts.c b/src/calendar/backends/contacts/e-cal-backend-contacts.c
+index 42f3457..b4926af 100644
+--- a/src/calendar/backends/contacts/e-cal-backend-contacts.c
++++ b/src/calendar/backends/contacts/e-cal-backend-contacts.c
+@@ -1387,7 +1387,18 @@ e_cal_backend_contacts_init (ECalBackendContacts *cbc)
+ 		(GDestroyNotify) g_free,
+ 		(GDestroyNotify) contact_record_free);
+ 
+-	cbc->priv->settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server.calendar",
++							 FALSE);
++		cbc->priv->settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	cbc->priv->notifyid = 0;
+ 	cbc->priv->update_alarms_id = 0;
+ 	cbc->priv->alarm_enabled = FALSE;
+diff --git a/src/calendar/backends/file/e-cal-backend-file.c b/src/calendar/backends/file/e-cal-backend-file.c
+index 2525856..7ecc1a8 100644
+--- a/src/calendar/backends/file/e-cal-backend-file.c
++++ b/src/calendar/backends/file/e-cal-backend-file.c
+@@ -3682,7 +3682,20 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend,
+ 			if (is_declined) {
+ 				GSettings *settings;
+ 
+-				settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
++				{
++					g_autoptr(GSettingsSchemaSource) schema_source;
++					g_autoptr(GSettingsSchema) schema;
++					schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++												    g_settings_schema_source_get_default(),
++												    TRUE,
++												    NULL);
++					schema = g_settings_schema_source_lookup(schema_source,
++										 "org.gnome.evolution-data-server.calendar",
++										 FALSE);
++					settings = g_settings_new_full(schema,
++								       NULL,
++								       NULL);
++				}
+ 				can_delete = g_settings_get_boolean (settings, "delete-meeting-on-decline");
+ 				g_clear_object (&settings);
+ 			}
+diff --git a/src/calendar/libecal/e-reminder-watcher.c b/src/calendar/libecal/e-reminder-watcher.c
+index c01e8b2..59fb4c4 100644
+--- a/src/calendar/libecal/e-reminder-watcher.c
++++ b/src/calendar/libecal/e-reminder-watcher.c
+@@ -2626,8 +2626,33 @@ e_reminder_watcher_init (EReminderWatcher *watcher)
+ 
+ 	watcher->priv = e_reminder_watcher_get_instance_private (watcher);
+ 	watcher->priv->cancellable = g_cancellable_new ();
+-	watcher->priv->settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
+-	watcher->priv->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server.calendar",
++							 FALSE);
++		watcher->priv->settings = g_settings_new_full(schema, NULL,
++							      NULL);
++	}
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@GDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.desktop.interface",
++							 FALSE);
++		watcher->priv->desktop_settings = g_settings_new_full(schema,
++								      NULL,
++								      NULL);
++	}
+ 	if (watcher->priv->desktop_settings) {
+ 		g_signal_connect_object (
+ 			watcher->priv->desktop_settings,
+diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c
+index 27fa153..3679d72 100644
+--- a/src/calendar/libedata-cal/e-cal-meta-backend.c
++++ b/src/calendar/libedata-cal/e-cal-meta-backend.c
+@@ -156,7 +156,18 @@ ecmb_is_power_saver_enabled (void)
+ 	GSettings *settings;
+ 	gboolean enabled = FALSE;
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 
+ 	if (g_settings_get_boolean (settings, "limit-operations-in-power-saver-mode")) {
+ 		GPowerProfileMonitor *power_monitor;
+@@ -2633,7 +2644,20 @@ ecmb_receive_object_sync (ECalMetaBackend *meta_backend,
+ 			if (is_declined) {
+ 				GSettings *settings;
+ 
+-				settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
++				{
++					g_autoptr(GSettingsSchemaSource) schema_source;
++					g_autoptr(GSettingsSchema) schema;
++					schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++												    g_settings_schema_source_get_default(),
++												    TRUE,
++												    NULL);
++					schema = g_settings_schema_source_lookup(schema_source,
++										 "org.gnome.evolution-data-server.calendar",
++										 FALSE);
++					settings = g_settings_new_full(schema,
++								       NULL,
++								       NULL);
++				}
+ 				is_declined = g_settings_get_boolean (settings, "delete-meeting-on-decline");
+ 				g_clear_object (&settings);
+ 			}
+diff --git a/src/camel/camel-cipher-context.c b/src/camel/camel-cipher-context.c
+index bef9188..ce92f6c 100644
+--- a/src/camel/camel-cipher-context.c
++++ b/src/camel/camel-cipher-context.c
+@@ -1631,7 +1631,18 @@ camel_cipher_can_load_photos (void)
+ 	GSettings *settings;
+ 	gboolean load_photos;
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	load_photos = g_settings_get_boolean (settings, "camel-cipher-load-photos");
+ 	g_clear_object (&settings);
+ 
+diff --git a/src/camel/camel-gpg-context.c b/src/camel/camel-gpg-context.c
+index db5fc2e..162e00f 100644
+--- a/src/camel/camel-gpg-context.c
++++ b/src/camel/camel-gpg-context.c
+@@ -747,7 +747,18 @@ gpg_ctx_get_executable_name (void)
+ 		GSettings *settings;
+ 		gchar *path;
+ 
+-		settings = g_settings_new ("org.gnome.evolution-data-server");
++		{
++			g_autoptr(GSettingsSchemaSource) schema_source;
++			g_autoptr(GSettingsSchema) schema;
++			schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++										    g_settings_schema_source_get_default(),
++										    TRUE,
++										    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 "org.gnome.evolution-data-server",
++								 FALSE);
++			settings = g_settings_new_full(schema, NULL, NULL);
++		}
+ 		path = g_settings_get_string (settings, "camel-gpg-binary");
+ 		g_clear_object (&settings);
+ 
+diff --git a/src/camel/camel-utils.c b/src/camel/camel-utils.c
+index e61160c..b6553a4 100644
+--- a/src/camel/camel-utils.c
++++ b/src/camel/camel-utils.c
+@@ -362,7 +362,19 @@ void
+ _camel_utils_initialize (void)
+ {
+ 	G_LOCK (mi_user_headers);
+-	mi_user_headers_settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		mi_user_headers_settings = g_settings_new_full(schema, NULL,
++							       NULL);
++	}
+ 	g_signal_connect (mi_user_headers_settings, "changed::camel-message-info-user-headers",
+ 		G_CALLBACK (mi_user_headers_settings_changed_cb), NULL);
+ 	G_UNLOCK (mi_user_headers);
+diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
+index ef34665..59f294b 100644
+--- a/src/camel/providers/imapx/camel-imapx-server.c
++++ b/src/camel/providers/imapx/camel-imapx-server.c
+@@ -5627,7 +5627,18 @@ camel_imapx_server_do_old_flags_update (CamelFolder *folder)
+ 	if (do_old_flags_update) {
+ 		GSettings *eds_settings;
+ 
+-		eds_settings = g_settings_new ("org.gnome.evolution-data-server");
++		{
++			g_autoptr(GSettingsSchemaSource) schema_source;
++			g_autoptr(GSettingsSchema) schema;
++			schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++										    g_settings_schema_source_get_default(),
++										    TRUE,
++										    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 "org.gnome.evolution-data-server",
++								 FALSE);
++			eds_settings = g_settings_new_full(schema, NULL, NULL);
++		}
+ 
+ 		if (g_settings_get_boolean (eds_settings, "limit-operations-in-power-saver-mode")) {
+ 			GPowerProfileMonitor *power_monitor;
+diff --git a/src/camel/providers/smtp/camel-smtp-transport.c b/src/camel/providers/smtp/camel-smtp-transport.c
+index 6556f1e..90f0a5e 100644
+--- a/src/camel/providers/smtp/camel-smtp-transport.c
++++ b/src/camel/providers/smtp/camel-smtp-transport.c
+@@ -1471,7 +1471,18 @@ smtp_helo (CamelSmtpTransport *transport,
+ 		transport->authtypes = NULL;
+ 	}
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	name = g_settings_get_string (settings, "camel-smtp-helo-argument");
+ 	g_clear_object (&settings);
+ 
+diff --git a/src/libedataserver/e-network-monitor.c b/src/libedataserver/e-network-monitor.c
+index 188f276..939f89b 100644
+--- a/src/libedataserver/e-network-monitor.c
++++ b/src/libedataserver/e-network-monitor.c
+@@ -256,7 +256,18 @@ e_network_monitor_constructed (GObject *object)
+ 	/* Chain up to parent's method. */
+ 	G_OBJECT_CLASS (e_network_monitor_parent_class)->constructed (object);
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	g_settings_bind (
+ 		settings, "network-monitor-gio-name",
+ 		object, "gio-name",
+diff --git a/src/libedataserver/e-oauth2-service-google.c b/src/libedataserver/e-oauth2-service-google.c
+index ec08afe..7b31227 100644
+--- a/src/libedataserver/e-oauth2-service-google.c
++++ b/src/libedataserver/e-oauth2-service-google.c
+@@ -71,7 +71,18 @@ eos_google_read_settings (EOAuth2Service *service,
+ 	if (!value) {
+ 		GSettings *settings;
+ 
+-		settings = g_settings_new ("org.gnome.evolution-data-server");
++		{
++			g_autoptr(GSettingsSchemaSource) schema_source;
++			g_autoptr(GSettingsSchema) schema;
++			schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++										    g_settings_schema_source_get_default(),
++										    TRUE,
++										    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 "org.gnome.evolution-data-server",
++								 FALSE);
++			settings = g_settings_new_full(schema, NULL, NULL);
++		}
+ 		value = g_settings_get_string (settings, key_name);
+ 		g_object_unref (settings);
+ 
+diff --git a/src/libedataserver/e-oauth2-service-outlook.c b/src/libedataserver/e-oauth2-service-outlook.c
+index 7633e93..2328048 100644
+--- a/src/libedataserver/e-oauth2-service-outlook.c
++++ b/src/libedataserver/e-oauth2-service-outlook.c
+@@ -71,7 +71,18 @@ eos_outlook_read_settings (EOAuth2Service *service,
+ 	if (!value) {
+ 		GSettings *settings;
+ 
+-		settings = g_settings_new ("org.gnome.evolution-data-server");
++		{
++			g_autoptr(GSettingsSchemaSource) schema_source;
++			g_autoptr(GSettingsSchema) schema;
++			schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++										    g_settings_schema_source_get_default(),
++										    TRUE,
++										    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 "org.gnome.evolution-data-server",
++								 FALSE);
++			settings = g_settings_new_full(schema, NULL, NULL);
++		}
+ 		value = g_settings_get_string (settings, key_name);
+ 		g_object_unref (settings);
+ 
+diff --git a/src/libedataserver/e-oauth2-service-yahoo.c b/src/libedataserver/e-oauth2-service-yahoo.c
+index 3bb1071..199e822 100644
+--- a/src/libedataserver/e-oauth2-service-yahoo.c
++++ b/src/libedataserver/e-oauth2-service-yahoo.c
+@@ -67,7 +67,18 @@ eos_yahoo_read_settings (EOAuth2Service *service,
+ 	if (!value) {
+ 		GSettings *settings;
+ 
+-		settings = g_settings_new ("org.gnome.evolution-data-server");
++		{
++			g_autoptr(GSettingsSchemaSource) schema_source;
++			g_autoptr(GSettingsSchema) schema;
++			schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++										    g_settings_schema_source_get_default(),
++										    TRUE,
++										    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 "org.gnome.evolution-data-server",
++								 FALSE);
++			settings = g_settings_new_full(schema, NULL, NULL);
++		}
+ 		value = g_settings_get_string (settings, key_name);
+ 		g_object_unref (settings);
+ 
+diff --git a/src/libedataserver/e-oauth2-service.c b/src/libedataserver/e-oauth2-service.c
+index 2364f3e..e8f59f2 100644
+--- a/src/libedataserver/e-oauth2-service.c
++++ b/src/libedataserver/e-oauth2-service.c
+@@ -94,7 +94,18 @@ eos_default_guess_can_process (EOAuth2Service *service,
+ 	name_len = strlen (name);
+ 	hostname_len = strlen (hostname);
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 	values = g_settings_get_strv (settings, "oauth2-services-hint");
+ 	g_object_unref (settings);
+ 
+diff --git a/src/libedataserver/e-source-registry.c b/src/libedataserver/e-source-registry.c
+index 4a9b398..e7cb404 100644
+--- a/src/libedataserver/e-source-registry.c
++++ b/src/libedataserver/e-source-registry.c
+@@ -1773,7 +1773,19 @@ e_source_registry_init (ESourceRegistry *registry)
+ 
+ 	g_mutex_init (&registry->priv->sources_lock);
+ 
+-	registry->priv->settings = g_settings_new (GSETTINGS_SCHEMA);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 GSETTINGS_SCHEMA,
++							 FALSE);
++		registry->priv->settings = g_settings_new_full(schema, NULL,
++							       NULL);
++	}
+ 
+ 	g_signal_connect (
+ 		registry->priv->settings, "changed",
+diff --git a/src/libedataserverui/e-reminders-widget.c b/src/libedataserverui/e-reminders-widget.c
+index 14b6481..7149b74 100644
+--- a/src/libedataserverui/e-reminders-widget.c
++++ b/src/libedataserverui/e-reminders-widget.c
+@@ -1986,7 +1986,19 @@ static void
+ e_reminders_widget_init (ERemindersWidget *reminders)
+ {
+ 	reminders->priv = e_reminders_widget_get_instance_private (reminders);
+-	reminders->priv->settings = g_settings_new ("org.gnome.evolution-data-server.calendar");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server.calendar",
++							 FALSE);
++		reminders->priv->settings = g_settings_new_full(schema, NULL,
++								NULL);
++	}
+ 	reminders->priv->cancellable = g_cancellable_new ();
+ 	reminders->priv->is_empty = TRUE;
+ 	reminders->priv->is_mapped = FALSE;
+diff --git a/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c b/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
+index 6f03053..b5db6b2 100644
+--- a/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
++++ b/src/services/evolution-source-registry/evolution-source-registry-autoconfig.c
+@@ -706,7 +706,18 @@ evolution_source_registry_merge_autoconfig_sources (ESourceRegistryServer *serve
+ 	gchar *autoconfig_directory;
+ 	gint ii;
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 
+ 	autoconfig_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, e_autoconfig_free_merge_source_data);
+ 
+diff --git a/src/services/evolution-source-registry/evolution-source-registry-migrate-proxies.c b/src/services/evolution-source-registry/evolution-source-registry-migrate-proxies.c
+index d531cb9..c96f1d5 100644
+--- a/src/services/evolution-source-registry/evolution-source-registry-migrate-proxies.c
++++ b/src/services/evolution-source-registry/evolution-source-registry-migrate-proxies.c
+@@ -61,7 +61,18 @@ evolution_source_registry_migrate_proxies (ESourceRegistryServer *server)
+ 	extension_name = E_SOURCE_EXTENSION_PROXY;
+ 	extension = e_source_get_extension (source, extension_name);
+ 
+-	settings = g_settings_new (NETWORK_CONFIG_SCHEMA_ID);
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++			schema = g_settings_schema_source_lookup(schema_source,
++								 NETWORK_CONFIG_SCHEMA_ID,
++								 FALSE);
++			settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 
+ 	switch (g_settings_get_int (settings, "proxy-type")) {
+ 		case 1:
+diff --git a/src/services/evolution-source-registry/evolution-source-registry.c b/src/services/evolution-source-registry/evolution-source-registry.c
+index 1c0a113..6b41423 100644
+--- a/src/services/evolution-source-registry/evolution-source-registry.c
++++ b/src/services/evolution-source-registry/evolution-source-registry.c
+@@ -181,7 +181,18 @@ main (gint argc,
+ 
+ reload:
+ 
+-	settings = g_settings_new ("org.gnome.evolution-data-server");
++	{
++		g_autoptr(GSettingsSchemaSource) schema_source;
++		g_autoptr(GSettingsSchema) schema;
++		schema_source = g_settings_schema_source_new_from_directory("@EDS@",
++									    g_settings_schema_source_get_default(),
++									    TRUE,
++									    NULL);
++		schema = g_settings_schema_source_lookup(schema_source,
++							 "org.gnome.evolution-data-server",
++							 FALSE);
++		settings = g_settings_new_full(schema, NULL, NULL);
++	}
+ 
+ 	if (!opt_disable_migration && !g_settings_get_boolean (settings, "migrated")) {
+ 		g_settings_set_boolean (settings, "migrated", TRUE);
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gdm/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gdm/default.nix
new file mode 100644
index 000000000000..f44278f896c3
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gdm/default.nix
@@ -0,0 +1,194 @@
+{ lib
+, stdenv
+, fetchurl
+, fetchpatch
+, substituteAll
+, meson
+, ninja
+, rsync
+, pkg-config
+, glib
+, itstool
+, xorg
+, accountsservice
+, libX11
+, gnome
+, systemd
+, dconf
+, gtk3
+, libcanberra-gtk3
+, pam
+, libgudev
+, libselinux
+, keyutils
+, audit
+, gobject-introspection
+, plymouth
+, coreutils
+, xorgserver
+, xwayland
+, dbus
+, nixos-icons
+, runCommand
+}:
+
+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 (finalAttrs: {
+  pname = "gdm";
+  version = "45.0.1";
+
+  outputs = [ "out" "dev" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gdm/${lib.versions.major finalAttrs.version}/${finalAttrs.pname}-${finalAttrs.version}.tar.xz";
+    sha256 = "ZXJXjAXjxladbtJp994qrzoDVldlRYbYJDkHu3pv+oU=";
+  };
+
+  mesonFlags = [
+    "-Dgdm-xsession=true"
+    # TODO: Setup a default-path? https://gitlab.gnome.org/GNOME/gdm/-/blob/6fc40ac6aa37c8ad87c32f0b1a5d813d34bf7770/meson_options.txt#L6
+    "-Dinitial-vt=${finalAttrs.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
+    rsync
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    accountsservice
+    audit
+    glib
+    gtk3
+    keyutils
+    libX11
+    libcanberra-gtk3
+    libgudev
+    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 xorgserver 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 = ''
+    # 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 $(getAllOutputNames); do
+        if [[ "$o" = "debug" ]]; then continue; fi
+        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";
+
+  separateDebugInfo = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gdm";
+      attrPath = "gnome.gdm";
+    };
+
+    # Used in GDM NixOS module
+    # Don't remove.
+    initialVT = "7";
+    dconfDb = "${finalAttrs.finalPackage}/share/gdm/greeter-dconf-defaults";
+    dconfProfile = "user-db:user\nfile-db:${finalAttrs.passthru.dconfDb}";
+
+    tests = {
+      profile = runCommand "gdm-profile-test" { } ''
+        if test "${finalAttrs.passthru.dconfProfile}" != "$(cat ${finalAttrs.finalPackage}/share/dconf/profile/gdm)"; then
+          echo "GDM dconf profile changed, please update gdm.nix"
+          exit 1
+        fi
+        touch $out
+      '';
+    };
+  };
+
+  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/nixpkgs/pkgs/desktops/gnome/core/gdm/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gdm/fix-paths.patch
new file mode 100644
index 000000000000..980627c78d46
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gdm/fix-paths.patch
@@ -0,0 +1,93 @@
+diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
+index 5fbbad68..739718ec 100644
+--- a/daemon/gdm-local-display-factory.c
++++ b/daemon/gdm-local-display-factory.c
+@@ -233,9 +233,9 @@ struct GdmDisplayServerConfiguration {
+         const char *session_type;
+ } display_server_configuration[] = {
+ #ifdef ENABLE_WAYLAND_SUPPORT
+-        { "wayland", GDM_KEY_WAYLAND_ENABLE, "/usr/bin/Xwayland", "wayland" },
++        { "wayland", GDM_KEY_WAYLAND_ENABLE, "@xwayland@/bin/Xwayland", "wayland" },
+ #endif
+-        { "xorg", GDM_KEY_XORG_ENABLE, "/usr/bin/Xorg", "x11" },
++        { "xorg", GDM_KEY_XORG_ENABLE, "@xorgserver@/bin/Xorg", "x11" },
+         { NULL, NULL, NULL },
+ };
+ 
+diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
+index cc61efc9..4c9d15af 100644
+--- a/daemon/gdm-manager.c
++++ b/daemon/gdm-manager.c
+@@ -148,7 +148,7 @@ plymouth_is_running (void)
+         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);
+@@ -166,7 +166,7 @@ plymouth_prepare_for_transition (void)
+         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);
+@@ -181,7 +181,7 @@ plymouth_quit_with_transition (void)
+         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);
+@@ -197,7 +197,7 @@ plymouth_quit_without_transition (void)
+         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);
+diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
+index 4b709731..245ac0cf 100644
+--- a/daemon/gdm-session.c
++++ b/daemon/gdm-session.c
+@@ -2972,16 +2972,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/data/gdm.service.in b/data/gdm.service.in
+index 17e8a8de..afc70977 100644
+--- 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]
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch b/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-session-worker_forward-vars.patch
new file mode 100644
index 000000000000..401b6aea0c28
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch b/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_extra_args.patch
new file mode 100644
index 000000000000..66071aa4af80
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch b/nixpkgs/pkgs/desktops/gnome/core/gdm/gdm-x-session_session-wrapper.patch
new file mode 100644
index 000000000000..58481f0730fa
--- /dev/null
+++ b/nixpkgs/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/nixpkgs/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override b/nixpkgs/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override
new file mode 100644
index 000000000000..8c17f494b0f2
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gdm/org.gnome.login-screen.gschema.override
@@ -0,0 +1,2 @@
+[org.gnome.login-screen]
+logo='@icon@'
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gdm/reset-environment.patch b/nixpkgs/pkgs/desktops/gnome/core/gdm/reset-environment.patch
new file mode 100644
index 000000000000..61defd9c4bc2
--- /dev/null
+++ b/nixpkgs/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");
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/default.nix
new file mode 100644
index 000000000000..808ff7c0c293
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/default.nix
@@ -0,0 +1,44 @@
+{ stdenv
+, lib
+, fetchurl
+, meson
+, ninja
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-backgrounds";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-backgrounds/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "zuDmiPuuXvenXzNa2i0Qd54I68qURfFYbeMsWptt7i0=";
+  };
+
+  patches = [
+    # Makes the database point to stable paths in /run/current-system/sw/share, which don't decay whenever this package's hash changes.
+    # This assumes a nixos + gnome system, where this package is installed in environment.systemPackages,
+    # and /share outputs are included in environment.pathsToLink.
+    ./stable-dir.patch
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-backgrounds";
+      attrPath = "gnome.gnome-backgrounds";
+    };
+  };
+
+  meta = with lib; {
+    description = "Default wallpaper set for GNOME";
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-backgrounds";
+    license = licenses.cc-by-sa-30;
+    platforms = platforms.unix;
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/stable-dir.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/stable-dir.patch
new file mode 100644
index 000000000000..cbc55e8a5c01
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-backgrounds/stable-dir.patch
@@ -0,0 +1,9 @@
+diff --git a/backgrounds/meson.build b/backgrounds/meson.build
+index 2175a16..cf521df 100644
+--- a/backgrounds/meson.build
++++ b/backgrounds/meson.build
+@@ -1,5 +1,5 @@
+ dataconf = configuration_data()
+-dataconf.set('BACKGROUNDDIR', backgrounddir)
++dataconf.set('BACKGROUNDDIR', '/run/current-system/sw/share/backgrounds/gnome')
+ dataconf.set('datadir', datadir)
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/1.0/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/1.0/default.nix
new file mode 100644
index 000000000000..38bb96980dca
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/1.0/default.nix
@@ -0,0 +1,97 @@
+{ stdenv
+, lib
+, fetchurl
+, fetchpatch
+, gnome
+, meson
+, ninja
+, pkg-config
+, gtk3
+, gettext
+, glib
+, udev
+, itstool
+, libxml2
+, wrapGAppsHook
+, libnotify
+, libcanberra-gtk3
+, gobject-introspection
+, gtk-doc
+, docbook-xsl-nons
+, docbook_xml_dtd_43
+, python3
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-bluetooth";
+  version = "3.34.5";
+
+  # TODO: split out "lib"
+  outputs = [ "out" "dev" "devdoc" "man" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "bJSeUsi+zCBU2qzWBJAfZs5c9wml+pHEu3ysyTm1Pqk=";
+  };
+
+  patches = [
+    # Fix build with meson 0.61.
+    # sendto/meson.build:24:5: ERROR: Function does not take positional arguments.
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-bluetooth/-/commit/755fd758f866d3a3f7ca482942beee749f13a91e.patch";
+      sha256 = "sha256-N0MJ0pYO411o2CTNZHWmEoG2m5TGUjR6YW6HSXHTR/A=";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    gettext
+    itstool
+    pkg-config
+    libxml2
+    wrapGAppsHook
+    gobject-introspection
+    gtk-doc
+    docbook-xsl-nons
+    docbook_xml_dtd_43
+    python3
+  ];
+
+  buildInputs = [
+    glib
+    gtk3
+    udev
+    libnotify
+    libcanberra-gtk3
+    gnome.adwaita-icon-theme
+    gsettings-desktop-schemas
+  ];
+
+  mesonFlags = [
+    "-Dicon_update=false"
+    "-Dgtk_doc=true"
+  ];
+
+  postPatch = ''
+    chmod +x meson_post_install.py # patchShebangs requires executable file
+    patchShebangs meson_post_install.py
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.gnome-bluetooth_1_0";
+      freeze = true;
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://help.gnome.org/users/gnome-bluetooth/stable/index.html.en";
+    description = "Application that let you manage Bluetooth in the GNOME destkop";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/default.nix
new file mode 100644
index 000000000000..7c80f475e564
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-bluetooth/default.nix
@@ -0,0 +1,86 @@
+{ lib
+, stdenv
+, fetchurl
+, gnome
+, meson
+, mesonEmulatorHook
+, ninja
+, pkg-config
+, gtk4
+, libadwaita
+, gettext
+, glib
+, udev
+, upower
+, itstool
+, libxml2
+, wrapGAppsHook4
+, libnotify
+, gsound
+, gobject-introspection
+, gtk-doc
+, docbook-xsl-nons
+, docbook_xml_dtd_43
+, python3
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-bluetooth";
+  version = "42.7";
+
+  # TODO: split out "lib"
+  outputs = [ "out" "dev" "devdoc" "man" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "lN8XKdvsO7EF5Yjq9TEru6oFxJ6nMyAqENw/dTK9+Gk=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    gettext
+    itstool
+    pkg-config
+    libxml2
+    wrapGAppsHook4
+    gobject-introspection
+    gtk-doc
+    docbook-xsl-nons
+    docbook_xml_dtd_43
+    python3
+  ] ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
+    mesonEmulatorHook
+  ];
+
+  buildInputs = [
+    glib
+    gtk4
+    libadwaita
+    udev
+    upower
+    libnotify
+    gsound
+    gsettings-desktop-schemas
+  ];
+
+  mesonFlags = [
+    "-Dgtk_doc=true"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-bluetooth";
+    description = "Application that lets you manage Bluetooth in the GNOME desktop";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-calculator/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-calculator/default.nix
new file mode 100644
index 000000000000..73863ccfaf33
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-calculator/default.nix
@@ -0,0 +1,81 @@
+{ stdenv
+, lib
+, meson
+, ninja
+, vala
+, gettext
+, itstool
+, fetchurl
+, pkg-config
+, libxml2
+, gtk4
+, glib
+, gtksourceview5
+, wrapGAppsHook4
+, gobject-introspection
+, gnome
+, mpfr
+, gmp
+, libsoup_3
+, libmpc
+, libadwaita
+, gsettings-desktop-schemas
+, libgee
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-calculator";
+  version = "45.0.2";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-calculator/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "fcvzI4SJcXHL5Ug+xmTZlOXnVekSrh35EWJPA8kIZ8I=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    vala
+    gettext
+    itstool
+    wrapGAppsHook4
+    gobject-introspection # for finding vapi files
+  ];
+
+  buildInputs = [
+    gtk4
+    glib
+    libxml2
+    gtksourceview5
+    mpfr
+    gmp
+    libgee
+    gsettings-desktop-schemas
+    libsoup_3
+    libmpc
+    libadwaita
+  ];
+
+  doCheck = true;
+
+  preCheck = ''
+    # Currency conversion test tries to store currency data in $HOME/.cache.
+    export HOME=$TMPDIR
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-calculator";
+      attrPath = "gnome.gnome-calculator";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Calculator";
+    description = "Application that solves mathematical equations and is suitable as a default application in a Desktop environment";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl3Plus;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/0001-Fix-build-with-Exiv2-0.28.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/0001-Fix-build-with-Exiv2-0.28.patch
new file mode 100644
index 000000000000..96688c8d8086
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/0001-Fix-build-with-Exiv2-0.28.patch
@@ -0,0 +1,73 @@
+From 0417f60c7e760e1ebc6acd3dc23818b38c3929e7 Mon Sep 17 00:00:00 2001
+From: Weijia Wang <contact@weijia.wang>
+Date: Mon, 7 Aug 2023 21:51:30 +0200
+Subject: [PATCH] Fix build with Exiv2 0.28
+
+---
+ src/gcm-helper-exiv.cpp | 20 ++++++++++++++++++--
+ 1 file changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/src/gcm-helper-exiv.cpp b/src/gcm-helper-exiv.cpp
+index 7ec69948..23c8b320 100644
+--- a/src/gcm-helper-exiv.cpp
++++ b/src/gcm-helper-exiv.cpp
+@@ -22,6 +22,10 @@
+ #include <exiv2/image.hpp>
+ #include <exiv2/exif.hpp>
+ 
++#if EXIV2_MAJOR_VERSION >= 1 || (EXIV2_MAJOR_VERSION == 0 && EXIV2_MINOR_VERSION >= 28)
++#define HAVE_EXIV2_0_28
++#endif
++
+ #if EXIV2_MAJOR_VERSION >= 1 || (EXIV2_MAJOR_VERSION == 0 && EXIV2_MINOR_VERSION >= 27)
+ #define HAVE_EXIV2_ERROR_CODE
+ #include <exiv2/error.hpp>
+@@ -33,7 +37,11 @@
+ int
+ main (int argc, char* const argv[])
+ {
++#ifdef HAVE_EXIV2_0_28
++	Exiv2::Image::UniquePtr image;
++#else
+ 	Exiv2::Image::AutoPtr image;
++#endif
+ 	Exiv2::ExifData exifData;
+ 	std::string filename;
+ 	std::string make;
+@@ -57,7 +65,9 @@ main (int argc, char* const argv[])
+ 		if (argc == 2)
+ 			filename = argv[1];
+ 		if (filename.empty())
+-#ifdef HAVE_EXIV2_ERROR_CODE
++#ifdef HAVE_EXIV2_0_28
++			throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, "No filename specified");
++#elif defined(HAVE_EXIV2_ERROR_CODE)
+ 			throw Exiv2::Error(Exiv2::kerErrorMessage, "No filename specified");
+ #else
+ 			throw Exiv2::Error(1, "No filename specified");
+@@ -70,7 +80,9 @@ main (int argc, char* const argv[])
+ 		if (exifData.empty()) {
+ 			std::string error(argv[1]);
+ 			error += ": No Exif data found in the file";
+-#ifdef HAVE_EXIV2_ERROR_CODE
++#ifdef HAVE_EXIV2_0_28
++			throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage, error);
++#elif defined(HAVE_EXIV2_ERROR_CODE)
+ 			throw Exiv2::Error(Exiv2::kerErrorMessage, error);
+ #else
+ 			throw Exiv2::Error(1, error);
+@@ -89,7 +101,11 @@ main (int argc, char* const argv[])
+ 		std::cout << model << "\n";
+ 		std::cout << make << "\n";
+ 		std::cout << serial << "\n";
++#ifdef HAVE_EXIV2_0_28
++	} catch (Exiv2::Error& e) {
++#else
+ 	} catch (Exiv2::AnyError& e) {
++#endif
+ 		std::cout << "Failed to load: " << e << "\n";
+ 		retval = -1;
+ 	}
+-- 
+2.39.2 (Apple Git-143)
+
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/default.nix
new file mode 100644
index 000000000000..7c9d3df9f1c0
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-color-manager/default.nix
@@ -0,0 +1,70 @@
+{ lib, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gettext
+, itstool
+, desktop-file-utils
+, gnome
+, glib
+, gtk3
+, libexif
+, libtiff
+, colord
+, colord-gtk
+, libcanberra-gtk3
+, lcms2
+, vte
+, exiv2
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-color-manager";
+  version = "3.32.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "1vpxa2zjz3lkq9ldjg0fl65db9s6b4kcs8nyaqfz3jygma7ifg3w";
+  };
+
+  patches = [
+    ./0001-Fix-build-with-Exiv2-0.28.patch
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    itstool
+    desktop-file-utils
+  ];
+
+  buildInputs = [
+    glib
+    gtk3
+    libexif
+    libtiff
+    colord
+    colord-gtk
+    libcanberra-gtk3
+    lcms2
+    vte
+    exiv2
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "A set of graphical utilities for color management to be used in the GNOME desktop";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-common/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-common/default.nix
new file mode 100644
index 000000000000..a9d28fcd4cfc
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-common/default.nix
@@ -0,0 +1,21 @@
+{ lib, stdenv, fetchurl, which, gnome, autoconf, automake }:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-common";
+  version = "3.18.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-common/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "22569e370ae755e04527b76328befc4c73b62bfd4a572499fde116b8318af8cf";
+  };
+
+  passthru = {
+    updateScript = gnome.updateScript { packageName = "gnome-common"; attrPath = "gnome.gnome-common"; };
+  };
+
+  propagatedBuildInputs = [ which autoconf automake ]; # autogen.sh which is using gnome-common tends to require which
+
+  meta = with lib; {
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-contacts/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-contacts/default.nix
new file mode 100644
index 000000000000..5f938a1fb79b
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-contacts/default.nix
@@ -0,0 +1,80 @@
+{ lib
+, stdenv
+, gettext
+, fetchurl
+, evolution-data-server-gtk4
+, pkg-config
+, libxslt
+, docbook-xsl-nons
+, docbook_xml_dtd_42
+, desktop-file-utils
+, gtk4
+, glib
+, libportal-gtk4
+, gnome-desktop
+, gnome-online-accounts
+, qrencode
+, wrapGAppsHook4
+, folks
+, libxml2
+, gnome
+, vala
+, meson
+, ninja
+, libadwaita
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-contacts";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-contacts/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "vR/fKm9kzdnyq7/tB+ZPKmmuNTb3T0gZjMN7rZ/NlD4=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    vala
+    gettext
+    libxslt
+    docbook-xsl-nons
+    docbook_xml_dtd_42
+    desktop-file-utils
+    wrapGAppsHook4
+  ];
+
+  buildInputs = [
+    gtk4
+    glib
+    libportal-gtk4
+    evolution-data-server-gtk4
+    gsettings-desktop-schemas
+    folks
+    gnome-desktop
+    libadwaita
+    libxml2
+    gnome-online-accounts
+    qrencode
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-contacts";
+      attrPath = "gnome.gnome-contacts";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Contacts";
+    description = "GNOME’s integrated address book";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/default.nix
new file mode 100644
index 000000000000..d59b5a139065
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/default.nix
@@ -0,0 +1,215 @@
+{ fetchurl
+, lib
+, stdenv
+, substituteAll
+, accountsservice
+, adwaita-icon-theme
+, colord
+, colord-gtk4
+, cups
+, docbook-xsl-nons
+, fontconfig
+, gdk-pixbuf
+, gettext
+, glib
+, glib-networking
+, gcr
+, glibc
+, gnome-bluetooth
+, gnome-color-manager
+, gnome-desktop
+, gnome-online-accounts
+, gnome-settings-daemon
+, gnome-tecla
+, gnome
+, gsettings-desktop-schemas
+, gsound
+, gst_all_1
+, gtk4
+, ibus
+, libgtop
+, libgudev
+, libadwaita
+, libkrb5
+, libpulseaudio
+, libpwquality
+, librsvg
+, webp-pixbuf-loader
+, libsecret
+, libwacom
+, libxml2
+, libxslt
+, meson
+, modemmanager
+, mutter
+, networkmanager
+, networkmanagerapplet
+, libnma-gtk4
+, ninja
+, pkg-config
+, polkit
+, python3
+, samba
+, setxkbmap
+, shadow
+, shared-mime-info
+, sound-theme-freedesktop
+, tracker
+, tracker-miners
+, tzdata
+, udisks2
+, upower
+, libepoxy
+, gnome-user-share
+, gnome-remote-desktop
+, wrapGAppsHook
+, xvfb-run
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-control-center";
+  version = "45.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-0obHYnFQ4RKqy7S3uRcX+tjokHYGFHnfxhCy3XRLV3o=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./paths.patch;
+      gcm = gnome-color-manager;
+      inherit glibc tzdata shadow;
+      inherit cups networkmanagerapplet;
+    })
+  ];
+
+  nativeBuildInputs = [
+    docbook-xsl-nons
+    gettext
+    libxslt
+    meson
+    ninja
+    pkg-config
+    python3
+    shared-mime-info
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    accountsservice
+    adwaita-icon-theme
+    colord
+    colord-gtk4
+    libepoxy
+    fontconfig
+    gdk-pixbuf
+    glib
+    glib-networking
+    gcr
+    gnome-bluetooth
+    gnome-desktop
+    gnome-online-accounts
+    gnome-remote-desktop # optional, sharing panel
+    gnome-settings-daemon
+    gnome-tecla
+    gnome-user-share # optional, sharing panel
+    gsettings-desktop-schemas
+    gsound
+    gtk4
+    ibus
+    libgtop
+    libgudev
+    libadwaita
+    libkrb5
+    libnma-gtk4
+    libpulseaudio
+    libpwquality
+    librsvg
+    libsecret
+    libwacom
+    libxml2
+    modemmanager
+    mutter # schemas for the keybindings
+    networkmanager
+    polkit
+    samba
+    tracker
+    tracker-miners # for search locations dialog
+    udisks2
+    upower
+  ] ++ (with gst_all_1; [
+    # For animations in Mouse panel.
+    gst-plugins-base
+    gst-plugins-good
+  ]);
+
+  nativeCheckInputs = [
+    python3.pkgs.python-dbusmock
+    setxkbmap
+    xvfb-run
+  ];
+
+  doCheck = true;
+
+  preConfigure = ''
+    # For ITS rules
+    addToSearchPath "XDG_DATA_DIRS" "${polkit.out}/share"
+  '';
+
+  checkPhase = ''
+    runHook preCheck
+
+    testEnvironment=(
+      # Basically same as https://github.com/NixOS/nixpkgs/pull/141299
+      "ADW_DISABLE_PORTAL=1"
+      "XDG_DATA_DIRS=${glib.getSchemaDataDirPath gsettings-desktop-schemas}"
+    )
+
+    env "''${testEnvironment[@]}" xvfb-run \
+      meson test --print-errorlogs
+
+    runHook postCheck
+  '';
+
+  postInstall = ''
+    # Pull in WebP support for gnome-backgrounds.
+    # In postInstall to run before gappsWrapperArgsHook.
+    export GDK_PIXBUF_MODULE_FILE="${gnome._gdkPixbufCacheBuilder_DO_NOT_USE {
+      extraLoaders = [
+        librsvg
+        webp-pixbuf-loader
+      ];
+    }}"
+  '';
+
+  preFixup = ''
+    gappsWrapperArgs+=(
+      --prefix XDG_DATA_DIRS : "${sound-theme-freedesktop}/share"
+      # Thumbnailers (for setting user profile pictures)
+      --prefix XDG_DATA_DIRS : "${gdk-pixbuf}/share"
+      --prefix XDG_DATA_DIRS : "${librsvg}/share"
+      # WM keyboard shortcuts
+      --prefix XDG_DATA_DIRS : "${mutter}/share"
+    )
+    for i in $out/share/applications/*; do
+      substituteInPlace $i --replace "Exec=gnome-control-center" "Exec=$out/bin/gnome-control-center"
+    done
+  '';
+
+  separateDebugInfo = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "Utilities to configure the GNOME desktop";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/paths.patch
new file mode 100644
index 000000000000..165497f11e2a
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-control-center/paths.patch
@@ -0,0 +1,177 @@
+diff --git a/panels/color/cc-color-panel.c b/panels/color/cc-color-panel.c
+index f6c84e3d2..cd897f8f5 100644
+--- a/panels/color/cc-color-panel.c
++++ b/panels/color/cc-color-panel.c
+@@ -614,7 +614,7 @@ gcm_prefs_calibrate_cb (CcColorPanel *self)
+ 
+   /* run with modal set */
+   argv = g_ptr_array_new_with_free_func (g_free);
+-  g_ptr_array_add (argv, g_strdup ("gcm-calibrate"));
++  g_ptr_array_add (argv, g_build_filename ("@gcm@", "bin", "gcm-calibrate", NULL));
+   g_ptr_array_add (argv, g_strdup ("--device"));
+   g_ptr_array_add (argv, g_strdup (cd_device_get_id (self->current_device)));
+   g_ptr_array_add (argv, g_strdup ("--parent-window"));
+@@ -989,7 +989,7 @@ gcm_prefs_profile_view (CcColorPanel *self, CdProfile *profile)
+ 
+   /* open up gcm-viewer as a info pane */
+   argv = g_ptr_array_new_with_free_func (g_free);
+-  g_ptr_array_add (argv, g_strdup ("gcm-viewer"));
++  g_ptr_array_add (argv, g_build_filename ("@gcm@", "bin", "gcm-viewer", NULL));
+   g_ptr_array_add (argv, g_strdup ("--profile"));
+   g_ptr_array_add (argv, g_strdup (cd_profile_get_id (profile)));
+   g_ptr_array_add (argv, g_strdup ("--parent-window"));
+@@ -1221,15 +1221,12 @@ gcm_prefs_device_clicked (CcColorPanel *self, CdDevice *device)
+ static void
+ gcm_prefs_profile_clicked (CcColorPanel *self, CdProfile *profile, CdDevice *device)
+ {
+-  g_autofree gchar *s = NULL;
+-
+   /* get profile */
+   g_debug ("selected profile = %s",
+      cd_profile_get_filename (profile));
+ 
+   /* allow getting profile info */
+-  if (cd_profile_get_filename (profile) != NULL &&
+-      (s = g_find_program_in_path ("gcm-viewer")) != NULL)
++  if (cd_profile_get_filename (profile) != NULL)
+     gtk_widget_set_sensitive (self->toolbutton_profile_view, TRUE);
+   else
+     gtk_widget_set_sensitive (self->toolbutton_profile_view, FALSE);
+diff --git a/panels/datetime/tz.h b/panels/datetime/tz.h
+index a2376f8a4..98769e08f 100644
+--- a/panels/datetime/tz.h
++++ b/panels/datetime/tz.h
+@@ -27,11 +27,7 @@
+ 
+ G_BEGIN_DECLS
+ 
+-#ifndef __sun
+-#  define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
+-#else
+-#  define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
+-#endif
++#define TZ_DATA_FILE "@tzdata@/share/zoneinfo/zone.tab"
+ 
+ typedef struct _TzDB TzDB;
+ typedef struct _TzLocation TzLocation;
+diff --git a/panels/network/connection-editor/net-connection-editor.c b/panels/network/connection-editor/net-connection-editor.c
+index 505b8ee25..62e94009f 100644
+--- a/panels/network/connection-editor/net-connection-editor.c
++++ b/panels/network/connection-editor/net-connection-editor.c
+@@ -267,9 +267,9 @@ net_connection_editor_do_fallback (NetConnectionEditor *self, const gchar *type)
+         g_autoptr(GError) error = NULL;
+ 
+         if (self->is_new_connection) {
+-                cmdline = g_strdup_printf ("nm-connection-editor --type='%s' --create", type);
++                cmdline = g_strdup_printf ("@networkmanagerapplet@/bin/nm-connection-editor --type='%s' --create", type);
+         } else {
+-                cmdline = g_strdup_printf ("nm-connection-editor --edit='%s'",
++                cmdline = g_strdup_printf ("@networkmanagerapplet@/bin/nm-connection-editor --edit='%s'",
+                                            nm_connection_get_uuid (self->connection));
+         }
+ 
+diff --git a/panels/network/net-device-bluetooth.c b/panels/network/net-device-bluetooth.c
+index 74dfb0e9a..5f53d1a20 100644
+--- a/panels/network/net-device-bluetooth.c
++++ b/panels/network/net-device-bluetooth.c
+@@ -90,7 +90,7 @@ nm_device_bluetooth_refresh_ui (NetDeviceBluetooth *self)
+         update_off_switch_from_device_state (self->device_off_switch, state, self);
+ 
+         /* set up the Options button */
+-        path = g_find_program_in_path ("nm-connection-editor");
++        path = g_find_program_in_path ("@networkmanagerapplet@/bin/nm-connection-editor");
+         gtk_widget_set_visible (GTK_WIDGET (self->options_button), state != NM_DEVICE_STATE_UNMANAGED && path != NULL);
+ }
+ 
+@@ -141,7 +141,7 @@ options_button_clicked_cb (NetDeviceBluetooth *self)
+ 
+         connection = net_device_get_find_connection (self->client, self->device);
+         uuid = nm_connection_get_uuid (connection);
+-        cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
++        cmdline = g_strdup_printf ("@networkmanagerapplet@/bin/nm-connection-editor --edit %s", uuid);
+         g_debug ("Launching '%s'\n", cmdline);
+         if (!g_spawn_command_line_async (cmdline, &error))
+                 g_warning ("Failed to launch nm-connection-editor: %s", error->message);
+@@ -185,7 +185,7 @@ net_device_bluetooth_init (NetDeviceBluetooth *self)
+ 
+         gtk_widget_init_template (GTK_WIDGET (self));
+ 
+-        path = g_find_program_in_path ("nm-connection-editor");
++        path = g_find_program_in_path ("@networkmanagerapplet@/bin/nm-connection-editor");
+         gtk_widget_set_visible (GTK_WIDGET (self->options_button), path != NULL);
+ }
+ 
+diff --git a/panels/network/net-device-mobile.c b/panels/network/net-device-mobile.c
+index 34eb86241..50d0a2bed 100644
+--- a/panels/network/net-device-mobile.c
++++ b/panels/network/net-device-mobile.c
+@@ -508,7 +508,7 @@ options_button_clicked_cb (NetDeviceMobile *self)
+ 
+         connection = net_device_get_find_connection (self->client, self->device);
+         uuid = nm_connection_get_uuid (connection);
+-        cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
++        cmdline = g_strdup_printf ("@networkmanagerapplet@/bin/nm-connection-editor --edit %s", uuid);
+         g_debug ("Launching '%s'\n", cmdline);
+         if (!g_spawn_command_line_async (cmdline, &error))
+                 g_warning ("Failed to launch nm-connection-editor: %s", error->message);
+@@ -797,7 +797,7 @@ net_device_mobile_init (NetDeviceMobile *self)
+ 
+         self->cancellable = g_cancellable_new ();
+ 
+-        path = g_find_program_in_path ("nm-connection-editor");
++        path = g_find_program_in_path ("@networkmanagerapplet@/bin/nm-connection-editor");
+         gtk_widget_set_visible (GTK_WIDGET (self->options_button), path != NULL);
+ }
+ 
+diff --git a/panels/printers/pp-host.c b/panels/printers/pp-host.c
+index a31a606e3..ed5133d29 100644
+--- a/panels/printers/pp-host.c
++++ b/panels/printers/pp-host.c
+@@ -256,7 +256,7 @@ _pp_host_get_snmp_devices_thread (GTask        *task,
+   devices = g_ptr_array_new_with_free_func (g_object_unref);
+ 
+   argv = g_new0 (gchar *, 3);
+-  argv[0] = g_strdup ("/usr/lib/cups/backend/snmp");
++  argv[0] = g_strdup ("@cups@/lib/cups/backend/snmp");
+   argv[1] = g_strdup (priv->hostname);
+ 
+   /* Use SNMP to get printer's informations */
+diff --git a/panels/user-accounts/run-passwd.c b/panels/user-accounts/run-passwd.c
+index 86f53d4fc..0b052856f 100644
+--- a/panels/user-accounts/run-passwd.c
++++ b/panels/user-accounts/run-passwd.c
+@@ -150,7 +150,7 @@ spawn_passwd (PasswdHandler *passwd_handler, GError **error)
+         gchar  **envp;
+         gint    my_stdin, my_stdout, my_stderr;
+ 
+-        argv[0] = "/usr/bin/passwd";    /* Is it safe to rely on a hard-coded path? */
++        argv[0] = "/run/wrappers/bin/passwd";    /* Is it safe to rely on a hard-coded path? */
+         argv[1] = NULL;
+ 
+         envp = g_get_environ ();
+diff --git a/panels/user-accounts/user-utils.c b/panels/user-accounts/user-utils.c
+index 83d4cd091..e8784c722 100644
+--- a/panels/user-accounts/user-utils.c
++++ b/panels/user-accounts/user-utils.c
+@@ -486,7 +486,7 @@ is_valid_username_async (const gchar *username,
+          * future, so it would be nice to have some official way for this
+          * instead of relying on the current "--login" implementation.
+          */
+-        argv[0] = "/usr/sbin/usermod";
++        argv[0] = "@shadow@/bin/usermod";
+         argv[1] = "--login";
+         argv[2] = data->username;
+         argv[3] = "--";
+diff --git a/tests/datetime/test-endianess.c b/tests/datetime/test-endianess.c
+index 9cb92007a..84d2f0fa3 100644
+--- a/tests/datetime/test-endianess.c
++++ b/tests/datetime/test-endianess.c
+@@ -26,7 +26,7 @@ test_endianess (void)
+ 	g_autoptr(GDir) dir = NULL;
+ 	const char *name;
+ 
+-	dir = g_dir_open ("/usr/share/i18n/locales/", 0, NULL);
++	dir = g_dir_open ("@glibc@/share/i18n/locales/", 0, NULL);
+ 	if (dir == NULL) {
+ 		/* Try with /usr/share/locale/
+ 		 * https://bugzilla.gnome.org/show_bug.cgi?id=646780 */
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-dictionary/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-dictionary/default.nix
new file mode 100644
index 000000000000..ebd9b58fd96a
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-dictionary/default.nix
@@ -0,0 +1,85 @@
+{ stdenv
+, lib
+, fetchurl
+, fetchpatch
+, meson
+, ninja
+, pkg-config
+, desktop-file-utils
+, appstream-glib
+, libxslt
+, libxml2
+, gettext
+, itstool
+, wrapGAppsHook
+, docbook_xsl
+, docbook_xml_dtd_43
+, gnome
+, gtk3
+, glib
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-dictionary";
+  version = "40.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-dictionary/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "1d8dhcfys788vv27v34i3s3x3jdvdi2kqn2a5p8c937a9hm0qr9f";
+  };
+
+  patches = [
+    # Fix test dependencies with meson 0.57, can be removed on next bump
+    # We need to explicitly depend on the generated files.
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-dictionary/-/commit/87c026cfe4acbcfc62d15950f88a71d8d9678c7e.patch";
+      sha256 = "tKesWeOK3OqOxrXm4dZvCZHHdTD7AQbYDjtYDCsLd3A=";
+    })
+    # Fix build with meson 0.61, can be removed on next bump
+    # data/appdata/meson.build:3:5: ERROR: Function does not take positional arguments.
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-dictionary/-/commit/cf3f8a67cd6f3059c555ed9cf0f5fba10abb7f68.patch";
+      sha256 = "cIRM6ACqsnEo2JWYvr6EBye5o0BudugZMShCe1U5hz8=";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    wrapGAppsHook
+    libxml2
+    gettext
+    itstool
+    desktop-file-utils
+    appstream-glib
+    libxslt
+    docbook_xsl
+    docbook_xml_dtd_43
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    gsettings-desktop-schemas
+    gnome.adwaita-icon-theme
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-dictionary";
+      attrPath = "gnome.gnome-dictionary";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Dictionary";
+    description = "Dictionary is the GNOME application to look up definitions";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-disk-utility/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-disk-utility/default.nix
new file mode 100644
index 000000000000..b0189cc1321d
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-disk-utility/default.nix
@@ -0,0 +1,81 @@
+{ lib
+, stdenv
+, gettext
+, fetchurl
+, pkg-config
+, udisks2
+, libhandy
+, libsecret
+, libdvdread
+, meson
+, ninja
+, gtk3
+, glib
+, wrapGAppsHook
+, libnotify
+, itstool
+, gnome
+, libxml2
+, gsettings-desktop-schemas
+, libcanberra-gtk3
+, libxslt
+, docbook-xsl-nons
+, desktop-file-utils
+, libpwquality
+, systemd
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-disk-utility";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-disk-utility/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-PYYl+qmQR7xK79KZIa1yirTXAM/4bg8uxn6Nuod9DdM=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    itstool
+    libxslt
+    docbook-xsl-nons
+    desktop-file-utils
+    wrapGAppsHook
+    libxml2
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    libhandy
+    libsecret
+    libpwquality
+    libnotify
+    libdvdread
+    libcanberra-gtk3
+    udisks2
+    gnome.adwaita-icon-theme
+    systemd
+    gnome.gnome-settings-daemon
+    gsettings-desktop-schemas
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-disk-utility";
+      attrPath = "gnome.gnome-disk-utility";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Disks";
+    description = "A udisks graphical front-end";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    mainProgram = "gnome-disks";
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-font-viewer/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-font-viewer/default.nix
new file mode 100644
index 000000000000..9e5003ae2f35
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-font-viewer/default.nix
@@ -0,0 +1,66 @@
+{ lib
+, stdenv
+, meson
+, ninja
+, gettext
+, fetchurl
+, pkg-config
+, gtk4
+, glib
+, libxml2
+, gnome-desktop
+, libadwaita
+, fribidi
+, wrapGAppsHook4
+, gnome
+, harfbuzz
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-font-viewer";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-font-viewer/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "l8traN2mDeCrMDg4NYbx5LwdpaSPRAJb1rvnTqBcKwg=";
+  };
+
+  doCheck = true;
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    wrapGAppsHook4
+    libxml2
+    glib
+  ];
+
+  buildInputs = [
+    gtk4
+    glib
+    gnome-desktop
+    harfbuzz
+    libadwaita
+    fribidi
+  ];
+
+  # Do not run meson-postinstall.sh
+  preConfigure = "sed -i '2,$ d'  meson-postinstall.sh";
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-font-viewer";
+      attrPath = "gnome.gnome-font-viewer";
+    };
+  };
+
+  meta = with lib; {
+    description = "Program that can preview fonts and create thumbnails for fonts";
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-font-viewer";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/0001-fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/0001-fix-paths.patch
new file mode 100644
index 000000000000..f3cd9f6f0427
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/0001-fix-paths.patch
@@ -0,0 +1,53 @@
+From 1ae0eca39ba6af27f37e2fe81395b91a2761a408 Mon Sep 17 00:00:00 2001
+Message-Id: <1ae0eca39ba6af27f37e2fe81395b91a2761a408.1600627676.git-series.worldofpeace@protonmail.ch>
+From: WORLDofPEACE <worldofpeace@protonmail.ch>
+Date: Sun, 20 Sep 2020 14:46:59 -0400
+Subject: [PATCH] fix paths
+
+---
+ gnome-initial-setup/pages/keyboard/cc-input-chooser.c | 6 +++---
+ gnome-initial-setup/pages/timezone/tz.h               | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+index 196abf6..613d0e5 100644
+--- a/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
++++ b/gnome-initial-setup/pages/keyboard/cc-input-chooser.c
+@@ -177,9 +177,9 @@ preview_cb (GtkLabel       *label,
+ 		return TRUE;
+ 
+ 	if (variant[0])
+-		commandline = g_strdup_printf ("tecla \"%s+%s\"", layout, variant);
++		commandline = g_strdup_printf ("@tecla@/bin/tecla \"%s+%s\"", layout, variant);
+ 	else
+-		commandline = g_strdup_printf ("tecla %s", layout);
++		commandline = g_strdup_printf ("@tecla@/bin/tecla %s", layout);
+ 	g_spawn_command_line_async (commandline, NULL);
+ 	g_free (commandline);
+ 
+@@ -831,7 +831,7 @@ cc_input_chooser_class_init (CcInputChooserClass *klass)
+                 g_param_spec_string ("showing-extra", "", "", "",
+                                      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ 
+-	signals[CHANGED] = 
++	signals[CHANGED] =
+ 		g_signal_new ("changed",
+ 			      G_TYPE_FROM_CLASS (object_class),
+ 			      G_SIGNAL_RUN_FIRST,
+diff --git a/gnome-initial-setup/pages/timezone/tz.h b/gnome-initial-setup/pages/timezone/tz.h
+index a2376f8..5cb7bc9 100644
+--- a/gnome-initial-setup/pages/timezone/tz.h
++++ b/gnome-initial-setup/pages/timezone/tz.h
+@@ -28,7 +28,7 @@
+ G_BEGIN_DECLS
+ 
+ #ifndef __sun
+-#  define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
++#  define TZ_DATA_FILE "@tzdata@/share/zoneinfo/zone.tab"
+ #else
+ #  define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
+ #endif
+
+base-commit: 5132e206a6bf81964450561d68473ac015760455
+-- 
+git-series 0.9.1
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/default.nix
new file mode 100644
index 000000000000..969d5012cc55
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/default.nix
@@ -0,0 +1,115 @@
+{ stdenv
+, lib
+, fetchurl
+, substituteAll
+, dconf
+, gettext
+, meson
+, ninja
+, pkg-config
+, wrapGAppsHook4
+, gnome
+, accountsservice
+, fontconfig
+, gdm
+, geoclue2
+, geocode-glib_2
+, glib
+, gnome-desktop
+, gnome-online-accounts
+, gtk3
+, gtk4
+, libgweather
+, json-glib
+, krb5
+, libpwquality
+, librest_1_0
+, libsecret
+, networkmanager
+, pango
+, polkit
+, webkitgtk_6_0
+, systemd
+, libadwaita
+, libnma-gtk4
+, tzdata
+, gnome-tecla
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-initial-setup";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sa/nZHmPiUi+25XHqzG9eFKaxctIHEH3p3d/Jk3lS9g=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./0001-fix-paths.patch;
+      inherit tzdata;
+      tecla = gnome-tecla;
+    })
+  ];
+
+  nativeBuildInputs = [
+    dconf
+    gettext
+    meson
+    ninja
+    pkg-config
+    systemd
+    wrapGAppsHook4
+  ];
+
+  buildInputs = [
+    accountsservice
+    fontconfig
+    gdm
+    geoclue2
+    geocode-glib_2
+    glib
+    gnome-desktop
+    gnome-online-accounts
+    gsettings-desktop-schemas
+    gtk3
+    gtk4
+    json-glib
+    krb5
+    libgweather
+    libadwaita
+    libnma-gtk4
+    libpwquality
+    librest_1_0
+    libsecret
+    networkmanager
+    pango
+    polkit
+    webkitgtk_6_0
+  ];
+
+  mesonFlags = [
+    "-Dibus=disabled"
+    "-Dparental_controls=disabled"
+    "-Dvendor-conf-file=${./vendor.conf}"
+  ];
+
+  PKG_CONFIG_SYSTEMD_SYSUSERSDIR = "${placeholder "out"}/lib/sysusers.d";
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "Simple, easy, and safe way to prepare a new system";
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-initial-setup";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/vendor.conf b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/vendor.conf
new file mode 100644
index 000000000000..a06b37e100ed
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-initial-setup/vendor.conf
@@ -0,0 +1,5 @@
+# Disable pages not right for NixOS
+# For example user accounts should be preconfigured
+# and we can't modify system time with systemd.
+[pages]
+skip=account;software;password;timezone;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-keyring/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-keyring/default.nix
new file mode 100644
index 000000000000..6a160f6cf77d
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-keyring/default.nix
@@ -0,0 +1,105 @@
+{ lib
+, stdenv
+, fetchurl
+, pkg-config
+, dbus
+, libgcrypt
+, pam
+, python3
+, glib
+, libxslt
+, gettext
+, gcr
+, autoreconfHook
+, libcap_ng
+, libselinux
+, p11-kit
+, openssh
+, wrapGAppsHook
+, docbook-xsl-nons
+, docbook_xml_dtd_43
+, gnome
+, useWrappedDaemon ? true
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-keyring";
+  version = "42.1";
+
+  outputs = [ "out" "dev" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-keyring/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "x/TQQMx2prf+Z+CO+RBpEcPIDUD8iMv8jiaEpMlG4+Y=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    gettext
+    libxslt
+    # Upstream uses ancient autotools to pre-generate the scripts.
+    autoreconfHook
+    docbook-xsl-nons
+    docbook_xml_dtd_43
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    glib
+    libgcrypt
+    pam
+    openssh
+    libcap_ng
+    libselinux
+    gcr
+    p11-kit
+  ];
+
+  nativeCheckInputs = [ dbus python3 ];
+
+  configureFlags = [
+    "--with-pkcs11-config=${placeholder "out"}/etc/pkcs11/" # installation directories
+    "--with-pkcs11-modules=${placeholder "out"}/lib/pkcs11/"
+  ];
+
+  # Tends to fail non-deterministically.
+  # - https://github.com/NixOS/nixpkgs/issues/55293
+  # - https://github.com/NixOS/nixpkgs/issues/51121
+  doCheck = false;
+
+  postPatch = ''
+    patchShebangs build
+  '';
+
+  checkPhase = ''
+    export HOME=$(mktemp -d)
+    dbus-run-session \
+      --config-file=${dbus}/share/dbus-1/session.conf \
+      make check
+  '';
+
+  # Use wrapped gnome-keyring-daemon with cap_ipc_lock=ep
+  postFixup = lib.optionalString useWrappedDaemon ''
+    files=($out/etc/xdg/autostart/* $out/share/dbus-1/services/*)
+
+    for file in ''${files[*]}; do
+      substituteInPlace $file \
+        --replace "$out/bin/gnome-keyring-daemon" "/run/wrappers/bin/gnome-keyring-daemon"
+    done
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-keyring";
+      attrPath = "gnome.gnome-keyring";
+    };
+  };
+
+  meta = with lib; {
+    description = "Collection of components in GNOME that store secrets, passwords, keys, certificates and make them available to applications";
+    homepage = "https://wiki.gnome.org/Projects/GnomeKeyring";
+    license = licenses.gpl2;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-online-miners/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-online-miners/default.nix
new file mode 100644
index 000000000000..a45cd7a1ed21
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-online-miners/default.nix
@@ -0,0 +1,116 @@
+{ lib, stdenv
+, fetchurl
+, fetchpatch
+, autoconf-archive
+, autoreconfHook
+, pkg-config
+, glib
+, gnome
+, libxml2
+, libgdata
+, grilo
+, libzapojit
+, grilo-plugins
+, gnome-online-accounts
+, libmediaart
+, tracker
+, gfbgraph
+, librest
+, libsoup
+, json-glib
+, gmp
+, openssl
+, dleyna-server
+, wrapGAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-online-miners";
+  version = "3.34.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-online-miners/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "1n2jz9i8a42zwxx5h8j2gdy6q1vyydh4vl00r0al7w8jzdh24p44";
+  };
+
+  patches = [
+    # Fix use after free
+    # https://gitlab.gnome.org/GNOME/gnome-online-miners/merge_requests/4
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/9eb57c6a8cd1a925c508646edae936eee0a8e46b.patch";
+      sha256 = "O1GRnzs33I0mFzrNDFkTGiBKstq5krYg7fwj60367TA=";
+    })
+
+    # Port to Tracker 3
+    # https://gitlab.gnome.org/GNOME/gnome-online-miners/merge_requests/3
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/2d3798252807cad9eb061ed2b37e35170c1a1daf.patch";
+      sha256 = "hwrkxroMpTfOwJAPkYQFdDCroZ2qSsvOgDetrJDig20=";
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/1548c0c527f0e4389047448d7d3b6cff55278c8e.patch";
+      sha256 = "U9w81c9Kze7kv5KHeGqvDeSNHzSayVrUG0XYsYMa1sg=";
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/941ebd8890c9ac4f75a1f58ccbea9731f46ad912.patch";
+      sha256 = "JHtDlZ54/BlSiUA3ROHfCTtTKSin3g6JNm8NS6pYML8=";
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/d1681a64bc3f65894af2549e3ba2bffbaf6f539a.patch";
+      sha256 = "9ZEatz5I81UAnjS1qCGWYDQQOxg/qp9Tg3xG/a+3goc=";
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-online-miners/commit/3d2af8785c84d6e50d8a8e6a2569a4b709184e94.patch";
+      sha256 = "7bdUE2k6g3Z8sdGYEb6pUm1/wbKDe4BHbylXUzfuTG0=";
+    })
+  ];
+
+  nativeBuildInputs = [
+    # patch changes configure.ac
+    autoconf-archive
+    autoreconfHook
+
+    pkg-config
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    glib
+    libgdata
+    libxml2
+    libsoup
+    gmp
+    openssl
+    grilo
+    libzapojit
+    grilo-plugins
+    gnome-online-accounts
+    libmediaart
+    tracker
+    gfbgraph
+    json-glib
+    librest
+    dleyna-server
+  ];
+
+  env.NIX_CFLAGS_COMPILE = toString [
+    "-Wno-error=format-security" # https://gitlab.gnome.org/GNOME/gnome-online-miners/merge_requests/3/diffs#note_942747
+  ];
+
+  enableParallelBuilding = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-online-miners";
+      attrPath = "gnome.gnome-online-miners";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Projects/GnomeOnlineMiners";
+    description = "A set of crawlers that go through your online content and index them locally in Tracker";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-remote-desktop/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-remote-desktop/default.nix
new file mode 100644
index 000000000000..9b2f0876d7f5
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-remote-desktop/default.nix
@@ -0,0 +1,84 @@
+{ lib, stdenv
+, fetchurl
+, cairo
+, meson
+, ninja
+, pkg-config
+, python3
+, asciidoc
+, wrapGAppsHook
+, glib
+, libei
+, libepoxy
+, libdrm
+, nv-codec-headers-11
+, pipewire
+, systemd
+, libsecret
+, libnotify
+, libxkbcommon
+, gdk-pixbuf
+, freerdp
+, fdk_aac
+, tpm2-tss
+, fuse3
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-remote-desktop";
+  version = "45.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    hash = "sha256-3NnBisIwZpVjH88AqIZFw443DroFxp3zn1QCBNTq/Y0=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    python3
+    asciidoc
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    cairo
+    freerdp
+    fdk_aac
+    tpm2-tss
+    fuse3
+    gdk-pixbuf # For libnotify
+    glib
+    libei
+    libepoxy
+    libdrm
+    nv-codec-headers-11
+    libnotify
+    libsecret
+    libxkbcommon
+    pipewire
+    systemd
+  ];
+
+  mesonFlags = [
+    "-Dsystemd_user_unit_dir=${placeholder "out"}/lib/systemd/user"
+    "-Dtests=false" # Too deep of a rabbit hole.
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Projects/Mutter/RemoteDesktop";
+    description = "GNOME Remote Desktop server";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-screenshot/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-screenshot/default.nix
new file mode 100644
index 000000000000..3904f1443f7d
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-screenshot/default.nix
@@ -0,0 +1,82 @@
+{ stdenv
+, lib
+, gettext
+, libxml2
+, libhandy
+, fetchurl
+, fetchpatch
+, pkg-config
+, libcanberra-gtk3
+, gtk3
+, glib
+, meson
+, ninja
+, python3
+, wrapGAppsHook
+, appstream-glib
+, desktop-file-utils
+, gnome
+, gsettings-desktop-schemas
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-screenshot";
+  version = "41.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "Stt97JJkKPdCY9V5ZnPPFC5HILbnaPVGio0JM/mMlZc=";
+  };
+
+  patches = [
+    # Fix build with meson 0.61
+    # https://gitlab.gnome.org/GNOME/gnome-screenshot/-/issues/186
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-screenshot/-/commit/b60dad3c2536c17bd201f74ad8e40eb74385ed9f.patch";
+      sha256 = "Js83h/3xxcw2hsgjzGa5lAYFXVrt6MPhXOTh5dZTx/w=";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    appstream-glib
+    libxml2
+    desktop-file-utils
+    python3
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    libcanberra-gtk3
+    libhandy
+    gnome.adwaita-icon-theme
+    gsettings-desktop-schemas
+  ];
+
+  doCheck = true;
+
+  postPatch = ''
+    chmod +x build-aux/postinstall.py # patchShebangs requires executable file
+    patchShebangs build-aux/postinstall.py
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-screenshot";
+    description = "Utility used in the GNOME desktop environment for taking screenshots";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-session/ctl.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/ctl.nix
new file mode 100644
index 000000000000..09fc80bf9ef8
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/ctl.nix
@@ -0,0 +1,42 @@
+{ lib
+, stdenv
+, fetchFromGitHub
+, meson
+, ninja
+, pkg-config
+, glib
+, systemd
+, wrapGAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-session-ctl";
+  version = "42.0";
+
+  src = fetchFromGitHub {
+    owner = "nix-community";
+    repo = pname;
+    rev = version;
+    hash = "sha256-XGJVmlxqbJ/1frbzn2TI7BJm449xeLk43xMMqFsLYko=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    glib
+    systemd
+  ];
+
+  meta = with lib; {
+    description = "gnome-session-ctl extracted from gnome-session for nixpkgs";
+    homepage = "https://github.com/nix-community/gnome-session-ctl";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-session/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/default.nix
new file mode 100644
index 000000000000..dc0cade8d410
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/default.nix
@@ -0,0 +1,141 @@
+{ fetchurl
+, lib
+, stdenv
+, substituteAll
+, meson
+, ninja
+, pkg-config
+, gnome
+, glib
+, gtk3
+, gsettings-desktop-schemas
+, gnome-desktop
+, dbus
+, json-glib
+, libICE
+, xmlto
+, docbook_xsl
+, docbook_xml_dtd_412
+, python3
+, libxslt
+, gettext
+, makeWrapper
+, systemd
+, xorg
+, libepoxy
+, bash
+, gnome-session-ctl
+, gnomeShellSupport ? true
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-session";
+  # Also bump ./ctl.nix when bumping major version.
+  version = "45.0";
+
+  outputs = [ "out" "sessions" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-session/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "cG0v/KysOFU6PAGFeT9aK0qslAu154nZU8mAgWO+8vE=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      gsettings = "${glib.bin}/bin/gsettings";
+      dbusLaunch = "${dbus.lib}/bin/dbus-launch";
+      bash = "${bash}/bin/bash";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    makeWrapper
+    xmlto
+    libxslt
+    docbook_xsl
+    docbook_xml_dtd_412
+    python3
+    dbus # for DTD
+  ];
+
+  buildInputs = [
+    glib
+    gtk3
+    libICE
+    gnome-desktop
+    json-glib
+    xorg.xtrans
+    gnome.adwaita-icon-theme
+    gnome.gnome-settings-daemon
+    gsettings-desktop-schemas
+    systemd
+    libepoxy
+  ];
+
+  mesonFlags = [
+    "-Dsystemd=true"
+    "-Dsystemd_session=default"
+  ];
+
+  postPatch = ''
+    chmod +x meson_post_install.py # patchShebangs requires executable file
+    patchShebangs meson_post_install.py
+
+    # Use our provided `gnome-session-ctl`
+    original="@libexecdir@/gnome-session-ctl"
+    replacement="${gnome-session-ctl}/libexec/gnome-session-ctl"
+
+    find data/ -type f -name "*.service.in" -exec sed -i \
+      -e s,$original,$replacement,g \
+      {} +
+  '';
+
+  # We move the GNOME sessions to another output since gnome-session is a dependency of
+  # GDM itself. If we do not hide them, it will show broken GNOME sessions when GDM is
+  # enabled without proper GNOME installation.
+  postInstall = ''
+    mkdir $sessions
+    moveToOutput share/wayland-sessions "$sessions"
+    moveToOutput share/xsessions "$sessions"
+
+    # Our provided one is being used
+    rm -rf $out/libexec/gnome-session-ctl
+  '';
+
+  # `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/libexec/gnome-session-binary" \
+      --prefix GI_TYPELIB_PATH : "$GI_TYPELIB_PATH" \
+      --suffix XDG_DATA_DIRS : "$out/share:$GSETTINGS_SCHEMAS_PATH" \
+      ${lib.optionalString gnomeShellSupport "--suffix XDG_DATA_DIRS : \"${gnome.gnome-shell}/share\""} \
+      --suffix XDG_CONFIG_DIRS : "${gnome.gnome-settings-daemon}/etc/xdg"
+  '';
+
+  separateDebugInfo = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-session";
+      attrPath = "gnome.gnome-session";
+    };
+    providedSessions = [
+      "gnome"
+      "gnome-xorg"
+    ];
+  };
+
+  meta = with lib; {
+    description = "GNOME session manager";
+    homepage = "https://wiki.gnome.org/Projects/SessionManagement";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-session/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/fix-paths.patch
new file mode 100644
index 000000000000..38805c645b95
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-session/fix-paths.patch
@@ -0,0 +1,35 @@
+diff --git a/gnome-session/gnome-session.in b/gnome-session/gnome-session.in
+index b4b1f8fa..99d52cba 100755
+--- a/gnome-session/gnome-session.in
++++ b/gnome-session/gnome-session.in
+@@ -4,13 +4,15 @@ if [ "x$XDG_SESSION_TYPE" = "xwayland" ] &&
+    [ "x$XDG_SESSION_CLASS" != "xgreeter" ] &&
+    [  -n "$SHELL" ]; then
+   if [ "$1" != '-l' ]; then
+-    exec bash -c "exec -l '$SHELL' -c '$0 -l $*'"
++    # Make sure the shell actually sets up the environment.
++    unset __NIXOS_SET_ENVIRONMENT_DONE
++    exec @bash@ -c "exec -l '$SHELL' -c '$0 -l $*'"
+   else
+     shift
+   fi
+ fi
+ 
+-SETTING=$(G_MESSAGES_DEBUG='' gsettings get org.gnome.system.locale region)
++SETTING=$(G_MESSAGES_DEBUG='' @gsettings@ get org.gnome.system.locale region)
+ REGION=${SETTING#\'}
+ REGION=${REGION%\'}
+ 
+diff --git a/gnome-session/main.c b/gnome-session/main.c
+index a460a849..9d07898f 100644
+--- a/gnome-session/main.c
++++ b/gnome-session/main.c
+@@ -215,7 +215,7 @@ require_dbus_session (int      argc,
+         }
+         new_argv[i + 2] = NULL;
+         
+-        if (!execvp ("dbus-launch", new_argv)) {
++        if (!execvp ("@dbusLaunch@", new_argv)) {
+                 g_set_error (error, 
+                              G_SPAWN_ERROR,
+                              G_SPAWN_ERROR_FAILED,
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/default.nix
new file mode 100644
index 000000000000..95eb6fe1d25e
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/default.nix
@@ -0,0 +1,128 @@
+{ stdenv
+, lib
+, fetchpatch
+, substituteAll
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gnome
+, perl
+, gettext
+, gtk3
+, glib
+, libnotify
+, libgnomekbd
+, lcms2
+, libpulseaudio
+, alsa-lib
+, libcanberra-gtk3
+, upower
+, colord
+, libgweather
+, polkit
+, gsettings-desktop-schemas
+, geoclue2
+, systemd
+, libgudev
+, libwacom
+, libxslt
+, libxml2
+, modemmanager
+, networkmanager
+, gnome-desktop
+, geocode-glib_2
+, docbook_xsl
+, wrapGAppsHook
+, python3
+, tzdata
+, nss
+, gcr_4
+, gnome-session-ctl
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-settings-daemon";
+  version = "43.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-settings-daemon/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "NRO7JPxvgYFmciOmSgZ1NP3M879mMmqUA9OLDw1gE9A=";
+  };
+
+  patches = [
+    # https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/merge_requests/202
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/gnome-settings-daemon/commit/aae1e774dd9de22fe3520cf9eb2bfbf7216f5eb0.patch";
+      sha256 = "O4m0rOW8Zrgu3Q0p0OA8b951VC0FjYbOUk9MLzB9icI=";
+    })
+
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit tzdata;
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    perl
+    gettext
+    libxml2
+    libxslt
+    docbook_xsl
+    wrapGAppsHook
+    python3
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    gsettings-desktop-schemas
+    modemmanager
+    networkmanager
+    libnotify
+    libgnomekbd # for org.gnome.libgnomekbd.keyboard schema
+    gnome-desktop
+    lcms2
+    libpulseaudio
+    alsa-lib
+    libcanberra-gtk3
+    upower
+    colord
+    libgweather
+    nss
+    polkit
+    geocode-glib_2
+    geoclue2
+    systemd
+    libgudev
+    libwacom
+    gcr_4
+  ];
+
+  mesonFlags = [
+    "-Dudev_dir=${placeholder "out"}/lib/udev"
+    "-Dgnome_session_ctl_path=${gnome-session-ctl}/libexec/gnome-session-ctl"
+  ];
+
+  # Default for release buildtype but passed manually because
+  # we're using plain
+  env.NIX_CFLAGS_COMPILE = "-DG_DISABLE_CAST_CHECKS";
+
+  postPatch = ''
+    for f in gnome-settings-daemon/codegen.py plugins/power/gsd-power-constants-update.pl; do
+      chmod +x $f
+      patchShebangs $f
+    done
+  '';
+
+  meta = with lib; {
+    description = "GNOME Settings Daemon";
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-settings-daemon/";
+    license = licenses.gpl2Plus;
+    maintainers = teams.pantheon.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/fix-paths.patch
new file mode 100644
index 000000000000..2229302cab7c
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/43/fix-paths.patch
@@ -0,0 +1,15 @@
+--- a/plugins/datetime/tz.h
++++ b/plugins/datetime/tz.h
+@@ -27,11 +27,7 @@
+ 
+ #include <glib.h>
+ 
+-#ifndef __sun
+-#  define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
+-#else
+-#  define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
+-#endif
++#define TZ_DATA_FILE "@tzdata@/share/zoneinfo/zone.tab"
+ 
+ typedef struct _TzDB TzDB;
+ typedef struct _TzLocation TzLocation;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/add-gnome-session-ctl-option.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/add-gnome-session-ctl-option.patch
new file mode 100644
index 000000000000..8bdf39ce37b6
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/add-gnome-session-ctl-option.patch
@@ -0,0 +1,58 @@
+From aae1e774dd9de22fe3520cf9eb2bfbf7216f5eb0 Mon Sep 17 00:00:00 2001
+From: WORLDofPEACE <worldofpeace@protonmail.ch>
+Date: Sun, 20 Sep 2020 16:09:36 -0400
+Subject: [PATCH] build: add a gnome_session_ctl_path option
+
+In gsd.service.in the ExecStopPost expects g-s-d libexecdir to
+be from the same prefix as gnome-session's, and this is not necessarily
+true as there are linux distro's that install their packages into their
+own individual prefixes (like NixOS or Guix).
+---
+ meson_options.txt      | 1 +
+ plugins/gsd.service.in | 2 +-
+ plugins/meson.build    | 6 ++++++
+ 3 files changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/meson_options.txt b/meson_options.txt
+index 3e04cf64f..21e003c61 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -1,4 +1,5 @@
+ option('udev_dir', type: 'string', value: '', description: 'Absolute path of the udev base directory')
++option('gnome_session_ctl_path', type: 'string', value: '', description: 'Absolute path to the gnome-session-ctl binary')
+ option('systemd', type: 'boolean', value: true, description: 'Enable systemd integration')
+ 
+ option('alsa', type: 'boolean', value: true, description: 'build with ALSA support (not optional on Linux platforms)')
+diff --git a/plugins/gsd.service.in b/plugins/gsd.service.in
+index 79b5f5536..bfbde6d05 100644
+--- a/plugins/gsd.service.in
++++ b/plugins/gsd.service.in
+@@ -23,4 +23,4 @@ BusName=@plugin_dbus_name@
+ TimeoutStopSec=5
+ # We cannot use OnFailure as e.g. dependency failures are normal
+ # https://github.com/systemd/systemd/issues/12352
+-ExecStopPost=@libexecdir@/gnome-session-ctl --exec-stop-check
++ExecStopPost=@gnome_session_ctl@ --exec-stop-check
+diff --git a/plugins/meson.build b/plugins/meson.build
+index 83e018854..266a0f093 100644
+--- a/plugins/meson.build
++++ b/plugins/meson.build
+@@ -20,6 +20,11 @@ all_plugins = [
+ 
+ disabled_plugins = []
+ 
++gnome_session_ctl = get_option('gnome_session_ctl_path')
++if gnome_session_ctl == ''
++  gnome_session_ctl = join_paths(gsd_libexecdir, 'gnome-session-ctl')
++endif
++
+ if not enable_smartcard
+     disabled_plugins += ['smartcard']
+ endif
+@@ -125,6 +130,7 @@ foreach plugin: all_plugins
+         unit_conf.set('plugin_name', plugin_name)
+         unit_conf.set('description', plugin_description)
+         unit_conf.set('libexecdir', gsd_libexecdir)
++        unit_conf.set('gnome_session_ctl', gnome_session_ctl)
+         unit_conf.set('plugin_dbus_name', plugin_dbus_name)
+         unit_conf.set('plugin_restart', plugin_restart_rule.get(plugin_name, 'on-failure'))
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/default.nix
new file mode 100644
index 000000000000..699f9961c11f
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/default.nix
@@ -0,0 +1,126 @@
+{ stdenv
+, lib
+, substituteAll
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gnome
+, perl
+, gettext
+, gtk3
+, glib
+, libnotify
+, libgnomekbd
+, libpulseaudio
+, alsa-lib
+, libcanberra-gtk3
+, upower
+, colord
+, libgweather
+, polkit
+, gsettings-desktop-schemas
+, geoclue2
+, systemd
+, libgudev
+, libwacom
+, libxslt
+, libxml2
+, modemmanager
+, networkmanager
+, gnome-desktop
+, geocode-glib_2
+, docbook_xsl
+, wrapGAppsHook
+, python3
+, tzdata
+, gcr_4
+, gnome-session-ctl
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-settings-daemon";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-settings-daemon/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "u03EaVDiqQ848jIlhIhW0qextxjInQKFzhl7cBa7Hcg=";
+  };
+
+  patches = [
+    # https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/merge_requests/202
+    ./add-gnome-session-ctl-option.patch
+
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit tzdata;
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    perl
+    gettext
+    libxml2
+    libxslt
+    docbook_xsl
+    wrapGAppsHook
+    python3
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    gsettings-desktop-schemas
+    modemmanager
+    networkmanager
+    libnotify
+    libgnomekbd # for org.gnome.libgnomekbd.keyboard schema
+    gnome-desktop
+    libpulseaudio
+    alsa-lib
+    libcanberra-gtk3
+    upower
+    colord
+    libgweather
+    polkit
+    geocode-glib_2
+    geoclue2
+    systemd
+    libgudev
+    libwacom
+    gcr_4
+  ];
+
+  mesonFlags = [
+    "-Dudev_dir=${placeholder "out"}/lib/udev"
+    "-Dgnome_session_ctl_path=${gnome-session-ctl}/libexec/gnome-session-ctl"
+  ];
+
+  # Default for release buildtype but passed manually because
+  # we're using plain
+  env.NIX_CFLAGS_COMPILE = "-DG_DISABLE_CAST_CHECKS";
+
+
+  postPatch = ''
+    for f in gnome-settings-daemon/codegen.py plugins/power/gsd-power-constants-update.pl; do
+      chmod +x $f
+      patchShebangs $f
+    done
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/fix-paths.patch
new file mode 100644
index 000000000000..2229302cab7c
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-settings-daemon/fix-paths.patch
@@ -0,0 +1,15 @@
+--- a/plugins/datetime/tz.h
++++ b/plugins/datetime/tz.h
+@@ -27,11 +27,7 @@
+ 
+ #include <glib.h>
+ 
+-#ifndef __sun
+-#  define TZ_DATA_FILE "/usr/share/zoneinfo/zone.tab"
+-#else
+-#  define TZ_DATA_FILE "/usr/share/lib/zoneinfo/tab/zone_sun.tab"
+-#endif
++#define TZ_DATA_FILE "@tzdata@/share/zoneinfo/zone.tab"
+ 
+ typedef struct _TzDB TzDB;
+ typedef struct _TzLocation TzLocation;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/default.nix
new file mode 100644
index 000000000000..493e0342333f
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/default.nix
@@ -0,0 +1,78 @@
+{ lib
+, stdenv
+, fetchurl
+, meson
+, ninja
+, gettext
+, pkg-config
+, glib
+, gnome
+, gnome-menus
+, substituteAll
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-shell-extensions";
+  version = "45.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-shell-extensions/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "JC4VoMBuggw/2N1q6sGo74Zc5YiC5Zda8dZZNLtNQmE=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix_gmenu.patch;
+      gmenu_path = "${gnome-menus}/lib/girepository-1.0";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    glib
+  ];
+
+  mesonFlags = [
+    "-Dextension_set=all"
+  ];
+
+  preFixup = ''
+    # Since we do not install the schemas to central location,
+    # let’s link them to where extensions installed
+    # through the extension portal would look for them.
+    # Adapted from export-zips.sh in the source.
+
+    extensiondir=$out/share/gnome-shell/extensions
+    schemadir=${glib.makeSchemaPath "$out" "$name"}
+
+    for f in $extensiondir/*; do
+      name=$(basename "''${f%%@*}")
+      schema=$schemadir/org.gnome.shell.extensions.$name.gschema.xml
+      schemas_compiled=$schemadir/gschemas.compiled
+
+      if [[ -f $schema ]]; then
+        mkdir "$f/schemas"
+        ln -s "$schema" "$f/schemas"
+        ln -s "$schemas_compiled" "$f/schemas"
+      fi
+    done
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Projects/GnomeShell/Extensions";
+    description = "Modify and extend GNOME Shell functionality and behavior";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/fix_gmenu.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/fix_gmenu.patch
new file mode 100644
index 000000000000..1254f532d611
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell-extensions/fix_gmenu.patch
@@ -0,0 +1,22 @@
+diff --git a/extensions/apps-menu/extension.js b/extensions/apps-menu/extension.js
+index 6eb58f1..28e1195 100644
+--- a/extensions/apps-menu/extension.js
++++ b/extensions/apps-menu/extension.js
+@@ -10,7 +10,7 @@ import Atk from 'gi://Atk';
+ import Clutter from 'gi://Clutter';
+ import Gio from 'gi://Gio';
+ import GLib from 'gi://GLib';
+-import GMenu from 'gi://GMenu';
++import GIRepository from 'gi://GIRepository';
+ import GObject from 'gi://GObject';
+ import Gtk from 'gi://Gtk';
+ import Meta from 'gi://Meta';
+@@ -25,6 +25,8 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js';
+ import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js';
+ import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js';
+ 
++GIRepository.Repository.prepend_search_path('@gmenu_path@');
++const {default: GMenu} = await import('gi://GMenu');
+ const appSys = Shell.AppSystem.get_default();
+ 
+ const APPLICATION_ICON_SIZE = 32;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/default.nix
new file mode 100644
index 000000000000..2471061ae4f0
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/default.nix
@@ -0,0 +1,234 @@
+{ fetchurl
+, fetchpatch
+, substituteAll
+, lib, stdenv
+, meson
+, ninja
+, pkg-config
+, gnome
+, json-glib
+, gettext
+, libsecret
+, python3
+, polkit
+, networkmanager
+, gtk-doc
+, docbook-xsl-nons
+, at-spi2-core
+, libstartup_notification
+, unzip
+, shared-mime-info
+, libgweather
+, librsvg
+, webp-pixbuf-loader
+, geoclue2
+, perl
+, docbook_xml_dtd_45
+, desktop-file-utils
+, libpulseaudio
+, libical
+, gobject-introspection
+, wrapGAppsHook4
+, libxslt
+, gcr_4
+, accountsservice
+, gdk-pixbuf
+, gdm
+, upower
+, ibus
+, libnma-gtk4
+, gnome-desktop
+, gsettings-desktop-schemas
+, gnome-keyring
+, glib
+, gjs
+, mutter
+, evolution-data-server-gtk4
+, gtk3
+, gtk4
+, libadwaita
+, sassc
+, systemd
+, pipewire
+, gst_all_1
+, adwaita-icon-theme
+, gnome-bluetooth
+, gnome-clocks
+, gnome-settings-daemon
+, gnome-autoar
+, gnome-tecla
+, asciidoc
+, bash-completion
+, mesa
+}:
+
+let
+  pythonEnv = python3.withPackages (ps: with ps; [ pygobject3 ]);
+in
+stdenv.mkDerivation rec {
+  pname = "gnome-shell";
+  version = "45.1";
+
+  outputs = [ "out" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-shell/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "FfykvWEpqLP5kBl/vR7ljXS2QVEK+q8Igqf6NmNPxfI=";
+  };
+
+  patches = [
+    # Hardcode paths to various dependencies so that they can be found at runtime.
+    (substituteAll {
+      src = ./fix-paths.patch;
+      glib_compile_schemas = "${glib.dev}/bin/glib-compile-schemas";
+      gsettings = "${glib.bin}/bin/gsettings";
+      tecla = "${lib.getBin gnome-tecla}/bin/tecla";
+      unzip = "${lib.getBin unzip}/bin/unzip";
+    })
+
+    # Use absolute path for libshew installation to make our patched gobject-introspection
+    # aware of the location to hardcode in the generated GIR file.
+    ./shew-gir-path.patch
+
+    # Make D-Bus services wrappable.
+    ./wrap-services.patch
+
+    # Fix greeter logo being too big.
+    # https://gitlab.gnome.org/GNOME/gnome-shell/issues/2591
+    # Reverts https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1101
+    ./greeter-logo-size.patch
+
+    # Work around failing fingerprint auth
+    (fetchpatch {
+      url = "https://src.fedoraproject.org/rpms/gnome-shell/raw/9a647c460b651aaec0b8a21f046cc289c1999416/f/0001-gdm-Work-around-failing-fingerprint-auth.patch";
+      sha256 = "pFvZli3TilUt6YwdZztpB8Xq7O60XfuWUuPMMVSpqLw=";
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    docbook-xsl-nons
+    docbook_xml_dtd_45
+    gtk-doc
+    perl
+    wrapGAppsHook4
+    sassc
+    desktop-file-utils
+    libxslt.bin
+    asciidoc
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    systemd
+    gsettings-desktop-schemas
+    gnome-keyring
+    glib
+    gcr_4
+    accountsservice
+    libsecret
+    polkit
+    gdk-pixbuf
+    librsvg
+    networkmanager
+    libstartup_notification
+    gjs
+    mutter
+    libpulseaudio
+    evolution-data-server-gtk4
+    libical
+    gtk3
+    gtk4
+    libadwaita
+    gdm
+    geoclue2
+    adwaita-icon-theme
+    gnome-bluetooth
+    gnome-clocks # schemas needed
+    at-spi2-core
+    upower
+    ibus
+    gnome-desktop
+    gnome-settings-daemon
+    mesa
+
+    # recording
+    pipewire
+    gst_all_1.gstreamer
+    gst_all_1.gst-plugins-base
+    gst_all_1.gst-plugins-good
+
+    # not declared at build time, but typelib is needed at runtime
+    libgweather
+    libnma-gtk4
+
+    # for gnome-extension tool
+    bash-completion
+    gnome-autoar
+    json-glib
+
+    # for tools
+    pythonEnv
+  ];
+
+  mesonFlags = [
+    "-Dgtk_doc=true"
+    "-Dtests=false"
+  ];
+
+  postPatch = ''
+    patchShebangs src/data-to-c.pl
+
+    # We can generate it ourselves.
+    rm -f man/gnome-shell.1
+    rm data/theme/gnome-shell-{light,dark}.css
+  '';
+
+  postInstall = ''
+    # Pull in WebP support for gnome-backgrounds.
+    # In postInstall to run before gappsWrapperArgsHook.
+    export GDK_PIXBUF_MODULE_FILE="${gnome._gdkPixbufCacheBuilder_DO_NOT_USE {
+      extraLoaders = [
+        librsvg
+        webp-pixbuf-loader
+      ];
+    }}"
+  '';
+
+  preFixup = ''
+    gappsWrapperArgs+=(
+      # Until glib’s xdgmime is patched
+      # Fixes “Failed to load resource:///org/gnome/shell/theme/noise-texture.png: Unrecognized image file format”
+      --prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
+    )
+  '';
+
+  postFixup = ''
+    # The services need typelibs.
+    for svc in org.gnome.ScreenSaver org.gnome.Shell.Extensions org.gnome.Shell.Notifications org.gnome.Shell.Screencast; do
+      wrapGApp $out/share/gnome-shell/$svc
+    done
+  '';
+
+  separateDebugInfo = true;
+
+  passthru = {
+    mozillaPlugin = "/lib/mozilla/plugins";
+    updateScript = gnome.updateScript {
+      packageName = "gnome-shell";
+      attrPath = "gnome.gnome-shell";
+    };
+  };
+
+  meta = with lib; {
+    description = "Core user interface for the GNOME 3 desktop";
+    homepage = "https://wiki.gnome.org/Projects/GnomeShell";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/fix-paths.patch
new file mode 100644
index 000000000000..e27847378bb2
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/fix-paths.patch
@@ -0,0 +1,71 @@
+diff --git a/data/org.gnome.Shell-disable-extensions.service b/data/org.gnome.Shell-disable-extensions.service
+index de91167c5..1c9965678 100644
+--- a/data/org.gnome.Shell-disable-extensions.service
++++ b/data/org.gnome.Shell-disable-extensions.service
+@@ -11,5 +11,5 @@ ConditionPathExists=%t/gnome-shell-disable-extensions
+ [Service]
+ Type=simple
+ # Disable extensions
+-ExecStart=gsettings set org.gnome.shell disable-user-extensions true
++ExecStart=@gsettings@ set org.gnome.shell disable-user-extensions true
+ Restart=no
+diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js
+index 197cc1c1c..dd74aa167 100644
+--- a/js/ui/extensionDownloader.js
++++ b/js/ui/extensionDownloader.js
+@@ -110,7 +110,7 @@ async function extractExtensionArchive(bytes, dir) {
+     stream.close_async(GLib.PRIORITY_DEFAULT, null);
+ 
+     const unzip = Gio.Subprocess.new(
+-        ['unzip', '-uod', dir.get_path(), '--', file.get_path()],
++        ['@unzip@', '-uod', dir.get_path(), '--', file.get_path()],
+         Gio.SubprocessFlags.NONE);
+     await unzip.wait_check_async(null);
+ 
+@@ -132,7 +132,7 @@ async function extractExtensionArchive(bytes, dir) {
+     }
+ 
+     const compileSchema = Gio.Subprocess.new(
+-        ['glib-compile-schemas', '--strict', schemasPath.get_path()],
++        ['@glib_compile_schemas@', '--strict', schemasPath.get_path()],
+         Gio.SubprocessFlags.NONE);
+ 
+     try {
+diff --git a/js/ui/status/keyboard.js b/js/ui/status/keyboard.js
+index fff4e73c2..92859b099 100644
+--- a/js/ui/status/keyboard.js
++++ b/js/ui/status/keyboard.js
+@@ -1092,6 +1092,6 @@ class InputSourceIndicator extends PanelMenu.Button {
+         if (xkbVariant.length > 0)
+             description = `${description}\t${xkbVariant}`;
+ 
+-        Util.spawn(['tecla', description]);
++        Util.spawn(['@tecla@', description]);
+     }
+ });
+diff --git a/subprojects/extensions-tool/src/command-install.c b/subprojects/extensions-tool/src/command-install.c
+index 11fb4b6b7..e00e4807b 100644
+--- a/subprojects/extensions-tool/src/command-install.c
++++ b/subprojects/extensions-tool/src/command-install.c
+@@ -158,7 +158,7 @@ install_extension (const char *bundle,
+ 
+       schemapath = g_file_get_path (schemadir);
+       proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_SILENCE, &error,
+-                               "glib-compile-schemas", "--strict", schemapath,
++                               "@glib_compile_schemas@", "--strict", schemapath,
+                                NULL);
+ 
+       if (!g_subprocess_wait_check (proc, NULL, &error))
+diff --git a/subprojects/extensions-tool/src/command-pack.c b/subprojects/extensions-tool/src/command-pack.c
+index f2cfcd51a..2a9a7efdf 100644
+--- a/subprojects/extensions-tool/src/command-pack.c
++++ b/subprojects/extensions-tool/src/command-pack.c
+@@ -168,7 +168,7 @@ extension_pack_add_schemas (ExtensionPack  *pack,
+ #else
+   dstpath = g_file_get_path (dstdir);
+   proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_SILENCE, error,
+-                           "glib-compile-schemas", "--strict", dstpath, NULL);
++                           "@glib_compile_schemas@", "--strict", dstpath, NULL);
+ 
+   if (!g_subprocess_wait_check (proc, NULL, error))
+     return FALSE;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/greeter-logo-size.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/greeter-logo-size.patch
new file mode 100644
index 000000000000..e58610ddc2b2
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/greeter-logo-size.patch
@@ -0,0 +1,21 @@
+diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
+index a3e4372b4..36f6c1f47 100644
+--- a/js/gdm/loginDialog.js
++++ b/js/gdm/loginDialog.js
+@@ -43,6 +43,7 @@ import * as UserWidget from '../ui/userWidget.js';
+ const _FADE_ANIMATION_TIME = 250;
+ const _SCROLL_ANIMATION_TIME = 500;
+ const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
++const _LOGO_ICON_HEIGHT = 48;
+ 
+ export const UserListItem = GObject.registerClass({
+     Signals: {'activate': {}},
+@@ -839,7 +840,7 @@ export const LoginDialog = GObject.registerClass({
+             const scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
+             const texture = this._textureCache.load_file_async(
+                 this._logoFile,
+-                -1, -1,
++                -1, _LOGO_ICON_HEIGHT,
+                 scaleFactor, resourceScale);
+             this._logoBin.add_child(texture);
+         }
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/shew-gir-path.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/shew-gir-path.patch
new file mode 100644
index 000000000000..6d888725b5d2
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/shew-gir-path.patch
@@ -0,0 +1,11 @@
+--- a/subprojects/shew/src/meson.build
++++ b/subprojects/shew/src/meson.build
+@@ -13,7 +13,7 @@ shew_sources = [
+ libshew = library(full_name,
+   sources: shew_sources,
+   dependencies: [gtk_dep, x11_dep],
+-  install_dir: pkglibdir,
++  install_dir: get_option('prefix') / pkglibdir,
+   install: true,
+ )
+ 
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/wrap-services.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/wrap-services.patch
new file mode 100644
index 000000000000..eca485c32124
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-shell/wrap-services.patch
@@ -0,0 +1,57 @@
+diff --git a/js/dbusServices/dbus-service.in b/js/dbusServices/dbus-service.in
+old mode 100644
+new mode 100755
+index 5c698f58a..1ed61a7e3
+--- a/js/dbusServices/dbus-service.in
++++ b/js/dbusServices/dbus-service.in
+@@ -1,3 +1,9 @@
++#!@gjs@ -m
++
++// gjs determines the package name from argv[0], which is .*-wrapped
++// so we need to override it to the original one.
++imports.package._findEffectiveEntryPointName = () => '@service@'
++
+ import {programInvocationName, programArgs} from 'system';
+ 
+ imports.package.init({
+diff --git a/js/dbusServices/dbus-service.service.in b/js/dbusServices/dbus-service.service.in
+index 3b0d09abe..4fd4bb66d 100644
+--- a/js/dbusServices/dbus-service.service.in
++++ b/js/dbusServices/dbus-service.service.in
+@@ -1,3 +1,3 @@
+ [D-BUS Service]
+ Name=@service@
+-Exec=@gjs@ -m @pkgdatadir@/@service@
++Exec=@pkgdatadir@/@service@
+diff --git a/js/dbusServices/meson.build b/js/dbusServices/meson.build
+index eb941ed90..552051e5a 100644
+--- a/js/dbusServices/meson.build
++++ b/js/dbusServices/meson.build
+@@ -2,6 +2,7 @@ launcherconf = configuration_data()
+ launcherconf.set('PACKAGE_NAME', meson.project_name())
+ launcherconf.set('prefix', prefix)
+ launcherconf.set('libdir', libdir)
++launcherconf.set('gjs', gjs.full_path())
+ 
+ dbus_services = {
+   'org.gnome.Shell.Extensions': 'extensions',
+@@ -18,16 +19,17 @@ endif
+ config_dir = '@0@/..'.format(meson.current_build_dir())
+ 
+ foreach service, dir : dbus_services
++  svc_launcherconf = launcherconf
++  svc_launcherconf.set('service', service)
+   configure_file(
+     input: 'dbus-service.in',
+     output: service,
+-    configuration: launcherconf,
++    configuration: svc_launcherconf,
+     install_dir: pkgdatadir,
+   )
+ 
+   serviceconf = configuration_data()
+   serviceconf.set('service', service)
+-  serviceconf.set('gjs', gjs.full_path())
+   serviceconf.set('pkgdatadir', pkgdatadir)
+ 
+   configure_file(
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-software/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-software/default.nix
new file mode 100644
index 000000000000..931a2d643dd2
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-software/default.nix
@@ -0,0 +1,125 @@
+{ lib
+, stdenv
+, fetchurl
+, substituteAll
+, pkg-config
+, meson
+, ninja
+, gettext
+, gnome
+, wrapGAppsHook4
+, packagekit
+, ostree
+, glib
+, appstream
+, libsoup_3
+, libadwaita
+, polkit
+, isocodes
+, gspell
+, libxslt
+, gobject-introspection
+, flatpak
+, fwupd
+, gtk4
+, gsettings-desktop-schemas
+, gnome-desktop
+, libgudev
+, libxmlb
+, malcontent
+, json-glib
+, libsecret
+, valgrind-light
+, docbook-xsl-nons
+, docbook_xml_dtd_42
+, docbook_xml_dtd_43
+, gtk-doc
+, desktop-file-utils
+, libsysprof-capture
+, gst_all_1
+}:
+
+let
+  withFwupd = stdenv.hostPlatform.isx86;
+in
+
+stdenv.mkDerivation rec {
+  pname = "gnome-software";
+  version = "45.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-software/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "1ySF96bgkX9k7b7daP17VyRsbr8QxaRRCLY5RmNXeKI=";
+  };
+
+  patches = [
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit isocodes;
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    wrapGAppsHook4
+    libxslt
+    docbook_xml_dtd_42
+    docbook_xml_dtd_43
+    valgrind-light
+    docbook-xsl-nons
+    gtk-doc
+    desktop-file-utils
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    gtk4
+    glib
+    packagekit
+    appstream
+    libsoup_3
+    libadwaita
+    gsettings-desktop-schemas
+    gnome-desktop
+    gspell
+    json-glib
+    libsecret
+    ostree
+    polkit
+    flatpak
+    libgudev
+    libxmlb
+    malcontent
+    libsysprof-capture
+    # For video screenshots
+    gst_all_1.gst-plugins-base
+    gst_all_1.gst-plugins-good
+  ] ++ lib.optionals withFwupd [
+    fwupd
+  ];
+
+  mesonFlags = [
+    # Requires /etc/machine-id, D-Bus system bus, etc.
+    "-Dtests=false"
+  ] ++ lib.optionals (!withFwupd) [
+    "-Dfwupd=false"
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.gnome-software";
+    };
+  };
+
+  meta = with lib; {
+    description = "Software store that lets you install and update applications and system extensions";
+    homepage = "https://wiki.gnome.org/Apps/Software";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-software/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-software/fix-paths.patch
new file mode 100644
index 000000000000..6f443a8a43ed
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-software/fix-paths.patch
@@ -0,0 +1,11 @@
+--- a/src/gs-language.c
++++ b/src/gs-language.c
+@@ -95,7 +95,7 @@
+ 	g_autoptr(GMarkupParseContext) context = NULL;
+ 
+ 	/* find filename */
+-	filename = g_build_filename (DATADIR, "xml", "iso-codes", "iso_639.xml", NULL);
++	filename = g_build_filename ("@isocodes@", "share", "xml", "iso-codes", "iso_639.xml", NULL);
+ 	if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
+ 		g_free (filename);
+ 		filename = g_build_filename ("/usr", "share", "xml", "iso-codes", "iso_639.xml", NULL);
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/default.nix
new file mode 100644
index 000000000000..60de20502b37
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/default.nix
@@ -0,0 +1,79 @@
+{ lib
+, stdenv
+, gettext
+, fetchurl
+, pkg-config
+, gtkmm3
+, libxml2
+, bash
+, gtk3
+, libhandy
+, glib
+, wrapGAppsHook
+, meson
+, ninja
+, gsettings-desktop-schemas
+, itstool
+, gnome
+, librsvg
+, gdk-pixbuf
+, libgtop
+, systemd
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-system-monitor";
+  version = "45.0.2";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-system-monitor/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "xeJy2Qv5mGo/hhPXbg0n+kLfrO5cAZLnOSG7lLGGii4=";
+  };
+
+  patches = [
+    # Fix pkexec detection on NixOS.
+    ./fix-paths.patch
+  ];
+
+  nativeBuildInputs = [
+    pkg-config
+    gettext
+    itstool
+    wrapGAppsHook
+    meson
+    ninja
+    glib
+  ];
+
+  buildInputs = [
+    bash
+    gtk3
+    libhandy
+    glib
+    libxml2
+    gtkmm3
+    libgtop
+    gdk-pixbuf
+    gnome.adwaita-icon-theme
+    librsvg
+    gsettings-desktop-schemas
+    systemd
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "gnome-system-monitor";
+      attrPath = "gnome.gnome-system-monitor";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/SystemMonitor";
+    description = "System Monitor shows you what programs are running and how much processor time, memory, and disk space are being used";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/fix-paths.patch
new file mode 100644
index 000000000000..967ef5e15542
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-system-monitor/fix-paths.patch
@@ -0,0 +1,12 @@
+diff --git a/src/gsm_pkexec.cpp b/src/gsm_pkexec.cpp
+index 5e1edf2f..717d7bf1 100644
+--- a/src/gsm_pkexec.cpp
++++ b/src/gsm_pkexec.cpp
+@@ -36,5 +36,6 @@ gsm_pkexec_create_root_password_dialog (const char *command)
+ gboolean
+ procman_has_pkexec (void)
+ {
+-  return g_file_test ("/usr/bin/pkexec", G_FILE_TEST_EXISTS);
++  return g_file_test ("/run/wrappers/bin/pkexec", G_FILE_TEST_EXISTS)
++      || g_file_test ("/usr/bin/pkexec", G_FILE_TEST_EXISTS);
+ }
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-terminal/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-terminal/default.nix
new file mode 100644
index 000000000000..bc524bc800db
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-terminal/default.nix
@@ -0,0 +1,103 @@
+{ stdenv
+, lib
+, fetchFromGitLab
+, meson
+, ninja
+, pkg-config
+, python3
+, libxml2
+, gnome
+, gitUpdater
+, nautilus
+, glib
+, gtk4
+, gtk3
+, libhandy
+, gsettings-desktop-schemas
+, vte
+, gettext
+, which
+, libuuid
+, vala
+, desktop-file-utils
+, itstool
+, wrapGAppsHook
+, pcre2
+, libxslt
+, docbook-xsl-nons
+, nixosTests
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-terminal";
+  version = "3.50.1";
+
+  src = fetchFromGitLab {
+    domain = "gitlab.gnome.org";
+    owner = "GNOME";
+    repo = "gnome-terminal";
+    rev = version;
+    sha256 = "sha256-lJAzmz8tvEbr371VtYjlV4+z3cSy4QrmP0vmD5WiJD4=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    gettext
+    itstool
+    which
+    libxml2
+    libxslt
+    glib # for glib-compile-schemas
+    docbook-xsl-nons
+    vala
+    desktop-file-utils
+    wrapGAppsHook
+    pcre2
+    python3
+  ];
+
+  buildInputs = [
+    glib
+    gtk4
+    gtk3
+    libhandy
+    gsettings-desktop-schemas
+    vte
+    libuuid
+    nautilus # For extension
+  ];
+
+  # Silly build system, it looks for dbus file from gnome-shell in the
+  # installation tree of the package it is configuring.
+  postPatch = ''
+    substituteInPlace src/meson.build \
+       --replace "gt_prefix / gt_dbusinterfacedir / 'org.gnome.ShellSearchProvider2.xml'" \
+       "'${gnome.gnome-shell}/share/dbus-1/interfaces/org.gnome.ShellSearchProvider2.xml'"
+
+    patchShebangs \
+      data/icons/meson_updateiconcache.py \
+      data/meson_desktopfile.py \
+      data/meson_metainfofile.py \
+      src/meson_compileschemas.py
+  '';
+
+  passthru = {
+    updateScript = gitUpdater {
+      odd-unstable = true;
+    };
+
+    tests = {
+      test = nixosTests.terminal-emulators.gnome-terminal;
+    };
+  };
+
+  meta = with lib; {
+    description = "The GNOME Terminal Emulator";
+    homepage = "https://wiki.gnome.org/Apps/Terminal";
+    platforms = platforms.linux;
+    license = licenses.gpl3Plus;
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-themes-extra/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-themes-extra/default.nix
new file mode 100644
index 000000000000..efc5318fb59b
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-themes-extra/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchurl, intltool, gtk3, gnome, librsvg, pkg-config, pango, atk, gtk2
+, gdk-pixbuf, hicolor-icon-theme }:
+
+let
+  pname = "gnome-themes-extra";
+  version = "3.28";
+in stdenv.mkDerivation rec {
+  name = "${pname}-${version}";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${name}.tar.xz";
+    sha256 = "06aqg9asq2vqi9wr29bs4v8z2bf4manhbhfghf4nvw01y2zs0jvw";
+  };
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  nativeBuildInputs = [ pkg-config intltool gtk3 ];
+  buildInputs = [ gtk3 librsvg pango atk gtk2 gdk-pixbuf ];
+  propagatedBuildInputs = [ gnome.adwaita-icon-theme hicolor-icon-theme ];
+
+  dontDropIconThemeCache = true;
+
+  postInstall = ''
+    gtk-update-icon-cache "$out"/share/icons/HighContrast
+  '';
+
+  meta = with lib; {
+    platforms = platforms.unix;
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-tour/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-tour/default.nix
new file mode 100644
index 000000000000..9ded6a332654
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-tour/default.nix
@@ -0,0 +1,74 @@
+{ lib
+, stdenv
+, rustPlatform
+, gettext
+, meson
+, ninja
+, fetchurl
+, pkg-config
+, gtk4
+, glib
+, gdk-pixbuf
+, desktop-file-utils
+, appstream-glib
+, wrapGAppsHook4
+, python3
+, gnome
+, libadwaita
+, librsvg
+, rustc
+, cargo
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-tour";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    hash = "sha256-W+S470uPTV7KzMMQSNtuCFqPe/+tqghDuOiniP8dre4=";
+  };
+
+  cargoVendorDir = "vendor";
+
+  depsBuildBuild = [
+    pkg-config
+  ];
+
+  nativeBuildInputs = [
+    appstream-glib
+    cargo
+    desktop-file-utils
+    gettext
+    glib # glib-compile-resources
+    meson
+    ninja
+    pkg-config
+    python3
+    rustPlatform.cargoSetupHook
+    rustc
+    wrapGAppsHook4
+  ];
+
+  buildInputs = [
+    gdk-pixbuf
+    glib
+    gtk4
+    libadwaita
+    librsvg
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://gitlab.gnome.org/GNOME/gnome-tour";
+    description = "GNOME Greeter & Tour";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gnome-user-share/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gnome-user-share/default.nix
new file mode 100644
index 000000000000..2a09ef1ae2b0
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gnome-user-share/default.nix
@@ -0,0 +1,70 @@
+{ stdenv
+, lib
+, gettext
+, meson
+, ninja
+, fetchurl
+, apacheHttpd
+, pkg-config
+, glib
+, libxml2
+, systemd
+, wrapGAppsHook
+, itstool
+, mod_dnssd
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "gnome-user-share";
+  version = "43.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/gnome-user-share/${lib.versions.major version}/gnome-user-share-${version}.tar.xz";
+    sha256 = "DfMGqgVYMT81Pvf1G/onwDYoGtxFZ34c+/p8n4YVOM4=";
+  };
+
+  preConfigure = ''
+    sed -e 's,^LoadModule dnssd_module.\+,LoadModule dnssd_module ${mod_dnssd}/modules/mod_dnssd.so,' \
+      -e 's,''${HTTP_MODULES_PATH},${apacheHttpd}/modules,' \
+      -i data/dav_user_2.4.conf
+  '';
+
+  mesonFlags = [
+    "-Dhttpd=${apacheHttpd.out}/bin/httpd"
+    "-Dmodules_path=${apacheHttpd}/modules"
+    "-Dsystemduserunitdir=${placeholder "out"}/etc/systemd/user"
+  ];
+
+  nativeBuildInputs = [
+    pkg-config
+    meson
+    ninja
+    gettext
+    itstool
+    libxml2
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    glib
+    systemd
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://help.gnome.org/users/gnome-user-share/3.8";
+    description = "Service that exports the contents of the Public folder in your home directory on the local network";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/gucharmap/default.nix b/nixpkgs/pkgs/desktops/gnome/core/gucharmap/default.nix
new file mode 100644
index 000000000000..91bea357d251
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/gucharmap/default.nix
@@ -0,0 +1,113 @@
+{ stdenv
+, lib
+, intltool
+, fetchFromGitLab
+, meson
+, mesonEmulatorHook
+, ninja
+, pkg-config
+, python3
+, gtk3
+, pcre2
+, glib
+, desktop-file-utils
+, gtk-doc
+, wrapGAppsHook
+, itstool
+, libxml2
+, yelp-tools
+, docbook_xsl
+, docbook_xml_dtd_412
+, gsettings-desktop-schemas
+, unzip
+, unicode-character-database
+, unihan-database
+, runCommand
+, symlinkJoin
+, gobject-introspection
+, gitUpdater
+}:
+
+let
+  # TODO: make upstream patch allowing to use the uncompressed file,
+  # preferably from XDG_DATA_DIRS.
+  # https://gitlab.gnome.org/GNOME/gucharmap/issues/13
+  unihanZip = runCommand "unihan" {} ''
+    mkdir -p $out/share/unicode
+    ln -s ${unihan-database.src} $out/share/unicode/Unihan.zip
+  '';
+  ucd = symlinkJoin {
+    name = "ucd+unihan";
+    paths = [
+      unihanZip
+      unicode-character-database
+    ];
+  };
+in stdenv.mkDerivation rec {
+  pname = "gucharmap";
+  version = "15.1.2";
+
+  outputs = [ "out" "lib" "dev" "devdoc" ];
+
+  src = fetchFromGitLab {
+    domain = "gitlab.gnome.org";
+    owner = "GNOME";
+    repo = "gucharmap";
+    rev = version;
+    sha256 = "sha256-tvFw2k5xCl+QE6cHvLj5KKdYFSghN7PVgHPmd27wh7k=";
+  };
+
+  strictDeps = true;
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    python3
+    wrapGAppsHook
+    unzip
+    intltool
+    itstool
+    gtk-doc
+    docbook_xsl
+    docbook_xml_dtd_412
+    yelp-tools
+    libxml2
+    desktop-file-utils
+    gobject-introspection
+  ] ++ lib.optionals (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) [
+    mesonEmulatorHook
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    gsettings-desktop-schemas
+    pcre2
+  ];
+
+  mesonFlags = [
+    "-Ducd_path=${ucd}/share/unicode"
+    "-Dvapi=false"
+  ];
+
+  doCheck = true;
+
+  postPatch = ''
+    patchShebangs \
+      data/meson_desktopfile.py \
+      gucharmap/gen-guch-unicode-tables.pl
+  '';
+
+  passthru = {
+    updateScript = gitUpdater {
+    };
+  };
+
+  meta = with lib; {
+    description = "GNOME Character Map, based on the Unicode Character Database";
+    homepage = "https://wiki.gnome.org/Apps/Gucharmap";
+    license = licenses.gpl3;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/libgnome-keyring/default.nix b/nixpkgs/pkgs/desktops/gnome/core/libgnome-keyring/default.nix
new file mode 100644
index 000000000000..f6d2eb4bf63a
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/libgnome-keyring/default.nix
@@ -0,0 +1,35 @@
+{ lib, stdenv, fetchurl, glib, dbus, libgcrypt, pkg-config, intltool, gobject-introspection, gnome
+, testers
+}:
+
+stdenv.mkDerivation (finalAttrs: {
+  pname = "libgnome-keyring";
+  version = "3.12.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/libgnome-keyring/${lib.versions.majorMinor finalAttrs.version}/libgnome-keyring-${finalAttrs.version}.tar.xz";
+    sha256 = "c4c178fbb05f72acc484d22ddb0568f7532c409b0a13e06513ff54b91e947783";
+  };
+
+  outputs = [ "out" "dev" ];
+
+  propagatedBuildInputs = [ glib gobject-introspection dbus libgcrypt ];
+  nativeBuildInputs = [ pkg-config intltool ];
+
+  passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
+
+  meta = {
+    description = "Framework for managing passwords and other secrets";
+    homepage = "https://wiki.gnome.org/Projects/GnomeKeyring";
+    license = with lib.licenses; [ gpl2Plus lgpl2Plus ];
+    pkgConfigModules = [ "gnome-keyring-1" ];
+    platforms = lib.platforms.unix;
+    maintainers = [];
+
+    longDescription = ''
+      gnome-keyring is a program that keeps password and other secrets for
+      users. The library libgnome-keyring is used by applications to integrate
+      with the gnome-keyring system.
+    '';
+  };
+})
diff --git a/nixpkgs/pkgs/desktops/gnome/core/mutter/43/default.nix b/nixpkgs/pkgs/desktops/gnome/core/mutter/43/default.nix
new file mode 100644
index 000000000000..e565603ae576
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/mutter/43/default.nix
@@ -0,0 +1,193 @@
+{ fetchurl
+, runCommand
+, lib
+, fetchpatch
+, stdenv
+, pkg-config
+, gnome
+, gettext
+, gobject-introspection
+, cairo
+, colord
+, lcms2
+, pango
+, json-glib
+, libstartup_notification
+, libcanberra
+, ninja
+, xvfb-run
+, xkeyboard_config
+, libxcvt
+, libxkbfile
+, libXdamage
+, libxkbcommon
+, libXtst
+, libinput
+, libdrm
+, gsettings-desktop-schemas
+, glib
+, gtk3
+, gnome-desktop
+, pipewire
+, libgudev
+, libwacom
+, xwayland
+, mesa
+, meson
+, gnome-settings-daemon
+, xorgserver
+, python3
+, wrapGAppsHook
+, gi-docgen
+, sysprof
+, libsysprof-capture
+, desktop-file-utils
+, libcap_ng
+, egl-wayland
+, graphene
+, wayland
+, wayland-protocols
+}:
+
+stdenv.mkDerivation (finalAttrs: {
+  pname = "mutter";
+  version = "43.8";
+
+  outputs = [ "out" "dev" "man" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/mutter/${lib.versions.major finalAttrs.version}/mutter-${finalAttrs.version}.tar.xz";
+    sha256 = "TjTh8XWTS9hJqEvZX6Nb8G6EEuAt8loDbC8RNdUz8oE=";
+  };
+
+  patches = [
+    # Fix build with separate sysprof.
+    # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2572
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/mutter/-/commit/285a5a4d54ca83b136b787ce5ebf1d774f9499d5.patch";
+      sha256 = "/npUE3idMSTVlFptsDpZmGWjZ/d2gqruVlJKq4eF4xU=";
+    })
+
+    # Remove support for window shading.
+    # The corresponding key was removed in gsettings-desktop-schemas 45.alpha.
+    # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2884
+    #
+    # Fetch the patch from magpie as they share same code base and this feature
+    # is never supported on wayland (note that magpie 0.9.x won't support wayland).
+    # https://github.com/BuddiesOfBudgie/magpie/issues/9
+    (fetchpatch {
+      url = "https://github.com/BuddiesOfBudgie/magpie/commit/4177c466375462ca8ed8fdb60913df4422f19144.patch";
+      sha256 = "NVx40WDnlUL050D529KVohvNBdVrheXxmJ73U3+KSeQ=";
+    })
+  ];
+
+  mesonFlags = [
+    "-Degl_device=true"
+    "-Dinstalled_tests=false" # TODO: enable these
+    "-Dwayland_eglstream=true"
+    "-Dprofiler=true"
+    "-Dxwayland_path=${lib.getExe xwayland}"
+    # This should be auto detected, but it looks like it manages a false
+    # positive.
+    "-Dxwayland_initfd=disabled"
+    "-Ddocs=true"
+  ];
+
+  propagatedBuildInputs = [
+    # required for pkg-config to detect mutter-clutter
+    json-glib
+    libXtst
+    libcap_ng
+    graphene
+  ];
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    gettext
+    libxcvt
+    mesa # needed for gbm
+    meson
+    ninja
+    xvfb-run
+    pkg-config
+    python3
+    wrapGAppsHook
+    gi-docgen
+    xorgserver
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    cairo
+    egl-wayland
+    glib
+    gnome-desktop
+    gnome-settings-daemon
+    gsettings-desktop-schemas
+    gtk3
+    libcanberra
+    libdrm
+    libgudev
+    libinput
+    libstartup_notification
+    libwacom
+    libxkbcommon
+    libxkbfile
+    libXdamage
+    colord
+    lcms2
+    pango
+    pipewire
+    sysprof # for D-Bus interfaces
+    libsysprof-capture
+    xkeyboard_config
+    xwayland
+    wayland
+    wayland-protocols
+  ];
+
+  postPatch = ''
+    patchShebangs src/backends/native/gen-default-modes.py
+
+    # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3187
+    substituteInPlace meson.build \
+      --replace "dependency('sysprof-4')" "dependency('sysprof-6')"
+  '';
+
+  postInstall = ''
+    ${glib.dev}/bin/glib-compile-schemas "$out/share/glib-2.0/schemas"
+  '';
+
+  postFixup = ''
+    # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
+    # TODO: Move this into a directory devhelp can find.
+    moveToOutput "share/mutter-11/doc" "$devdoc"
+  '';
+
+  # Install udev files into our own tree.
+  PKG_CONFIG_UDEV_UDEVDIR = "${placeholder "out"}/lib/udev";
+
+  separateDebugInfo = true;
+
+  passthru = {
+    libdir = "${finalAttrs.finalPackage}/lib/mutter-11";
+
+    tests = {
+      libdirExists = runCommand "mutter-libdir-exists" {} ''
+        if [[ ! -d ${finalAttrs.finalPackage.libdir} ]]; then
+          echo "passthru.libdir should contain a directory, “${finalAttrs.finalPackage.libdir}” is not one."
+          exit 1
+        fi
+        touch $out
+      '';
+    };
+  };
+
+  meta = with lib; {
+    description = "A window manager for GNOME";
+    homepage = "https://gitlab.gnome.org/GNOME/mutter";
+    license = licenses.gpl2Plus;
+    maintainers = teams.pantheon.members;
+    platforms = platforms.linux;
+  };
+})
diff --git a/nixpkgs/pkgs/desktops/gnome/core/mutter/default.nix b/nixpkgs/pkgs/desktops/gnome/core/mutter/default.nix
new file mode 100644
index 000000000000..03414346f643
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/mutter/default.nix
@@ -0,0 +1,209 @@
+{ fetchurl
+, runCommand
+, lib
+, stdenv
+, pkg-config
+, gnome
+, gettext
+, gobject-introspection
+, cairo
+, colord
+, lcms2
+, pango
+, json-glib
+, libstartup_notification
+, libcanberra
+, ninja
+, xvfb-run
+, libxcvt
+, libICE
+, libX11
+, libXcomposite
+, libXcursor
+, libXdamage
+, libXext
+, libXfixes
+, libXi
+, libXtst
+, libxkbfile
+, xkeyboard_config
+, libxkbcommon
+, libXrender
+, libxcb
+, libXrandr
+, libXinerama
+, libXau
+, libinput
+, libdrm
+, libei
+, gsettings-desktop-schemas
+, glib
+, atk
+, gtk4
+, fribidi
+, harfbuzz
+, gnome-desktop
+, pipewire
+, libgudev
+, libwacom
+, libSM
+, xwayland
+, mesa
+, meson
+, gnome-settings-daemon
+, xorgserver
+, python3
+, wrapGAppsHook4
+, gi-docgen
+, sysprof
+, libsysprof-capture
+, desktop-file-utils
+, libcap_ng
+, egl-wayland
+, graphene
+, wayland
+, wayland-protocols
+}:
+
+stdenv.mkDerivation (finalAttrs: {
+  pname = "mutter";
+  version = "45.1";
+
+  outputs = [ "out" "dev" "man" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/mutter/${lib.versions.major finalAttrs.version}/mutter-${finalAttrs.version}.tar.xz";
+    sha256 = "LNPF77Itt2x5MRyxiJoaqy/rNbSk3QPzgiqreZnaISw=";
+  };
+
+  mesonFlags = [
+    "-Degl_device=true"
+    "-Dinstalled_tests=false" # TODO: enable these
+    "-Dtests=false"
+    "-Dwayland_eglstream=true"
+    "-Dprofiler=true"
+    "-Dxwayland_path=${lib.getExe xwayland}"
+    # This should be auto detected, but it looks like it manages a false
+    # positive.
+    "-Dxwayland_initfd=disabled"
+    "-Ddocs=true"
+  ];
+
+  propagatedBuildInputs = [
+    # required for pkg-config to detect mutter-clutter
+    json-glib
+    libcap_ng
+    graphene
+  ];
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    gettext
+    libxcvt
+    mesa # needed for gbm
+    meson
+    ninja
+    xvfb-run
+    pkg-config
+    python3
+    wrapGAppsHook4
+    gi-docgen
+    xorgserver
+    gobject-introspection
+  ];
+
+  buildInputs = [
+    cairo
+    egl-wayland
+    glib
+    gnome-desktop
+    gnome-settings-daemon
+    gsettings-desktop-schemas
+    atk
+    fribidi
+    harfbuzz
+    libcanberra
+    libdrm
+    libei
+    libgudev
+    libinput
+    libstartup_notification
+    libwacom
+    libSM
+    colord
+    lcms2
+    pango
+    pipewire
+    sysprof # for D-Bus interfaces
+    libsysprof-capture
+    xwayland
+    wayland
+    wayland-protocols
+  ] ++ [
+    # X11 client
+    gtk4
+    libICE
+    libX11
+    libXcomposite
+    libXcursor
+    libXdamage
+    libXext
+    libXfixes
+    libXi
+    libXtst
+    libxkbfile
+    xkeyboard_config
+    libxkbcommon
+    libXrender
+    libxcb
+    libXrandr
+    libXinerama
+    libXau
+  ];
+
+  postPatch = ''
+    patchShebangs src/backends/native/gen-default-modes.py
+  '';
+
+  postInstall = ''
+    ${glib.dev}/bin/glib-compile-schemas "$out/share/glib-2.0/schemas"
+  '';
+
+  postFixup = ''
+    # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
+    # TODO: Move this into a directory devhelp can find.
+    moveToOutput "share/mutter-13/doc" "$devdoc"
+  '';
+
+  # Install udev files into our own tree.
+  PKG_CONFIG_UDEV_UDEVDIR = "${placeholder "out"}/lib/udev";
+
+  separateDebugInfo = true;
+
+  passthru = {
+    libdir = "${finalAttrs.finalPackage}/lib/mutter-13";
+
+    tests = {
+      libdirExists = runCommand "mutter-libdir-exists" {} ''
+        if [[ ! -d ${finalAttrs.finalPackage.libdir} ]]; then
+          echo "passthru.libdir should contain a directory, “${finalAttrs.finalPackage.libdir}” is not one."
+          exit 1
+        fi
+        touch $out
+      '';
+    };
+
+    updateScript = gnome.updateScript {
+      packageName = "mutter";
+      attrPath = "gnome.mutter";
+    };
+  };
+
+  meta = with lib; {
+    description = "A window manager for GNOME";
+    homepage = "https://gitlab.gnome.org/GNOME/mutter";
+    license = licenses.gpl2Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+})
diff --git a/nixpkgs/pkgs/desktops/gnome/core/nautilus/default.nix b/nixpkgs/pkgs/desktops/gnome/core/nautilus/default.nix
new file mode 100644
index 000000000000..395b4f41c76b
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/nautilus/default.nix
@@ -0,0 +1,134 @@
+{ lib
+, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gi-docgen
+, docbook-xsl-nons
+, gettext
+, libxml2
+, desktop-file-utils
+, wrapGAppsHook4
+, gtk4
+, libadwaita
+, libportal-gtk4
+, gnome
+, gnome-autoar
+, glib-networking
+, shared-mime-info
+, libnotify
+, libexif
+, libseccomp
+, librsvg
+, webp-pixbuf-loader
+, tracker
+, tracker-miners
+, gexiv2
+, libselinux
+, libcloudproviders
+, gdk-pixbuf
+, substituteAll
+, gnome-desktop
+, gst_all_1
+, gsettings-desktop-schemas
+, gnome-user-share
+, gobject-introspection
+}:
+
+stdenv.mkDerivation rec {
+  pname = "nautilus";
+  version = "45.1";
+
+  outputs = [ "out" "dev" "devdoc" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "I72qmoVGbFk3qJ2t3QgO0DvMK0notkr2ByBjU73oL+M=";
+  };
+
+  patches = [
+    # Allow changing extension directory using environment variable.
+    ./extension_dir.patch
+
+    # Hardcode required paths.
+    (substituteAll {
+      src = ./fix-paths.patch;
+      inherit tracker;
+    })
+  ];
+
+  nativeBuildInputs = [
+    desktop-file-utils
+    gettext
+    gobject-introspection
+    libxml2
+    meson
+    ninja
+    pkg-config
+    gi-docgen
+    docbook-xsl-nons
+    wrapGAppsHook4
+  ];
+
+  buildInputs = [
+    gexiv2
+    glib-networking
+    gnome-desktop
+    gnome.adwaita-icon-theme
+    gsettings-desktop-schemas
+    gnome-user-share
+    gst_all_1.gst-plugins-base
+    gtk4
+    libadwaita
+    libportal-gtk4
+    libexif
+    libnotify
+    libseccomp
+    libselinux
+    gdk-pixbuf
+    libcloudproviders
+    shared-mime-info
+    tracker
+    tracker-miners
+    gnome-autoar
+  ];
+
+  propagatedBuildInputs = [
+    gtk4
+  ];
+
+  mesonFlags = [
+    "-Ddocs=true"
+  ];
+
+  preFixup = ''
+    gappsWrapperArgs+=(
+      # Thumbnailers
+      --prefix XDG_DATA_DIRS : "${gdk-pixbuf}/share"
+      --prefix XDG_DATA_DIRS : "${librsvg}/share"
+      --prefix XDG_DATA_DIRS : "${webp-pixbuf-loader}/share"
+      --prefix XDG_DATA_DIRS : "${shared-mime-info}/share"
+    )
+  '';
+
+  postFixup = ''
+    # Cannot be in postInstall, otherwise _multioutDocs hook in preFixup will move right back.
+    moveToOutput "share/doc" "$devdoc"
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    description = "The file manager for GNOME";
+    homepage = "https://wiki.gnome.org/Apps/Files";
+    license = licenses.gpl3Plus;
+    platforms = platforms.linux;
+    maintainers = teams.gnome.members;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/nautilus/extension_dir.patch b/nixpkgs/pkgs/desktops/gnome/core/nautilus/extension_dir.patch
new file mode 100644
index 000000000000..a1bdd64f989b
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/nautilus/extension_dir.patch
@@ -0,0 +1,26 @@
+diff --git a/src/nautilus-module.c b/src/nautilus-module.c
+index cd889ff18..e2cd6468e 100644
+--- a/src/nautilus-module.c
++++ b/src/nautilus-module.c
+@@ -267,6 +267,7 @@ void
+ nautilus_module_setup (void)
+ {
+     static gboolean initialized = FALSE;
++    const gchar* extensiondir = NULL;
+     const gchar *disable_plugins;
+ 
+     disable_plugins = g_getenv ("NAUTILUS_DISABLE_PLUGINS");
+@@ -280,7 +281,12 @@ nautilus_module_setup (void)
+     {
+         initialized = TRUE;
+ 
+-        load_module_dir (NAUTILUS_EXTENSIONDIR);
++        extensiondir = g_getenv ("NAUTILUS_4_EXTENSION_DIR");
++        if (extensiondir == NULL) {
++            extensiondir = NAUTILUS_EXTENSIONDIR;
++        }
++
++        load_module_dir (extensiondir);
+ 
+         eel_debug_call_at_shutdown (free_module_objects);
+     }
diff --git a/nixpkgs/pkgs/desktops/gnome/core/nautilus/fix-paths.patch b/nixpkgs/pkgs/desktops/gnome/core/nautilus/fix-paths.patch
new file mode 100644
index 000000000000..dc9874359b23
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/nautilus/fix-paths.patch
@@ -0,0 +1,13 @@
+diff --git a/src/nautilus-tag-manager.c b/src/nautilus-tag-manager.c
+index 28b96c996..0b1fad9ab 100644
+--- a/src/nautilus-tag-manager.c
++++ b/src/nautilus-tag-manager.c
+@@ -962,7 +962,7 @@ child_watch_cb (GPid     pid,
+ static void
+ export_tracker2_data (NautilusTagManager *self)
+ {
+-    gchar *argv[] = {"tracker3", "export", "--2to3", "files-starred", "--keyfile", NULL};
++    gchar *argv[] = {"@tracker@/bin/tracker3", "export", "--2to3", "files-starred", "--keyfile", NULL};
+     gint stdout_fd;
+     GPid child_pid;
+     g_autoptr (GError) error = NULL;
diff --git a/nixpkgs/pkgs/desktops/gnome/core/rygel/add-option-for-installation-sysconfdir.patch b/nixpkgs/pkgs/desktops/gnome/core/rygel/add-option-for-installation-sysconfdir.patch
new file mode 100644
index 000000000000..5204e3518aba
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/rygel/add-option-for-installation-sysconfdir.patch
@@ -0,0 +1,35 @@
+diff --git a/meson.build b/meson.build
+index 27bde61f..3d434de9 100644
+--- a/meson.build
++++ b/meson.build
+@@ -22,7 +22,11 @@ if not get_option('uninstalled')
+     rygel_datadir = join_paths(get_option('prefix'), get_option('datadir'), 'rygel')
+     rygel_libexecdir = join_paths(get_option('prefix'), get_option('libexecdir'),
+     'rygel')
+-    rygel_sysconfdir = join_paths(get_option('prefix'), get_option('sysconfdir'))
++    if get_option('sysconfdir_install') != ''
++        rygel_sysconfdir = join_paths(get_option('prefix'), get_option('sysconfdir_install'))
++    else
++        rygel_sysconfdir = join_paths(get_option('prefix'), get_option('sysconfdir'))
++    endif
+     rygel_plugindir = join_paths(rygel_libdir, 'rygel-2.8', 'plugins')
+     rygel_enginedir = join_paths(rygel_libdir, 'rygel-2.8', 'engines')
+     rygel_presetdir = join_paths(rygel_datadir, 'presets')
+@@ -57,7 +61,7 @@ conf.set_quoted('DATA_DIR', rygel_datadir)
+ conf.set_quoted('PLUGIN_DIR', rygel_plugindir)
+ conf.set_quoted('BIG_ICON_DIR', rygel_bigicondir)
+ conf.set_quoted('SMALL_ICON_DIR', rygel_smallicondir)
+-conf.set_quoted('SYS_CONFIG_DIR', rygel_sysconfdir)
++conf.set_quoted('SYS_CONFIG_DIR', get_option('sysconfdir'))
+ conf.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir')))
+ conf.set_quoted('MX_EXTRACT_PATH', join_paths(rygel_libexecdir, 'mx-extract'))
+ conf.set_quoted('DESKTOP_DIR', join_paths(get_option('prefix'), get_option('datadir'), 'applications'))
+diff --git a/meson_options.txt b/meson_options.txt
+index fd04776a..3dee43ba 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -1,3 +1,4 @@
++option('sysconfdir_install', type: 'string', value: '', description: 'sysconfdir to use during installation')
+ option('uninstalled', type: 'boolean', value: 'false', description: 'Run Rygel from build directory only')
+ option('api-docs', type: 'boolean', value: 'false', description: 'Build the API documentation')
+ option('man_pages', type: 'boolean', value: 'true', description: 'Build the man pages')
diff --git a/nixpkgs/pkgs/desktops/gnome/core/rygel/default.nix b/nixpkgs/pkgs/desktops/gnome/core/rygel/default.nix
new file mode 100644
index 000000000000..059fcde8ea3c
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/rygel/default.nix
@@ -0,0 +1,108 @@
+{ lib, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, vala
+, gettext
+, libxml2
+, gobject-introspection
+, wrapGAppsHook
+, python3
+, glib
+, gssdp_1_6
+, gupnp_1_6
+, gupnp-av
+, gupnp-dlna
+, gst_all_1
+, libgee
+, libsoup_3
+, gtk3
+, libmediaart
+, sqlite
+, systemd
+, tracker
+, shared-mime-info
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "rygel";
+  version = "0.42.4";
+
+  # TODO: split out lib
+  outputs = [ "out" "dev" ];
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "YxDfqi0zK2YRm5sCD61qS9J9m8Yfr3gMpcoLYoEzA/c=";
+  };
+
+  patches = [
+    ./add-option-for-installation-sysconfdir.patch
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    pkg-config
+    vala
+    gettext
+    libxml2
+    gobject-introspection
+    wrapGAppsHook
+    python3
+  ];
+
+  buildInputs = [
+    glib
+    gssdp_1_6
+    gupnp_1_6
+    gupnp-av
+    gupnp-dlna
+    libgee
+    libsoup_3
+    gtk3
+    libmediaart
+    sqlite
+    systemd
+    tracker
+    shared-mime-info
+  ] ++ (with gst_all_1; [
+    gstreamer
+    gst-editing-services
+    gst-plugins-base
+    gst-plugins-good
+    gst-plugins-bad
+    gst-plugins-ugly
+  ]);
+
+  mesonFlags = [
+    "-Dsystemd-user-units-dir=${placeholder "out"}/lib/systemd/user"
+    "-Dapi-docs=false"
+    "--sysconfdir=/etc"
+    "-Dsysconfdir_install=${placeholder "out"}/etc"
+  ];
+
+  doCheck = true;
+
+  postPatch = ''
+    patchShebangs data/xml/process-xml.py
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+      versionPolicy = "odd-unstable";
+    };
+  };
+
+  meta = with lib; {
+    description = "A home media solution (UPnP AV MediaServer) that allows you to easily share audio, video and pictures to other devices";
+    homepage = "https://wiki.gnome.org/Projects/Rygel";
+    license = licenses.lgpl21Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/simple-scan/default.nix b/nixpkgs/pkgs/desktops/gnome/core/simple-scan/default.nix
new file mode 100644
index 000000000000..9d7e60eed64d
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/simple-scan/default.nix
@@ -0,0 +1,88 @@
+{ lib, stdenv
+, fetchurl
+, meson
+, ninja
+, pkg-config
+, gettext
+, itstool
+, python3
+, wrapGAppsHook
+, cairo
+, gdk-pixbuf
+, colord
+, glib
+, gtk3
+, gusb
+, packagekit
+, libhandy
+, libwebp
+, libxml2
+, sane-backends
+, vala
+, gnome
+, gobject-introspection
+}:
+
+stdenv.mkDerivation rec {
+  pname = "simple-scan";
+  version = "44.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/${pname}/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-Obhw/Ub0R/dH6uzC3yYEnvdzGFCZ8OE8Z1ZWJk3ZjpU=";
+  };
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    gettext
+    itstool
+    pkg-config
+    python3
+    wrapGAppsHook
+    libxml2
+    gobject-introspection # For setup hook
+    vala
+  ];
+
+  buildInputs = [
+    cairo
+    gdk-pixbuf
+    colord
+    glib
+    gusb
+    gtk3
+    libhandy
+    libwebp
+    packagekit
+    sane-backends
+  ];
+
+  postPatch = ''
+    patchShebangs data/meson_compile_gschema.py
+  '';
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "simple-scan";
+    };
+  };
+
+  meta = with lib; {
+    description = "Simple scanning utility";
+    longDescription = ''
+      A really easy way to scan both documents and photos. You can crop out the
+      bad parts of a photo and rotate it if it is the wrong way round. You can
+      print your scans, export them to pdf, or save them in a range of image
+      formats. Basically a frontend for SANE - which is the same backend as
+      XSANE uses. This means that all existing scanners will work and the
+      interface is well tested.
+    '';
+    homepage = "https://gitlab.gnome.org/GNOME/simple-scan";
+    license = licenses.gpl3Plus;
+    maintainers = teams.gnome.members;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/sushi/default.nix b/nixpkgs/pkgs/desktops/gnome/core/sushi/default.nix
new file mode 100644
index 000000000000..5c54f03d7d53
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/sushi/default.nix
@@ -0,0 +1,85 @@
+{ lib, stdenv
+, fetchurl
+, pkg-config
+, meson
+, gettext
+, gobject-introspection
+, glib
+, gnome
+, gtksourceview4
+, gjs
+, libsoup_3
+, webkitgtk_4_1
+, icu
+, wrapGAppsHook
+, gst_all_1
+, gdk-pixbuf
+, librsvg
+, gtk3
+, harfbuzz
+, ninja
+, libepoxy
+}:
+
+stdenv.mkDerivation rec {
+  pname = "sushi";
+  version = "45.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/sushi/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "al8UsFo0cf5DhTzCsOGuVITX+fhvfqN2F5gpub9Kwd0=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    meson
+    ninja
+    gettext
+    gobject-introspection
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    glib
+    gtk3
+    gnome.evince
+    icu
+    harfbuzz
+    gjs
+    gtksourceview4
+    gdk-pixbuf
+    librsvg
+    libsoup_3
+    webkitgtk_4_1
+    libepoxy
+    gst_all_1.gstreamer
+    gst_all_1.gst-plugins-base
+    (gst_all_1.gst-plugins-good.override { gtkSupport = true; })
+    gst_all_1.gst-plugins-bad
+    gst_all_1.gst-plugins-ugly
+  ];
+
+  # See https://github.com/NixOS/nixpkgs/issues/31168
+  postInstall = ''
+    for file in $out/libexec/org.gnome.NautilusPreviewer
+    do
+      sed -e $"2iimports.package._findEffectiveEntryPointName = () => \'$(basename $file)\' " \
+        -i $file
+    done
+  '';
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "sushi";
+      attrPath = "gnome.sushi";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://en.wikipedia.org/wiki/Sushi_(software)";
+    description = "A quick previewer for Nautilus";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/totem/default.nix b/nixpkgs/pkgs/desktops/gnome/core/totem/default.nix
new file mode 100644
index 000000000000..24c637909a32
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/totem/default.nix
@@ -0,0 +1,143 @@
+{ stdenv
+, lib
+, fetchurl
+, fetchpatch
+, meson
+, ninja
+, gettext
+, gst_all_1
+, python3Packages
+, shared-mime-info
+, pkg-config
+, gtk3
+, glib
+, gobject-introspection
+, totem-pl-parser
+, wrapGAppsHook
+, itstool
+, libxml2
+, vala
+, gnome
+, grilo
+, grilo-plugins
+, libpeas
+, libportal-gtk3
+, libhandy
+, adwaita-icon-theme
+, gnome-desktop
+, gsettings-desktop-schemas
+, gdk-pixbuf
+, xvfb-run
+}:
+
+stdenv.mkDerivation rec {
+  pname = "totem";
+  version = "43.0";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/totem/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "s202VZKLWJZGKk05+Dtq1m0328nJnc6wLqii43OUpB4=";
+  };
+
+  patches = [
+    # Lower X11 dependency version since we do not have it.
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/totem/-/commit/140d9eea70c3101ef3234abb4de5974cb84b13db.patch";
+      sha256 = "ohppxqMiH8Ksc9B2e3AXighfM6KVN+RNXYL+fLELSN8=";
+      revert = true;
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/totem/-/commit/2610b4536f73493587e4a5a38e01c9961fcabb96.patch";
+      sha256 = "nPfzS+LQuAlyQOz67hCdtx93w2frhgWlg1KGX5bEU38=";
+      revert = true;
+    })
+    (fetchpatch {
+      url = "https://gitlab.gnome.org/GNOME/totem/-/commit/5b871aee5292f25bbf39dca18045732e979e7a68.patch";
+      sha256 = "LqQLdgyZkIVc+/hQ5sdBLqhtjCVIMDSs9tjVXwMFodg=";
+      revert = true;
+    })
+  ];
+
+  nativeBuildInputs = [
+    meson
+    ninja
+    vala
+    pkg-config
+    gettext
+    python3Packages.python
+    itstool
+    gobject-introspection
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    gtk3
+    glib
+    grilo
+    totem-pl-parser
+    grilo-plugins
+    gst_all_1.gstreamer
+    gst_all_1.gst-plugins-base
+    (gst_all_1.gst-plugins-good.override { gtkSupport = true; })
+    gst_all_1.gst-plugins-bad
+    gst_all_1.gst-plugins-ugly
+    gst_all_1.gst-libav
+    libpeas
+    libportal-gtk3
+    libhandy
+    shared-mime-info
+    gdk-pixbuf
+    libxml2
+    adwaita-icon-theme
+    gnome-desktop
+    gsettings-desktop-schemas
+    # for plug-ins
+    python3Packages.pygobject3
+    python3Packages.dbus-python
+  ];
+
+  nativeCheckInputs = [
+    xvfb-run
+  ];
+
+  mesonFlags = [
+    # TODO: https://github.com/NixOS/nixpkgs/issues/36468
+    "-Dc_args=-I${glib.dev}/include/gio-unix-2.0"
+  ];
+
+  # Tests do not work with GStreamer 1.18.
+  # https://gitlab.gnome.org/GNOME/totem/-/issues/450
+  doCheck = false;
+
+  postPatch = ''
+    chmod +x meson_compile_python.py # patchShebangs requires executable file
+    patchShebangs \
+      ./meson_compile_python.py
+  '';
+
+  checkPhase = ''
+    runHook preCheck
+
+    xvfb-run -s '-screen 0 800x600x24' \
+      ninja test
+
+    runHook postCheck
+  '';
+
+  wrapPrefixVariables = [ "PYTHONPATH" ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "totem";
+      attrPath = "gnome.totem";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Videos";
+    description = "Movie player for the GNOME desktop based on GStreamer";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2Plus; # with exception to allow use of non-GPL compatible plug-ins
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/yelp-xsl/default.nix b/nixpkgs/pkgs/desktops/gnome/core/yelp-xsl/default.nix
new file mode 100644
index 000000000000..2fa3ec0ecdd4
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/yelp-xsl/default.nix
@@ -0,0 +1,52 @@
+{ lib, stdenv
+, gettext
+, fetchurl
+, pkg-config
+, itstool
+, libxml2
+, libxslt
+, gnome
+}:
+
+stdenv.mkDerivation rec {
+  pname = "yelp-xsl";
+  version = "42.1";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/yelp-xsl/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-I4vhULFlMIDOE5lxMw/TbTomWV4NagQKLAML89IAW80=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    gettext
+    itstool
+    libxml2
+    libxslt
+  ];
+
+  doCheck = true;
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = pname;
+      attrPath = "gnome.${pname}";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Yelp";
+    description = "Yelp's universal stylesheets for Mallard and DocBook";
+    maintainers = teams.gnome.members;
+    license = with licenses; [
+      # See https://gitlab.gnome.org/GNOME/yelp-xsl/blob/master/COPYING
+      # Stylesheets
+      lgpl2Plus
+      # Icons, unclear: https://gitlab.gnome.org/GNOME/yelp-xsl/issues/25
+      gpl2
+      # highlight.js
+      bsd3
+    ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/yelp/default.nix b/nixpkgs/pkgs/desktops/gnome/core/yelp/default.nix
new file mode 100644
index 000000000000..ee76194433c3
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/yelp/default.nix
@@ -0,0 +1,62 @@
+{ lib
+, stdenv
+, gettext
+, fetchurl
+, webkitgtk_4_1
+, pkg-config
+, gtk3
+, libhandy
+, glib
+, gnome
+, sqlite
+, itstool
+, libxml2
+, libxslt
+, gst_all_1
+, wrapGAppsHook
+}:
+
+stdenv.mkDerivation rec {
+  pname = "yelp";
+  version = "42.2";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/yelp/${lib.versions.major version}/${pname}-${version}.tar.xz";
+    sha256 = "sha256-osX9B4epCJxyLMZr0Phc33CI2HDntsyFeZ+OW/+erEs=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+    gettext
+    itstool
+    wrapGAppsHook
+  ];
+
+  buildInputs = [
+    gtk3
+    libhandy
+    glib
+    webkitgtk_4_1
+    sqlite
+    libxml2
+    libxslt
+    gnome.yelp-xsl
+    gnome.adwaita-icon-theme
+    gst_all_1.gst-plugins-base
+    gst_all_1.gst-plugins-good
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "yelp";
+    };
+  };
+
+  meta = with lib; {
+    homepage = "https://wiki.gnome.org/Apps/Yelp";
+    description = "The help viewer in Gnome";
+    maintainers = teams.gnome.members;
+    license = licenses.gpl2;
+    platforms = platforms.linux;
+  };
+}
diff --git a/nixpkgs/pkgs/desktops/gnome/core/zenity/default.nix b/nixpkgs/pkgs/desktops/gnome/core/zenity/default.nix
new file mode 100644
index 000000000000..e8be274a1f60
--- /dev/null
+++ b/nixpkgs/pkgs/desktops/gnome/core/zenity/default.nix
@@ -0,0 +1,57 @@
+{ stdenv
+, lib
+, fetchurl
+, help2man
+, meson
+, ninja
+, pkg-config
+, libxml2
+, gnome
+, gtk4
+, gettext
+, libadwaita
+, itstool
+, wrapGAppsHook4
+}:
+
+stdenv.mkDerivation rec {
+  pname = "zenity";
+  version = "3.99.2";
+
+  src = fetchurl {
+    url = "mirror://gnome/sources/zenity/${lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
+    sha256 = "oZR4kGuYi082fl6mOlkh5PmMuCVbugXrXK2LWhikFo8=";
+  };
+
+  nativeBuildInputs = [
+    help2man
+    meson
+    ninja
+    pkg-config
+    gettext
+    itstool
+    libxml2
+    wrapGAppsHook4
+  ];
+
+  buildInputs = [
+    gtk4
+    libadwaita
+  ];
+
+  passthru = {
+    updateScript = gnome.updateScript {
+      packageName = "zenity";
+      attrPath = "gnome.zenity";
+    };
+  };
+
+  meta = with lib; {
+    mainProgram = "zenity";
+    description = "Tool to display dialogs from the commandline and shell scripts";
+    homepage = "https://wiki.gnome.org/Projects/Zenity";
+    license = licenses.lgpl21Plus;
+    platforms = platforms.unix;
+    maintainers = teams.gnome.members;
+  };
+}