Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c5416d27e | ||
|
|
61d2689cbc |
@@ -134,6 +134,13 @@ preferred position controls where the hidden/kept boundary lands:
|
|||||||
- Verified with `--diag-hide` across positions 100–400. Below ~200 Wi-Fi gets
|
- Verified with `--diag-hide` across positions 100–400. Below ~200 Wi-Fi gets
|
||||||
hidden too; above ~300 app icons (Now Playing, TextInput) leak back.
|
hidden too; above ~300 app icons (Now Playing, TextInput) leak back.
|
||||||
- `debug.spacerPos` (Double) overrides the seed for tuning without rebuilding.
|
- `debug.spacerPos` (Double) overrides the seed for tuning without rebuilding.
|
||||||
|
- Pressing a tray tile calls `MenuBarItemManager.press`. A hidden item sits
|
||||||
|
off-screen, and its menu would open off-screen too, so press briefly
|
||||||
|
`suspend()`s the hider, waits ~0.18s for the layout to settle, performs the
|
||||||
|
accessibility action (`kAXPressAction`, then `kAXShowMenuAction`), and
|
||||||
|
`resume()`s ~1s later. The reveal is momentary, not for the whole time the
|
||||||
|
panel is open. macOS does not let us place or anchor another app's menu
|
||||||
|
anywhere else, so a momentary reveal is the only way to show it in view.
|
||||||
- **Order matters**: `AppDelegate` must call `setupStatusItem()` *before*
|
- **Order matters**: `AppDelegate` must call `setupStatusItem()` *before*
|
||||||
`MenuBarHider.shared.prepare()`. If the hider contracts the bar first, the
|
`MenuBarHider.shared.prepare()`. If the hider contracts the bar first, the
|
||||||
hamburger is created into the collapsed space and lands off-screen.
|
hamburger is created into the collapsed space and lands off-screen.
|
||||||
|
|||||||
@@ -103,10 +103,30 @@ final class MenuBarItemManager: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the real menu bar item by pressing its accessibility element, so
|
/// Opens the real menu bar item, so its menu/popover appears.
|
||||||
/// its menu/popover appears at its true screen location.
|
///
|
||||||
@discardableResult
|
/// A hidden item sits off-screen, and its menu would open off-screen too.
|
||||||
func press(_ item: MenuBarItem) -> Bool {
|
/// So briefly reveal the items, let the layout settle, press the item, then
|
||||||
|
/// hide again shortly after. The reveal is momentary rather than lasting the
|
||||||
|
/// whole time the panel is open.
|
||||||
|
func press(_ item: MenuBarItem) {
|
||||||
|
let hider = MenuBarHider.shared
|
||||||
|
let needsReveal = hider.isHiding
|
||||||
|
guard needsReveal else {
|
||||||
|
_ = performPress(item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hider.suspend()
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.18) {
|
||||||
|
_ = self.performPress(item)
|
||||||
|
// Let the menu finish appearing before the bar contracts again.
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||||
|
hider.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func performPress(_ item: MenuBarItem) -> Bool {
|
||||||
if AXUIElementPerformAction(item.element, kAXPressAction as CFString) == .success {
|
if AXUIElementPerformAction(item.element, kAXPressAction as CFString) == .success {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -252,6 +272,22 @@ final class MenuBarHider: ObservableObject {
|
|||||||
isHiding = hiding
|
isHiding = hiding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Temporarily reveal the items (e.g. while the panel is open) so pressing
|
||||||
|
/// a tray icon opens its menu at its real, on-screen position. Keeps the
|
||||||
|
/// user's `enabled` preference untouched.
|
||||||
|
func suspend() {
|
||||||
|
guard enabled else { return }
|
||||||
|
spacer?.length = 0
|
||||||
|
isHiding = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restore hiding after a `suspend()`.
|
||||||
|
func resume() {
|
||||||
|
guard enabled else { return }
|
||||||
|
spacer?.length = Self.hiddenLength
|
||||||
|
isHiding = true
|
||||||
|
}
|
||||||
|
|
||||||
/// Put the menu bar back the way we found it. Called on quit. Leaves the
|
/// Put the menu bar back the way we found it. Called on quit. Leaves the
|
||||||
/// user's preference intact.
|
/// user's preference intact.
|
||||||
func restore() {
|
func restore() {
|
||||||
|
|||||||
Reference in New Issue
Block a user