From b3475ca5c6bbc22ed47fc5cdd4abdf962fcf8b29 Mon Sep 17 00:00:00 2001
From: windingwind <33902321+windingwind@users.noreply.github.com>
Date: Mon, 29 Jun 2026 18:26:06 +0200
Subject: [PATCH] Reveal settings and data dir for excluding from Spotlight
---
.../preferences/preferences_advanced.xhtml | 11 +++--
.../preferences/preferences_spotlight.js | 5 +++
chrome/content/zotero/xpcom/spotlight.js | 30 --------------
chrome/locale/en-US/zotero/preferences.ftl | 4 +-
defaults/preferences/zotero.js | 1 -
test/tests/spotlightTest.js | 40 -------------------
6 files changed, 12 insertions(+), 79 deletions(-)
diff --git a/chrome/content/zotero/preferences/preferences_advanced.xhtml b/chrome/content/zotero/preferences/preferences_advanced.xhtml
index 571d2b941b..d3a0615f4e 100644
--- a/chrome/content/zotero/preferences/preferences_advanced.xhtml
+++ b/chrome/content/zotero/preferences/preferences_advanced.xhtml
@@ -340,12 +340,11 @@
-
+
+
+
diff --git a/chrome/content/zotero/preferences/preferences_spotlight.js b/chrome/content/zotero/preferences/preferences_spotlight.js
index 10abae8eef..035dd4f6d5 100644
--- a/chrome/content/zotero/preferences/preferences_spotlight.js
+++ b/chrome/content/zotero/preferences/preferences_spotlight.js
@@ -131,6 +131,11 @@ Zotero_Preferences.Spotlight = {
}
},
+ excludeDataDir: function () {
+ Zotero.DataDirectory.reveal();
+ Zotero.launchURL('x-apple.systempreferences:com.apple.preference.spotlight');
+ },
+
_excludedLibraries: function () {
try {
let raw = Zotero.Prefs.get('spotlight.excludedLibraries');
diff --git a/chrome/content/zotero/xpcom/spotlight.js b/chrome/content/zotero/xpcom/spotlight.js
index ae1f4bd74e..f04279ace9 100644
--- a/chrome/content/zotero/xpcom/spotlight.js
+++ b/chrome/content/zotero/xpcom/spotlight.js
@@ -90,8 +90,6 @@ Zotero.Spotlight = new function () {
_registerPrefObservers();
_enabled = !!Zotero.Prefs.get(PREF + 'enabled');
- // Applied regardless of ownership
- _applyDataDirExclusion().catch(e => Zotero.logError(e));
if (!_enabled) {
return;
}
@@ -367,11 +365,6 @@ Zotero.Spotlight = new function () {
_prefObserverIDs.push(
Zotero.Prefs.registerObserver(PREF + 'enabled', _onEnabledChanged)
);
- // excludeDataDir has an immediate filesystem effect, so apply on change.
- _prefObserverIDs.push(
- Zotero.Prefs.registerObserver(PREF + 'excludeDataDir',
- () => _applyDataDirExclusion().catch(e => Zotero.logError(e)))
- );
}
function _unregisterPrefObservers() {
@@ -406,29 +399,6 @@ Zotero.Spotlight = new function () {
_isOwner = false;
}
}
- await _applyDataDirExclusion();
- }
-
- // `.metadata_never_index` file excludes the data dir from Spotlight indexing.
- async function _applyDataDirExclusion() {
- if (!_dataDir) {
- return;
- }
- let file = PathUtils.join(_dataDir, '.metadata_never_index');
- let shouldExclude = _available && _enabled
- && !!Zotero.Prefs.get(PREF + 'excludeDataDir');
- try {
- let exists = await IOUtils.exists(file);
- if (shouldExclude && !exists) {
- await IOUtils.writeUTF8(file, '');
- }
- else if (!shouldExclude && exists) {
- await IOUtils.remove(file);
- }
- }
- catch (e) {
- Zotero.logError(e);
- }
}
this.getForeignOwner = async function () {
diff --git a/chrome/locale/en-US/zotero/preferences.ftl b/chrome/locale/en-US/zotero/preferences.ftl
index 7418900716..f04b91e485 100644
--- a/chrome/locale/en-US/zotero/preferences.ftl
+++ b/chrome/locale/en-US/zotero/preferences.ftl
@@ -111,9 +111,9 @@ preferences-spotlight-take-ownership =
.label = Use This Profile Instead
preferences-spotlight-libraries-title = Indexed Libraries
preferences-spotlight-privacy-title = Avoiding Duplicate Indexing
-preferences-spotlight-privacy-description = macOS may also index the attachment files in your { -app-name } data directory, showing them in Spotlight alongside your library items. Excluding the data directory keeps Spotlight showing only your { -app-name } items.
+preferences-spotlight-privacy-description = macOS may also index the attachment files in your { -app-name } data directory, showing them in Spotlight alongside your library items. To prevent this, add the data directory to the list under Spotlight’s Privacy settings.
preferences-spotlight-exclude-data-dir =
- .label = Exclude data directory from Spotlight
+ .label = Reveal Data Directory and Open Spotlight Settings…
preferences-spotlight-format-title = Display Format
preferences-spotlight-format-description = Customize how items appear in Spotlight. See the for the full list.
preferences-spotlight-title-template =
diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js
index a9503a0239..9fdf0aacb2 100644
--- a/defaults/preferences/zotero.js
+++ b/defaults/preferences/zotero.js
@@ -166,7 +166,6 @@ pref("extensions.zotero.httpServer.localAPI.enabled", false);
pref("extensions.zotero.spotlight.enabled", true);
pref("extensions.zotero.spotlight.openOnConfirm", true); // true = open the item's attachment, false = show in library
pref("extensions.zotero.spotlight.indexFullText", true);
-pref("extensions.zotero.spotlight.excludeDataDir", true);
pref("extensions.zotero.spotlight.titleTemplate", "{{ title }}");
pref("extensions.zotero.spotlight.descriptionTemplate", "{{ firstCreator }}{{ year prefix=\" (\" suffix=\")\" }}");
pref("extensions.zotero.spotlight.excludedLibraries", "[]"); // JSON array of libraryIDs to skip
diff --git a/test/tests/spotlightTest.js b/test/tests/spotlightTest.js
index 1e271d69b3..87b2dc08ff 100644
--- a/test/tests/spotlightTest.js
+++ b/test/tests/spotlightTest.js
@@ -9,7 +9,6 @@ describe("Zotero.Spotlight", function () {
'spotlight.enabled',
'spotlight.openOnConfirm',
'spotlight.indexFullText',
- 'spotlight.excludeDataDir',
'spotlight.titleTemplate',
'spotlight.descriptionTemplate',
'spotlight.excludedLibraries',
@@ -24,10 +23,6 @@ describe("Zotero.Spotlight", function () {
);
}
- function neverIndexPath() {
- return PathUtils.join(Zotero.DataDirectory.dir, '.metadata_never_index');
- }
-
// Unique lowercase-alnum token so a Core Spotlight wildcard query can find a
// specific item without colliding with anything else in the index.
function token() {
@@ -51,17 +46,6 @@ describe("Zotero.Spotlight", function () {
return results;
}
- async function waitForFileState(path, shouldExist, timeout = 5000) {
- let start = Date.now();
- while (Date.now() - start < timeout) {
- if ((await IOUtils.exists(path)) === shouldExist) {
- return true;
- }
- await Zotero.Promise.delay(100);
- }
- return false;
- }
-
before(async function () {
if (!Zotero.isMac || !Zotero.Spotlight || !Zotero.Spotlight.available) {
Zotero.debug("Spotlight: bridge unavailable; skipping Spotlight tests");
@@ -324,30 +308,6 @@ describe("Zotero.Spotlight", function () {
});
});
- describe("data directory exclusion", function () {
- before(function () {
- // The exclusion only applies while the feature is enabled.
- Zotero.Prefs.set('spotlight.enabled', true);
- });
-
- it("should write .metadata_never_index when the exclusion is on", async function () {
- Zotero.Prefs.set('spotlight.excludeDataDir', false);
- assert.isTrue(await waitForFileState(neverIndexPath(), false));
- Zotero.Prefs.set('spotlight.excludeDataDir', true);
- assert.isTrue(await waitForFileState(neverIndexPath(), true),
- ".metadata_never_index should be created");
- });
-
- it("should remove .metadata_never_index when the exclusion is off", async function () {
- Zotero.Prefs.set('spotlight.excludeDataDir', true);
- assert.isTrue(await waitForFileState(neverIndexPath(), true));
- Zotero.Prefs.set('spotlight.excludeDataDir', false);
- assert.isTrue(await waitForFileState(neverIndexPath(), false),
- ".metadata_never_index should be removed");
- Zotero.Prefs.set('spotlight.excludeDataDir', true);
- });
- });
-
describe("indexing round-trip", function () {
before(async function () {
if (!Zotero.Spotlight.indexingAvailable()) {