Adopt upstream PRs #1718 (non-notch clock) and #1668 (Bluetooth accessory banner)

NO
8d ago
+602-1

Summary

Adopts two upstream Boring Notch PRs by cherry-pick (-x, original authors kept), plus notes and string-catalog entries.

  • TheBoredTeam/boring.notch#1718 (Driton): optional clock in the closed notch on displays without a notch. Off by default, under Settings > Appearance > Idle state. Applied cleanly.
  • TheBoredTeam/boring.notch#1668 (ludovickjankowski-web): Bluetooth accessory connect/disconnect banner with battery level (AirPods L/R, HID fallback for Magic accessories). Opt-in under Settings > Battery > Accessories. Adds the com.apple.security.device.bluetooth entitlement and NSBluetoothAlwaysUsageDescription. Conflicts (project.pbxproj, ContentView.swift) resolved against our main.
  • English Localizable.xcstrings entries for the new strings.
  • docs/bluetooth-alert-notes.md: comparison of #1668 with DynamicNotch and MewNotch (MewNotch has no Bluetooth feature), gaps in #1668, and a recommendation for generalizing the alert pipeline later for Wi-Fi/VPN/Raycast.
  • scripts/dev.sh cherry-picked from main (was missing from the branch before the merge).

Merged origin/main (CI cleanup, Sparkle disabled, Quit menu) with no conflicts. scripts/dev.sh build succeeds.

Needs rebasing onto compact-only

This PR will need rework once the compact-only PR (#1) merges, because that PR rewrites ContentView.swift into a panel layout. The ContentView hook points to re-apply:

  1. @Default(.showClockWithoutNotch) property.
  2. Closed idle !vm.hasNotch branch: NotchClockView in place of the empty Rectangle when closed and the notch height is non-zero.
  3. Overlay of NotchClockView on the music activity centre when !vm.hasNotch.
  4. case bluetoothStatus in the state enum and its selection after the battery check.
  5. showBluetoothActivity computed property.
  6. chinWidth = 640 branch for showBluetoothActivity.
  7. else if showBluetoothActivity { BluetoothAccessoryView() } right after the PowerStatusNotice branch.

Not verified at runtime

The app was never launched. Bluetooth hardware behaviour (connect/disconnect callbacks, replay for already-connected devices, AirPods per-bud battery, the HID fallback under the sandbox), the non-notch layout, hover and fullscreen are all untested. See docs/bluetooth-alert-notes.md for the gaps in #1668.

How to test

cd /Users/knewton/.t3/worktrees/not.boring.notch/feat-upstream-prs-bt-clock && scripts/dev.sh

Quit the installed Boring Notch first (it shares the bundle ID). macOS may re-ask for permissions after each rebuild. Bluetooth permission is required for the accessory banner.

  • Clock: Settings > Appearance > Idle state > "Show clock on displays without a notch". On a non-notch display or external monitor the closed notch should show the time (and date if enabled), stay up while music plays, and be covered by notifications.
  • Bluetooth: Settings > Battery > Accessories > enable, allow the prompt. Connect/disconnect AirPods: a ~3 s banner with the name and battery %, then a grey "Disconnected" banner.

🤖 Generated with Claude Code


Summary by cubic

Adopts upstream PRs #1718 (optional clock when the display has no notch) and #1668 (Bluetooth accessory connect/disconnect banner with battery level).

  • #1718: Adds a clock to the closed notch on displays without a physical notch, off by default under Settings > Appearance > Idle state. Stays visible while music plays and is covered by notifications.
  • #1668: Shows a banner when Bluetooth accessories (AirPods, headphones, keyboards, mice) connect or disconnect, with battery level when available. Opt-in under Settings > Battery > Accessories and adds the Bluetooth entitlement plus usage description.
  • Adds English string-catalog entries, a comparison doc for #1668 against DynamicNotch and MewNotch, and a scripts/dev.sh build helper.

Note

  • Not runtime-verified: Bluetooth callbacks, battery fallback, and layout were never tested on hardware.
  • Will need rework once the compact-only PR merges, since that PR rewrites ContentView.swift; the diff lists the hook points to re-apply.