diff --git a/gnu/local.mk b/gnu/local.mk
index 255bb870e9..21826c9ec7 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1376,6 +1376,7 @@ dist_patch_DATA =						\
   %D%/packages/patches/gnome-online-miners-tracker-3.patch	\
   %D%/packages/patches/gnome-settings-daemon-gc.patch		\
   %D%/packages/patches/gnome-session-support-elogind.patch	\
+  %D%/packages/patches/gnome-shell-wrappable-dbus-services.patch\
   %D%/packages/patches/gnome-tweaks-search-paths.patch		\
   %D%/packages/patches/gnumach-support-noide.patch		\
   %D%/packages/patches/gnupg-default-pinentry.patch		\
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 4934ade3dd..e752232f78 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -9311,7 +9311,9 @@ (define-public gnome-shell
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
-                "01pw9qnnvh64x56z1gqh0qk6vfn0ihh4zijq23f4bpz9wszlbpwf"))))
+                "01pw9qnnvh64x56z1gqh0qk6vfn0ihh4zijq23f4bpz9wszlbpwf"))
+              (patches
+               (search-patches "gnome-shell-wrappable-dbus-services.patch"))))
     (build-system meson-build-system)
     (arguments
      (let ((disallowed-references
@@ -9405,7 +9407,14 @@ (define-public gnome-shell
                      (wrap-program (string-append #$output "/bin/" prog)
                        `("GUIX_PYTHONPATH"      ":" prefix (,python-path))
                        `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
-                   '("gnome-shell-perf-tool")))))
+                   '("gnome-shell-perf-tool"))
+                  ;; Make sure the dbus services can find typelibs
+                  (for-each
+                   (lambda (service)
+                     (wrap-program (string-append #$output "/share/gnome-shell/" service)
+                       `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
+                   '("org.gnome.ScreenSaver" "org.gnome.Shell.Extensions"
+                     "org.gnome.Shell.Notifications" "org.gnome.Shell.Screencast")))))
             (add-after 'install 'rewire
               (lambda* (#:key inputs #:allow-other-keys)
                 (for-each
diff --git a/gnu/packages/patches/gnome-shell-wrappable-dbus-services.patch b/gnu/packages/patches/gnome-shell-wrappable-dbus-services.patch
new file mode 100644
index 0000000000..67ed6beadb
--- /dev/null
+++ b/gnu/packages/patches/gnome-shell-wrappable-dbus-services.patch
@@ -0,0 +1,59 @@
+Retrieved from NixOS: https://github.com/NixOS/nixpkgs/blob/nixos-23.05/pkgs/desktops/gnome/core/gnome-shell/wrap-services.patch
+---
+diff --git a/js/dbusServices/dbus-service.in b/js/dbusServices/dbus-service.in
+old mode 100644
+new mode 100755
+index 524166102..6d0722a1c
+--- a/js/dbusServices/dbus-service.in
++++ b/js/dbusServices/dbus-service.in
+@@ -1,3 +1,9 @@
++#!@gjs@
++
++// 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@'
++
+ imports.package.start({
+     name: '@PACKAGE_NAME@',
+     prefix: '@prefix@',
+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@ @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(
