Keep all system icons visible and click Spotlight properly

The spacer boundary cut off Now Playing and the input source, which
should stay like Wi-Fi, so move it left of every Apple item. Spotlight's
status item ignores the accessibility press action, so click it at its
real position instead.

💘 Generated with Crush

Assisted-by: Crush:deepseek-v4.1-flash
This commit is contained in:
2026-09-27 10:35:20 +08:00
parent 8d795d0a28
commit abb0b548bf
4 changed files with 44 additions and 7 deletions
+39 -2
View File
@@ -11,6 +11,8 @@ struct MenuBarItem: Identifiable, Equatable {
let icon: NSImage
/// True for Apple's own items (Control Center, Spotlight, …).
let isSystem: Bool
/// Frame in Accessibility coordinates (origin top-left of the main screen).
let frame: CGRect?
let element: AXUIElement
static func == (lhs: MenuBarItem, rhs: MenuBarItem) -> Bool {
@@ -75,10 +77,11 @@ final class MenuBarItemManager: ObservableObject {
var seenTitles = Set<String>()
for (index, child) in children.enumerated() {
let position = pointAttribute(child, kAXPositionAttribute)
// 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 {
if let position, position.y > 60 {
continue
}
@@ -90,6 +93,14 @@ final class MenuBarItemManager: ObservableObject {
// "Control Center"; show each distinct title once per app.
if !seenTitles.insert(title).inserted { continue }
let size = sizeAttribute(child, kAXSizeAttribute)
let frame: CGRect?
if let position, let size {
frame = CGRect(origin: position, size: size)
} else {
frame = nil
}
found.append(MenuBarItem(
id: "\(pid)-\(index)",
pid: pid,
@@ -97,6 +108,7 @@ final class MenuBarItemManager: ObservableObject {
title: title,
icon: Self.icon(forTitle: title, app: app),
isSystem: Self.isSystemBundle(app.bundleIdentifier),
frame: frame,
element: child
))
}
@@ -138,12 +150,27 @@ final class MenuBarItemManager: ObservableObject {
}
private func performPress(_ item: MenuBarItem) -> Bool {
// Spotlight's status item accepts the accessibility press action but
// does nothing with it; it needs a genuine click.
if item.appName.lowercased().contains("spotlight"), let frame = item.frame {
postClick(at: CGPoint(x: frame.midX, y: frame.midY))
return true
}
if AXUIElementPerformAction(item.element, kAXPressAction as CFString) == .success {
return true
}
return AXUIElementPerformAction(item.element, kAXShowMenuAction as CFString) == .success
}
/// Posts a real left click at a point in Accessibility/global coordinates.
private func postClick(at point: CGPoint) {
let source = CGEventSource(stateID: .hidSystemState)
let down = CGEvent(mouseEventSource: source, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left)
let up = CGEvent(mouseEventSource: source, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left)
down?.post(tap: .cghidEventTap)
up?.post(tap: .cghidEventTap)
}
// MARK: - Classification
/// Apple's own menu bar items (Control Center, Spotlight, the input-source
@@ -235,6 +262,16 @@ final class MenuBarItemManager: ObservableObject {
guard AXValueGetValue(value as! AXValue, .cgPoint, &point) else { return nil }
return point
}
nonisolated static func sizeAttribute(_ element: AXUIElement, _ attribute: String) -> CGSize? {
var value: CFTypeRef?
guard AXUIElementCopyAttributeValue(element, attribute as CFString, &value) == .success,
let value,
CFGetTypeID(value) == AXValueGetTypeID() else { return nil }
var size = CGSize.zero
guard AXValueGetValue(value as! AXValue, .cgSize, &size) else { return nil }
return size
}
}
/// Best-effort menu bar item hiding. A zero-width spacer status item is created
@@ -279,7 +316,7 @@ final class MenuBarHider: ObservableObject {
if let override = UserDefaults.standard.object(forKey: "debug.spacerPos") as? Double {
UserDefaults.standard.set(override, forKey: key)
} else if UserDefaults.standard.object(forKey: key) == nil {
UserDefaults.standard.set(250.0, forKey: key)
UserDefaults.standard.set(350.0, forKey: key)
}
let item = NSStatusBar.system.statusItem(withLength: 0)
item.autosaveName = name