Skip to content

statusbar: show peripheral presence with a filled icon background - #105

Merged
MegaManSec merged 6 commits into
mainfrom
statusbar-presence-rework
Aug 10, 2026
Merged

statusbar: show peripheral presence with a filled icon background#105
MegaManSec merged 6 commits into
mainfrom
statusbar-presence-rework

Conversation

@MegaManSec

Copy link
Copy Markdown
Owner

Includes #104 (@hotsnow's connection indicator) plus a rework of the idle-state visuals:

  • Connected state renders the glyph knocked out of a filled rounded square (Control Center "engaged" look) instead of dimming via appearsDisabled/contentTintColor, which read as "app disabled" and broke the menu-open highlight tint.
  • Tri-state presence: plain icon and tooltip when no peripherals are registered or Bluetooth state is still unknown at launch.
  • Tooltips: "peripherals connected to this Mac" / "no peripherals connected to this Mac".
  • Icon refresh has its own merged $peripherals/$connectionStates subscription.
  • Reverts the #Preview guards (previews would compile out under Xcode too) and the .gitignore change.

Same head as #104 after the update push — merging either closes both.

@MegaManSec

Copy link
Copy Markdown
Owner Author

Archival copy of hotsnow/magic-switch#1 (the interim PR against the fork's feat/statusbar-active-indicator branch, auto-marked merged when its commits were pushed there — copied here in case the fork is ever deleted):

Rework connected indicator: filled background instead of dimming (opened 2026-08-09)

Builds on #104 (thanks!) with a few adjustments:

  • Show the connected state by knocking the glyph out of a filled rounded square (composited in code from the existing asset); disconnected keeps the normal icon. Dimming via appearsDisabled made the idle icon read as "app disabled" on whichever Mac doesn't currently hold the peripherals.
  • Tri-state presence: no registered peripherals (or Bluetooth state still unknown at launch) shows the plain icon and plain tooltip instead of "Disconnected".
  • Tooltips spell out the state: "peripherals connected to this Mac" / "no peripherals connected to this Mac".
  • Icon refresh gets its own merged $peripherals/$connectionStates subscription; the transfer-settle observer is back to single-purpose.
  • Reverts the #if canImport(PreviewsMacros) guards — that condition is false under Xcode's toolchain too, so previews would compile out entirely. (It looks like a workaround for building with Command Line Tools swiftc, which lacks the previews macro plugin; Xcode builds work with plain #Preview.) Also reverts the .gitignore change.

@MegaManSec
MegaManSec merged commit 42b2e9a into main Aug 10, 2026
2 checks passed
@MegaManSec
MegaManSec deleted the statusbar-presence-rework branch August 10, 2026 10:07
MegaManSec added a commit to hotsnow/magic-switch that referenced this pull request Aug 10, 2026
Review fixes for the connected-state indicator that merged in MegaManSec#105:

- peripheralPresence now counts .releasing as still-here (the device
  stays physically connected through the up-to-5s send preflight,
  during which the icon previously un-filled and the tooltip claimed
  nothing was connected), and treats a registered peripheral with no
  connectionStates entry as unknown rather than away, so a cold launch
  can't misreport a connected keyboard before the first IOBluetooth
  snapshot lands.
- Re-fetch connection states when CoreBluetooth reaches .poweredOn:
  the init-time snapshot bails while the radio reads off (login-item
  launch), and already-connected peripherals fire no new connect
  event, which left a false "away" standing for minutes.
- The icon observer derives presence via combineLatest +
  removeDuplicates instead of a Void merge, so routine no-op publishes
  (reconnect probes, peer syncs) no longer force a status-item redraw.
- The 3s ping bell flash survives idle refreshes; only a transfer
  arrow or needs-attention state cuts it short, restoring the original
  intent now that connection churn triggers refreshes.
- Both status-bar icons composite from copies of the named image; the
  shared NSImage(named:) cache instance is never mutated.
- refreshStatusBarIcon computes the tooltip once and reuses it for
  toolTip and the accessibility label.
MegaManSec added a commit that referenced this pull request Aug 10, 2026
)

Review fixes for the connected-state indicator that merged in #105:

- peripheralPresence now counts .releasing as still-here (the device
  stays physically connected through the up-to-5s send preflight,
  during which the icon previously un-filled and the tooltip claimed
  nothing was connected), and treats a registered peripheral with no
  connectionStates entry as unknown rather than away, so a cold launch
  can't misreport a connected keyboard before the first IOBluetooth
  snapshot lands.
- Re-fetch connection states when CoreBluetooth reaches .poweredOn:
  the init-time snapshot bails while the radio reads off (login-item
  launch), and already-connected peripherals fire no new connect
  event, which left a false "away" standing for minutes.
- The icon observer derives presence via combineLatest +
  removeDuplicates instead of a Void merge, so routine no-op publishes
  (reconnect probes, peer syncs) no longer force a status-item redraw.
- The 3s ping bell flash survives idle refreshes; only a transfer
  arrow or needs-attention state cuts it short, restoring the original
  intent now that connection churn triggers refreshes.
- Both status-bar icons composite from copies of the named image; the
  shared NSImage(named:) cache instance is never mutated.
- refreshStatusBarIcon computes the tooltip once and reuses it for
  toolTip and the accessibility label.

Co-authored-by: Joshua Rogers <MegaManSec@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.25.5 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant