Created
July 28, 2026 17:52
-
-
Save 0187773933/acb1f5a3d5feff95179c2001e51332a1 to your computer and use it in GitHub Desktop.
Mac OSX Disable Bluetooth Notifications PopUp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import sys | |
| import os | |
| import plistlib | |
| import subprocess | |
| import time | |
| TARGET = "com.apple.BTUserNotifications" | |
| CALIB_TARGET = "com.apple.iCal" | |
| # --- DO NOT MODIFY THIS LINE MANUALLY --- | |
| # To force a recalibration, change the value back to None | |
| CALIBRATED_TOGGLE_BIT = None | |
| # ---------------------------------------- | |
| def get_ncprefs(): | |
| res = subprocess.run(["defaults", "export", "com.apple.ncprefs", "-"], | |
| capture_output=True, check=True) | |
| return plistlib.loads(res.stdout) | |
| def set_ncprefs(prefs): | |
| subprocess.run(["defaults", "import", "com.apple.ncprefs", "-"], | |
| input=plistlib.dumps(prefs), check=True) | |
| def get_flags(prefs, bundle_id): | |
| for app in prefs.get("apps", []): | |
| if app.get("bundle-id") == bundle_id: | |
| return app.get("flags") | |
| return None | |
| def calibrate_and_save(): | |
| print("=== Phase 1: Calibration (First Run Only) ===") | |
| print("To safely modify the hidden Bluetooth settings, we need to calibrate the bitmask.") | |
| print(f"1. Open System Settings > Notifications > Calendar ({CALIB_TARGET}).") | |
| print("2. Ensure 'Allow Notifications' is currently ON.") | |
| input("Press ENTER when ready...") | |
| prefs1 = get_ncprefs() | |
| flags1 = get_flags(prefs1, CALIB_TARGET) | |
| if flags1 is None: | |
| sys.exit(f"Error: Could not find {CALIB_TARGET} in ncprefs.") | |
| print("\n3. Now toggle 'Allow Notifications' OFF for Calendar.") | |
| input("Press ENTER when done...") | |
| time.sleep(1) # Ensure cfprefsd catches up | |
| prefs2 = get_ncprefs() | |
| flags2 = get_flags(prefs2, CALIB_TARGET) | |
| toggle_bit = flags1 ^ flags2 | |
| if toggle_bit == 0: | |
| sys.exit("Error: The flags did not change. The bit could not be calibrated.") | |
| print(f"\n[+] Calibrated successfully! Master toggle bit is: {toggle_bit}") | |
| # Self-modification logic | |
| script_path = os.path.abspath(__file__) | |
| try: | |
| with open(script_path, 'r') as f: | |
| content = f.read() | |
| old_line = "CALIBRATED_TOGGLE_BIT = None" | |
| new_line = f"CALIBRATED_TOGGLE_BIT = {toggle_bit}" | |
| if old_line in content: | |
| content = content.replace(old_line, new_line, 1) | |
| with open(script_path, 'w') as f: | |
| f.write(content) | |
| print("[+] Script has updated itself. It will not ask to calibrate again.") | |
| else: | |
| print("[-] Warning: Could not find the exact placeholder to self-update. You may need to edit it manually.") | |
| except Exception as e: | |
| print(f"[-] Warning: Failed to self-modify script: {e}") | |
| print("\n4. You can turn Calendar 'Allow Notifications' back ON now.") | |
| input("Press ENTER when done...") | |
| return toggle_bit | |
| def main(): | |
| if len(sys.argv) != 2 or sys.argv[1].upper() not in ["ON", "OFF"]: | |
| print("Usage: python3 toggle_bt_notifications.py [ON|OFF]") | |
| sys.exit(1) | |
| action = sys.argv[1].upper() | |
| # Determine toggle bit (either hardcoded from a previous run or by calibrating now) | |
| toggle_bit = CALIBRATED_TOGGLE_BIT | |
| if toggle_bit is None: | |
| toggle_bit = calibrate_and_save() | |
| else: | |
| print(f"Using pre-calibrated toggle bit: {toggle_bit}") | |
| print(f"\n=== Phase 2: Applying Bluetooth Notification {action} ===") | |
| prefs = get_ncprefs() | |
| target_app = None | |
| for app in prefs.get("apps", []): | |
| if app.get("bundle-id") == TARGET: | |
| target_app = app | |
| break | |
| if not target_app: | |
| sys.exit(f"Error: {TARGET} not found. Connect/disconnect a device so macOS generates the hidden profile first.") | |
| current_flags = target_app["flags"] | |
| if action == "OFF": | |
| new_flags = current_flags & ~toggle_bit | |
| else: | |
| new_flags = current_flags | toggle_bit | |
| if current_flags == new_flags: | |
| print(f"Bluetooth notifications are already {action}. Nothing to do.") | |
| else: | |
| print(f"Updating {TARGET} flags: {current_flags} -> {new_flags}") | |
| target_app["flags"] = new_flags | |
| set_ncprefs(prefs) | |
| print("Restarting notification services (usernoted & cfprefsd)...") | |
| subprocess.run(["killall", "usernoted"], capture_output=True) | |
| subprocess.run(["killall", "cfprefsd"], capture_output=True) | |
| print("Done! Changes applied.") | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment