diff --git a/app-misc/localsearch/Manifest b/app-misc/localsearch/Manifest
index 1ca58135d4b41..16c13985e2e72 100644
--- a/app-misc/localsearch/Manifest
+++ b/app-misc/localsearch/Manifest
@@ -1,2 +1,3 @@
DIST localsearch-3.8.2.tar.xz 4547012 BLAKE2B 5d5636aaf7213d1d9e73e00c259b5f59e8efb4065d9acb4730d78c1dd5bf4cd460d36a8be09d01c294618eea0b8537f892c46c14699e8fc3c759c9c208500317 SHA512 d037b81467987e31294dfc2ea540db5581e5bbcd1688578d8a338352c3f0841270d78eb54fd8ec1aaa4807e7d15cc787c6ed414b295c9e0c93d286be1a87c661
+DIST localsearch-3.9.0.tar.xz 4527924 BLAKE2B 8c895fa3b59c6a368a2437833d4a463092629bbf43d18b44d109bbce89fcb7d64409d709cc9c64d5b202ece27d876cb711df3058fc77a3c37ee695554d19bdc3 SHA512 693be7a6070ef30e5382e85af346356ee7f07f97d284a6b3cb59c6c4b86d6d2caf5e979f2c9c2a71a332c475d65615d4917b6f148b693c11d26c03f5d81ae3df
DIST tracker-miners-3.6.2.tar.xz 7506528 BLAKE2B d0da1caaa72467ec03c7e3c35cbee48aca08dca59d45d11e5f5f887d75954dbac0671d5698226c9cb89e97b3a76b318013ca17f8508ec3f867758662f53b25b7 SHA512 032c96d41e02ed15b56937ea543428aef7b45ce4c206b749e6a99506dd48dd760e45b12563846a3208f0da42387d0547de9eef1fcb54d93cdbca4aad52050af4
diff --git a/app-misc/localsearch/localsearch-3.9.0.ebuild b/app-misc/localsearch/localsearch-3.9.0.ebuild
new file mode 100644
index 0000000000000..be8a6dfa7cf51
--- /dev/null
+++ b/app-misc/localsearch/localsearch-3.9.0.ebuild
@@ -0,0 +1,165 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+PYTHON_COMPAT=( python3_{11..14} )
+
+inherit flag-o-matic gnome.org gnome2-utils meson python-any-r1 systemd xdg
+
+DESCRIPTION="Indexer and search engine that powers desktop search for core GNOME components"
+HOMEPAGE="https://gnome.pages.gitlab.gnome.org/localsearch"
+
+LICENSE="GPL-2+ LGPL-2.1+"
+SLOT="3"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~loong ~ppc ~ppc64 ~riscv ~sparc ~x86"
+IUSE="cue exif gif gsf +gstreamer iptc +iso +jpeg landlock +pdf +playlist raw seccomp test +tiff upower +xml xmp xps"
+
+REQUIRED_USE="cue? ( gstreamer )" # cue is currently only supported via gstreamer, not ffmpeg
+RESTRICT="!test? ( test )"
+
+# tracker-2.1.7 currently always depends on ICU (theoretically could be libunistring instead);
+# so choose ICU over enca always here for the time being (ICU is preferred)
+RDEPEND="
+ >=app-misc/tinysparql-3.8:3
+ >=sys-apps/dbus-1.3.1
+ xmp? ( >=media-libs/exempi-2.1.0:= )
+ raw? ( media-libs/gexiv2 )
+ >=dev-libs/glib-2.70:2
+ dev-libs/libgudev
+ dev-libs/gobject-introspection
+ cue? ( media-libs/libcue:= )
+ exif? ( >=media-libs/libexif-0.6 )
+ gsf? ( >=gnome-extra/libgsf-1.14.24:= )
+ xps? ( app-text/libgxps )
+ iptc? ( media-libs/libiptcdata )
+ jpeg? ( media-libs/libjpeg-turbo:0= )
+ iso? ( >=sys-libs/libosinfo-1.10.0-r1 )
+ >=media-libs/libpng-1.2:0=
+ seccomp? ( >=sys-libs/libseccomp-2.0 )
+ tiff? ( media-libs/tiff:= )
+ xml? ( >=dev-libs/libxml2-2.6:= )
+ pdf? ( >=app-text/poppler-0.16.0:=[cairo] )
+ playlist? ( >=dev-libs/totem-pl-parser-3:= )
+
+ gif? ( media-libs/giflib:= )
+
+ app-arch/gzip
+
+ upower? ( >=sys-power/upower-0.9.0:= )
+
+ >=dev-libs/icu-4.8.1.1:=
+
+ gstreamer? (
+ >=media-libs/gstreamer-1.20:1.0
+ >=media-libs/gst-plugins-base-1.20:1.0
+ >=media-plugins/gst-plugins-meta-1.20:1.0 )
+ media-video/ffmpeg:0=
+"
+DEPEND="${RDEPEND}"
+BDEPEND="
+ app-text/asciidoc
+ dev-libs/libxslt
+ dev-util/glib-utils
+ dev-util/gdbus-codegen
+
+ >=sys-devel/gettext-0.19.8
+ virtual/pkgconfig
+ test? (
+ ${PYTHON_DEPS}
+ $(python_gen_any_dep 'dev-python/pygobject[${PYTHON_USEDEP}]')
+ $(python_gen_any_dep 'dev-python/tap-py[${PYTHON_USEDEP}]')
+ gstreamer? (
+ media-libs/gstreamer:1.0[introspection]
+ || (
+ media-plugins/gst-plugins-libav:1.0
+ media-plugins/gst-plugins-openh264:1.0
+ )
+ )
+ )
+"
+
+python_check_deps() {
+ python_has_version -b \
+ "dev-python/pygobject[${PYTHON_USEDEP}]" \
+ "dev-python/tap-py[${PYTHON_USEDEP}]"
+}
+
+pkg_setup() {
+ use test && python-any-r1_pkg_setup
+}
+
+src_prepare() {
+ default
+
+ # Avoid gst-inspect calls that may trigger sandbox;
+ # instead assume the detection will succeed and add the needed test deps for that
+ if use gstreamer; then
+ sed -i -e 's:detect-h264-codec.sh:/bin/true:' tests/functional-tests/meson.build || die
+ else
+ sed -i -e 's:detect-h264-codec.sh:/bin/false:' tests/functional-tests/meson.build || die
+ fi
+ gnome2_environment_reset # sets gstreamer safety variables
+}
+
+src_configure() {
+ # bug #944218
+ append-cflags -std=gnu17
+
+ append-cflags -DTRACKER_DEBUG -DG_DISABLE_CAST_CHECKS
+
+ local emesonargs=(
+ -Dman=true
+ -Dextract=true
+ $(meson_use test functional_tests)
+ $(meson_use test tests_tap_protocol)
+ -Dminer_fs=true
+ -Dwriteback=true
+ -Dabiword=true
+ -Dicon=true
+ -Dmp3=true
+ -Dps=true
+ -Dtext=true
+ -Dunzip_ps_gz_files=true # spawns gunzip
+ # Broken with our library layout for libstdc++ (bug #957705)
+ $(meson_feature landlock)
+ $(meson_feature cue)
+ $(meson_feature exif)
+ $(meson_feature gif)
+ $(meson_feature gsf)
+ $(meson_feature iptc)
+ $(meson_feature iso)
+ $(meson_feature jpeg)
+ $(meson_feature pdf)
+ $(meson_feature playlist)
+ -Dpng=enabled
+ $(meson_feature raw)
+ $(meson_feature tiff)
+ $(meson_feature xml)
+ $(meson_feature xmp)
+ $(meson_feature xps)
+
+ -Dbattery_detection=$(usex upower upower none)
+ # enca is a possibility, but right now we have tracker core always dep on icu and icu is preferred over enca
+ -Dcharset_detection=icu
+ # gupnp gstreamer_backend is in bad state, upstream suggests to use discoverer, which is the default
+ -Dsystemd_user_services_dir="$(systemd_get_userunitdir)"
+ )
+ meson_src_configure
+}
+
+src_test() {
+ export GSETTINGS_BACKEND="dconf" # Tests require dconf and explicitly check for it (env_reset set it to "memory")
+ export PYTHONPATH="${ESYSROOT}"/usr/$(get_libdir)/tinysparql-3.0
+ # Many (extractor) tests fail since version 3.9.0 https://gitlab.gnome.org/GNOME/localsearch/-/issues/405
+ dbus-run-session meson test -C "${BUILD_DIR}" --no-suite examples || die 'tests failed'
+}
+
+pkg_postinst() {
+ xdg_pkg_postinst
+ gnome2_schemas_update
+}
+
+pkg_postrm() {
+ xdg_pkg_postrm
+ gnome2_schemas_update
+}
diff --git a/app-misc/localsearch/metadata.xml b/app-misc/localsearch/metadata.xml
index 7fb3ba2f3ef74..55f90cd7f248c 100644
--- a/app-misc/localsearch/metadata.xml
+++ b/app-misc/localsearch/metadata.xml
@@ -11,6 +11,8 @@
for ODT.
Enable extraction of IPTC data from pictures
Enable extraction of metadata from ISO disk images
+ Enable support for metadata writeback functionality
+ Enable sandboxing using Landlock LSM
Add support for playlists
Add support for XPS file format through app-text/libgxps.
diff --git a/profiles/targets/desktop/gnome/package.use.force b/profiles/targets/desktop/gnome/package.use.force
new file mode 100644
index 0000000000000..b7a87347d0ea9
--- /dev/null
+++ b/profiles/targets/desktop/gnome/package.use.force
@@ -0,0 +1 @@
+app-misc/localsearch landlock