From 51e0272f405da6874a75233e8343f59f9138fe26 Mon Sep 17 00:00:00 2001 From: shoal-rat <95214059+shoal-rat@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:32:17 +0800 Subject: [PATCH 1/2] PermissionChecker: stop probing Mail/Messages/Safari for the FDA check Reading ~/Library/Mail, ~/Library/Messages and ~/Library/Safari fires the macOS 15 TCC "App Data" consent ("RClick" would like to access data from other apps) on every app launch. Probe the user TCC store instead: it is gated by Full Disk Access itself (kTCCServiceSystemPolicyAllFiles), which macOS denies silently, so the check stays accurate without ever prompting. Also drop the POSIX access() fast path: the probe directory is owned by the current user, so access(R_OK) succeeds on POSIX permissions alone and would report FDA as granted when it is not. Co-Authored-By: Claude Fable 5 --- RClick/Shared/PermissionChecker.swift | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/RClick/Shared/PermissionChecker.swift b/RClick/Shared/PermissionChecker.swift index 036ee9e..bb6a6e8 100644 --- a/RClick/Shared/PermissionChecker.swift +++ b/RClick/Shared/PermissionChecker.swift @@ -25,12 +25,16 @@ public class PermissionChecker { /// 需要 FDA 才能访问的检测路径 /// 每个路径下的文件/子目录只有开启了 FDA 才能被读取 + /// + /// Deliberately NOT ~/Library/Mail, Messages or Safari: those are other + /// apps' data containers, and on macOS 15+ merely attempting to read them + /// fires the TCC "App Data" consent ("RClick" would like to access data + /// from other apps) every time the app launches. The TCC store below is + /// gated by Full Disk Access itself (kTCCServiceSystemPolicyAllFiles), + /// which macOS denies *silently* — an accurate FDA probe with no prompt. private static let protectedTestPaths: [(path: String, description: String)] = [ - ("/Library/Application Support", "System Application Support"), - ("/Library/Logs", "System Logs"), - (NSString(string: "~/Library/Mail").expandingTildeInPath, "User Mail"), - (NSString(string: "~/Library/Messages").expandingTildeInPath, "User Messages"), - (NSString(string: "~/Library/Safari").expandingTildeInPath, "User Safari"), + (NSString(string: "~/Library/Application Support/com.apple.TCC").expandingTildeInPath, + "User TCC store"), ] /// 检测是否拥有完全磁盘访问权限 @@ -57,13 +61,10 @@ public class PermissionChecker { return false } - // 使用 POSIX access() 检测实际文件系统权限 - let result = url.path.withCString { access($0, R_OK) } - if result == 0 { - return true - } - - // access() 失败时,回退到 FileManager 方式(有些情况下 access 也会返回错误) + // No POSIX access() fast path here: the probe directory is owned by + // the current user, so access(R_OK) succeeds on POSIX permissions + // alone and would report FDA as granted when it is not. TCC is only + // enforced on the actual read attempt below. do { // 不用 .skipsHiddenFiles,避免空目录误判 let _ = try FileManager.default.contentsOfDirectory( From c595609c47842b212ff67793c12c5c2ecdccbcab Mon Sep 17 00:00:00 2001 From: shoal-rat <95214059+shoal-rat@users.noreply.github.com> Date: Mon, 6 Jul 2026 18:32:17 +0800 Subject: [PATCH 2/2] FinderSyncExt: observe / so the menu appears in every folder The observed set (/Users/ plus external volumes) left everything else on the system volume - /Applications, /opt, /tmp, ... - without the RClick context menu, although the method comment says whole-disk observation. Observing the root covers all of it, including external and network volumes mounted under /Volumes. FileProvider-backed locations (iCloud Drive, synced Desktop & Documents) remain excluded by macOS itself. Co-Authored-By: Claude Fable 5 --- FinderSyncExt/FinderSyncExt.swift | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/FinderSyncExt/FinderSyncExt.swift b/FinderSyncExt/FinderSyncExt.swift index da4e327..64c610f 100644 --- a/FinderSyncExt/FinderSyncExt.swift +++ b/FinderSyncExt/FinderSyncExt.swift @@ -71,25 +71,17 @@ class FinderSyncExt: FIFinderSync, @unchecked Sendable { // MARK: - Directory Observing - /// 设置监听目录 + /// 设置监听目录(全盘监听) + /// + /// Observing "/" covers every reachable folder — /Users, /Applications, + /// /opt, /tmp, external and network volumes (mounted under /Volumes) — + /// which is what the original per-path list intended but missed for + /// anything on the system volume outside /Users. FileProvider-backed + /// locations (iCloud Drive, synced Desktop & Documents) still get no + /// FinderSync menus; that is a macOS restriction on all FinderSync + /// extensions, not something an observation URL can change. private func setupObservingDirectories() { - var directories: Set = [] - - // 添加 /Users/ 目录 - if let usersDir = URL(string: "file:///Users/") { - directories.insert(usersDir) - } - - // 添加外接磁盘目录 - let volumns = FileManager.default.mountedVolumeURLs( - includingResourceValuesForKeys: nil, - options: .skipHiddenVolumes - ) ?? [] - - for volume in volumns.dropFirst() { // dropFirst 跳过系统盘 - directories.insert(volume) - } - + let directories: Set = [URL(fileURLWithPath: "/")] FIFinderSyncController.default().directoryURLs = directories logger.info("Observing directories: \(directories.map { $0.path })") }