Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5eb2d0f661 |
@@ -38,6 +38,10 @@ executable SwiftPM package, no external dependencies (all Apple frameworks).
|
||||
or per-element, so every helper returns `nil` instead of force-unwrapping. The
|
||||
`enumerate()` routine is `nonisolated static` so `--self-test` can run it.
|
||||
- Items are keyed by `pid-index`; `MenuBarItem` equality ignores the AX element.
|
||||
- Control Center is special: its extras menu bar lists **every module it owns**,
|
||||
including ones not in the bar, which are parked off-screen at `y≈982`.
|
||||
`enumerate()` drops items whose AX position `y > 60` and de-duplicates by
|
||||
title per app, otherwise the tray fills with identical "Control Center" tiles.
|
||||
- Reading another app's UI is the only TCC permission needed; there is no Screen
|
||||
Recording or Apple Events usage.
|
||||
|
||||
|
||||
@@ -68,11 +68,23 @@ final class MenuBarItemManager: ObservableObject {
|
||||
guard let bar = extrasMenuBar(of: axApp),
|
||||
let children = children(of: bar) else { continue }
|
||||
|
||||
var seenTitles = Set<String>()
|
||||
for (index, child) in children.enumerated() {
|
||||
// Control Center reports every module it owns, including the
|
||||
// ones not in the menu bar, which are parked off-screen around
|
||||
// y=982. Keep only items actually sitting in the bar.
|
||||
if let position = pointAttribute(child, kAXPositionAttribute), position.y > 60 {
|
||||
continue
|
||||
}
|
||||
|
||||
let title = stringAttribute(child, kAXDescriptionAttribute)
|
||||
?? stringAttribute(child, kAXTitleAttribute)
|
||||
?? app.localizedName
|
||||
?? "Item"
|
||||
// Several Control Center modules share the generic title
|
||||
// "Control Center"; show each distinct title once per app.
|
||||
if !seenTitles.insert(title).inserted { continue }
|
||||
|
||||
found.append(MenuBarItem(
|
||||
id: "\(pid)-\(index)",
|
||||
pid: pid,
|
||||
|
||||
Reference in New Issue
Block a user