2.1.0-beta.1
Pre-release
Pre-release
Hey, we have a Discord! Come say hi: discord.gg/KDfWjWDnR4.
First beta of the 2.1.0 line. This is the wave the 2.0.0 notes pointed at: triggers, groups, zen mode, Simple Mode, spacers, and a Thaw Bar that dresses itself. Anything that changes behavior ships switched off; flip it on when you want it.
Upgrade from 2.0.1
- Pick the beta channel in Settings → Updates. Stable stays on 2.0.1 until 2.1.0 leaves beta.
- No schema or
defaultschanges. Profiles, saved layouts, and hotkeys carry over untouched. - Trigger conditions are gated per feature under Settings → Developer. Battery and power work out of the box; everything else is a switch you flip deliberately.
Added
- Item triggers move a menu bar item when something happens: battery level, power source, frontmost or running app, network, VPN, Wi-Fi, Bluetooth, audio device, displays, a time window, a Focus, a place, Energy Mode, thermal pressure, camera or mic use, a script's exit, or another icon changing. Conditions combine with all/any/none, actions invert, and a wrong verdict costs a brief reveal instead of a rearranged bar. Designed and implemented by @alvst (#735, #965).
- Item groups bundle items so they move as one, including across sections, matching the macOS 27 semantics. Same-bundle clusters group automatically and dissolve on request.
- Zen mode seals the whole bar with one hotkey. Auto-reveals and hover tricks stand down, and a blinking icon does not get to reopen what you closed. Toggle it again to hand the bar back.
- Simple Mode collapses Settings to one page, ordered by what you actually touch. Everything it hides is still there when you switch it off.
- Tools pane gathers the destructive troubleshooting helpers in one place, plus announcements and Sparkle feed pinning.
- Spacer items create gaps on purpose: pick a width and an optional fill, then drag them like any item.
- Per-Space profiles bind a profile to a Space the way it already binds to a display. Bindings use the window server's per-Space
uuid, since the ID is renumbered at logout. Precedence is Focus Filter, then Space, then display. - Wallpaper changes re-tint the bar immediately. Thaw now watches the wallpaper store instead of polling for it. The poll stays for dynamic wallpapers, which change their pixels without ever rewriting that file.
- Adaptive Gradient tint builds the gradient from the wallpaper's dominant colours instead of one averaged brown. Colours are bucketed and taken most-covering first, skipping any too close to one already taken.
- Items that ask for attention can surface themselves. A blinking status icon briefly shows the section holding it. A blink is told apart from a clock or a battery percentage by whether the icon keeps returning to a state it already showed. Off by default under Advanced.
- A Thaw Bar of its own: shape, tint, and border for the bar, independent of the menu bar it mirrors (#248, thanks @kn666).
- Hidden icons that refresh at the slider rate. Captures run through a recyclable XPC helper, so the per-call dictionary leak stays out of the app (#942, thanks @CamilleGuillory).
- One Per display section: the repeated per-display blocks collapse into a single picker-driven section.
- A standalone layout editor opens on its own, with per-Space appearance overrides and last-pane restore; items can be activated straight from the editor (#985, thanks @alvst).
- App icons where captures can't go. Items nobody can capture draw their owning app's icon, so the Thaw Bar, the layout pane, and Search work with Accessibility alone.
- A hotkey for automatic rehiding (#665, thanks @nightah).
- Diagnostic logs that rotate by size and time (#974) and diagnostics rows you can edit (#976), both by @nk-tedo-001.
Fixed
- A profile apply no longer walks the visible section into the hidden one (#1027, thanks @nk-tedo-001). On a three-display Mac after a restart, the reporter's bar went from twelve visible items to one in six seconds. The hidden divider was parked off-screen with two visible-bound items already stranded behind it, and Phase 1 had just declined to rescue them — a parked divider cannot be dragged onto (#899), so it hands off to the per-item pass. That pass then anchored its moves on the stranded items. A drop point derives from its anchor's leading edge, so each move pressed at a point off the display, AppKit dropped the item beside the parked anchor, and the next move anchored on the item just stranded: six desired-visible items followed each other out of the bar. Moves bound for the visible section now require an anchor that is actually on screen, and skip when it is not. Moves into the hidden and always-hidden sections are untouched — parking is how concealment works, and gating those would refuse every move into a collapsed section. A skipped move counts as unenacted, so the arrangement is not written back to the saved order as though it had been achieved.
- Control Center modules no longer persist under another app's name, and profiles that already carry one heal on load (#1027). The reporter's
main.jsonheldcom.techsmith.snagit.capturehelper:Battery. On a three-display setup, the source-PID resolution matched Control Center's Battery window to Snagit's helper process, the resolved PID became the identifier's namespace, and the wrong spelling persisted. The live item readscom.apple.controlcenter:Battery, so it never matched the saved entry again: every apply planned Battery as an unmanaged arrival into the hidden section, and the reporter could not reorder it. No existing guard catches this. The PID did resolve, so the identity is not provisional. The title is not a generic slot, so the item is not transient. And one wrong PID is not a majority, so the #784 gate stayed quiet as designed. What does identify the item is the title: only Control Center names an item "Battery", "WiFi", or "FocusModes". Those titles under any other namespace are now treated as misattributed. The persistence path excludes them the way it excludes an unresolved item, and the load-time prune drops the ghost from saved orders and profiles outright, since the title alone is proof enough and no live twin is needed to confirm it; the module then re-persists under its real name on the next cycle that resolves it properly. The cost of a wrong verdict is small: an app that genuinely titles its item "Battery" or "Clock" keeps its movability and only loses its persisted position. GenericItem-Nslots are never touched, since a third-party app's own slot is indistinguishable from a misattributed one by title alone. - A bulk apply no longer dispatches while the section dividers sit out of order (#1027). In the same log, both of the reporter's other control items were classified into the hidden section before any apply ran. The dividers were scattered rather than collapsed onto one coordinate, so the zero-width gate from #868 passed while every section assignment derived from that reading was wrong. Both apply paths, the saved-order dispatch and the profile pass's fresh re-read, now refuse a reading that places the visible control item or the always-hidden divider outside its own section. The refusal also attempts recovery: it un-parks a stranded hidden divider and re-seats the visible chevron, so a scrambled bar returns to a state the gate accepts instead of staying stuck. A divider that is absent still passes. A disabled always-hidden section has no divider by design, and a missing divider is what the #849 gate already handles.
Dependencies
swift-systemis declared directly; Collections and AsyncChannel joined the lockfile. The last XCTest suites moved to Swift Testing.