From b5ceb033f5fa5f083ce9f33e010c023d12353875 Mon Sep 17 00:00:00 2001 From: AkiyamaKunka Date: Sun, 18 Oct 2026 12:34:50 -0500 Subject: [PATCH] Give Debug builds their own bundle identifier A build from Xcode and the installed Developer ID release both used com.knollsoft.Rectangle, so they shared one Accessibility grant and one preferences domain: whichever copy macOS had trusted first kept the grant, and the other showed the row enabled while still asking for permission. The Debug configuration now uses com.knollsoft.Rectangle.debug. Release (and therefore archives, CI and Sparkle updates) is unchanged. - ApplicationToggle.frontAppId starts from Bundle.main.bundleIdentifier instead of the release id literal. - The exported config keeps the canonical com.knollsoft.Rectangle. - Remove AppDelegate.launcherAppId, unused since the launcher was dropped. - README: note the Debug identifier for defaults/tccutil. - Tests pin both identifiers. Because the test target is hosted in the Debug app, the suite's UserDefaults writes now go to the .debug domain instead of the installed app's preferences. Fixes #1920. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 ++ Rectangle.xcodeproj/project.pbxproj | 2 +- Rectangle/AppDelegate.swift | 2 -- Rectangle/ApplicationToggle.swift | 2 +- RectangleTests/RectangleTests.swift | 15 +++++++++++++++ 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dfa7bfec..e0630280 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,8 @@ Rectangle uses [Swift Package Manager](https://www.swift.org/package-manager/) t The original repository for MASShortcut was archived, so Rectangle uses my [fork](https://github.com/rxhanson/MASShortcut). If you want to make any changes that involve MASShortcut, please make a pull request on my fork. +Debug builds use the bundle identifier `com.knollsoft.Rectangle.debug`, so a build from Xcode gets its own Accessibility permission and preferences instead of sharing the installed copy's. Quit the installed Rectangle while running a Debug build, since both respond to the same shortcuts and window drags. Use the `.debug` identifier with `defaults` and `tccutil`. For example, an ad-hoc signed build needs its permission granted again after rebuilding, and `tccutil reset Accessibility com.knollsoft.Rectangle.debug` clears the stale entry. + Due to the addition of the Liquid Glass icon with a fallback for older versions of macOS, there will be a build failure on macOS versions < 26. You can delete the "Asset Catalog Other Flags" to build locally on versions < 26 (but don't check that change in if you create a pull request). ## Credits diff --git a/Rectangle.xcodeproj/project.pbxproj b/Rectangle.xcodeproj/project.pbxproj index 8a5f78a6..c4584d6a 100644 --- a/Rectangle.xcodeproj/project.pbxproj +++ b/Rectangle.xcodeproj/project.pbxproj @@ -1462,7 +1462,7 @@ ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; MARKETING_VERSION = 2.0.3; - PRODUCT_BUNDLE_IDENTIFIER = com.knollsoft.Rectangle; + PRODUCT_BUNDLE_IDENTIFIER = com.knollsoft.Rectangle.debug; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_EMIT_LOC_STRINGS = YES; diff --git a/Rectangle/AppDelegate.swift b/Rectangle/AppDelegate.swift index 126f3082..b4a5b1bd 100644 --- a/Rectangle/AppDelegate.swift +++ b/Rectangle/AppDelegate.swift @@ -7,8 +7,6 @@ import os.log @main class AppDelegate: NSObject, NSApplicationDelegate { - static let launcherAppId = "com.knollsoft.RectangleLauncher" - private let accessibilityAuthorization = AccessibilityAuthorization() private let statusItem = RectangleStatusItem.instance static let windowHistory = WindowHistory() diff --git a/Rectangle/ApplicationToggle.swift b/Rectangle/ApplicationToggle.swift index 26b2b197..e38cac5e 100644 --- a/Rectangle/ApplicationToggle.swift +++ b/Rectangle/ApplicationToggle.swift @@ -5,7 +5,7 @@ import Cocoa class ApplicationToggle: NSObject { private var disabledApps = Set() - public private(set) static var frontAppId: String? = "com.knollsoft.Rectangle" + public private(set) static var frontAppId: String? = Bundle.main.bundleIdentifier public private(set) static var frontAppName: String? = "Rectangle" public private(set) static var shortcutsDisabled: Bool = false diff --git a/RectangleTests/RectangleTests.swift b/RectangleTests/RectangleTests.swift index 98b52fae..c09c7712 100644 --- a/RectangleTests/RectangleTests.swift +++ b/RectangleTests/RectangleTests.swift @@ -1968,6 +1968,21 @@ class DefaultsExportTests: XCTestCase { } } +final class BundleIdentityTests: XCTestCase { + + func testDebugBuildsUseTheirOwnBundleIdentifier() { + // Keeps a build from Xcode from sharing the installed app's + // Accessibility permission and preferences. + XCTAssertEqual(Bundle.main.bundleIdentifier, "com.knollsoft.Rectangle.debug") + } + + func testExportedConfigKeepsTheReleaseBundleIdentifier() throws { + let json = try XCTUnwrap(Defaults.encoded()) + let config = try XCTUnwrap(Defaults.convert(jsonString: json)) + XCTAssertEqual(config.bundleId, "com.knollsoft.Rectangle") + } +} + class ConfigImportTests: XCTestCase { private static let shortcutKeys = WindowAction.active.map(\.name) + TodoManager.defaultsKeys + StackBadgeManager.defaultsKeys