Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a4e2fbda2 | ||
|
|
92a57308b7 |
@@ -112,6 +112,24 @@ no control over this, so the app creates its own `NSStatusItem` and:
|
|||||||
`/tmp/simpletopbar-items.txt`; use it to verify the icon is not under the notch
|
`/tmp/simpletopbar-items.txt`; use it to verify the icon is not under the notch
|
||||||
(x should be ~1200, not ~765).
|
(x should be ~1200, not ~765).
|
||||||
|
|
||||||
|
## Hiding other menu bar items
|
||||||
|
|
||||||
|
`MenuBarHider` creates a zero-width spacer `NSStatusItem` at launch and grows its
|
||||||
|
length to `hiddenLength` (10_000) to push the icons on its left off-screen. Its
|
||||||
|
preferred position controls where the hidden/kept boundary lands:
|
||||||
|
|
||||||
|
- Seed **250** (default) puts the boundary just left of Wi-Fi, so every
|
||||||
|
third-party app icon goes to x < 0 (cmux, Kapture, moomoo, WireGuard,
|
||||||
|
TextInputMenuAgent, Now Playing) while **Wi-Fi (x≈1173), Spotlight, Clock,
|
||||||
|
Battery, Control Center and our hamburger stay visible**.
|
||||||
|
- Verified with `--diag-hide` across positions 100–400. Below ~200 Wi-Fi gets
|
||||||
|
hidden too; above ~300 app icons (Now Playing, TextInput) leak back.
|
||||||
|
- `debug.spacerPos` (Double) overrides the seed for tuning without rebuilding.
|
||||||
|
- **Wi-Fi/Spotlight/Clock/Battery/Control Center cannot be hidden**: macOS pins
|
||||||
|
them to the far right and a third-party item can never be inserted to their
|
||||||
|
right, so the spacer has nothing to push them with. This is a macOS
|
||||||
|
constraint, not a bug.
|
||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
- `AppListModel` is `@MainActor`; the `NSWorkspace` observers hop back with
|
- `AppListModel` is `@MainActor`; the `NSWorkspace` observers hop back with
|
||||||
|
|||||||
@@ -27,11 +27,25 @@ still works.
|
|||||||
|
|
||||||
macOS has no public API to move another app's status item. The **Hide items from
|
macOS has no public API to move another app's status item. The **Hide items from
|
||||||
the menu bar** toggle uses the spacer technique: a zero-width status item is
|
the menu bar** toggle uses the spacer technique: a zero-width status item is
|
||||||
created at launch whose length is expanded to push the items to its left
|
created at launch whose length is expanded to push the other icons off-screen so
|
||||||
off-screen. This is reliable only when SimpleTopBar starts at login (its spacer
|
they only live in this panel. It is off by default and always undone on quit; if
|
||||||
then sits to the right of later-launched apps' items) and may need re-toggling
|
the app dies, macOS removes the spacer automatically.
|
||||||
after items move around. It is off by default and always undone on quit; if the
|
|
||||||
app dies, macOS removes the spacer automatically.
|
What it can and cannot hide:
|
||||||
|
|
||||||
|
- It hides **other third-party apps' icons** (cmux, Kapture, WireGuard, input
|
||||||
|
source, Now Playing, …) so only your apps' icons leave the bar.
|
||||||
|
- It **keeps Wi-Fi, Spotlight, Clock, Battery and Control Center**. The spacer's
|
||||||
|
boundary is tuned (preferred position 250) to fall just left of Wi-Fi, so the
|
||||||
|
Apple items on the right stay visible. macOS reserves that far-right area: a
|
||||||
|
third-party item can never be placed to the right of it, so those icons cannot
|
||||||
|
be pushed away even in principle. (Bartender and Ice hit the same wall and
|
||||||
|
cover the area with their own overlay bar instead.)
|
||||||
|
- Newly launched apps are placed to the left of the spacer, so they are hidden
|
||||||
|
automatically.
|
||||||
|
- Advanced: set `defaults write dev.tzgyn.simpletopbar debug.spacerPos -float <n>`
|
||||||
|
to move the boundary (larger = keep more icons; > ~400 starts leaking app
|
||||||
|
icons back into the bar).
|
||||||
|
|
||||||
## Install with Homebrew
|
## Install with Homebrew
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if CommandLine.arguments.contains("--diag-hide") {
|
||||||
|
MenuBarHider.shared.enabled = true
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
||||||
|
dumpMenuBarItems()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// The tray is empty without Accessibility permission, so surface the
|
// The tray is empty without Accessibility permission, so surface the
|
||||||
// system prompt once at launch instead of waiting for the user to open
|
// system prompt once at launch instead of waiting for the user to open
|
||||||
// the panel and find the button.
|
// the panel and find the button.
|
||||||
|
|||||||
@@ -165,7 +165,18 @@ final class MenuBarHider: ObservableObject {
|
|||||||
/// Create the spacer early (at launch) so it lands as far right as possible.
|
/// Create the spacer early (at launch) so it lands as far right as possible.
|
||||||
func prepare() {
|
func prepare() {
|
||||||
guard spacer == nil else { return }
|
guard spacer == nil else { return }
|
||||||
|
let name = "SimpleTopBarHider"
|
||||||
|
let key = "NSStatusItem Preferred Position \(name)"
|
||||||
|
// The boundary between "hidden" and "kept" falls just left of Wi-Fi at
|
||||||
|
// ~250, so the other apps hide while Apple's Wi-Fi/Clock/Battery/Control
|
||||||
|
// Center/Spotlight stay visible. `debug.spacerPos` overrides the seed.
|
||||||
|
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)
|
||||||
|
}
|
||||||
let item = NSStatusBar.system.statusItem(withLength: 0)
|
let item = NSStatusBar.system.statusItem(withLength: 0)
|
||||||
|
item.autosaveName = name
|
||||||
item.button?.isHidden = true
|
item.button?.isHidden = true
|
||||||
spacer = item
|
spacer = item
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ struct TopBarView: View {
|
|||||||
.controlSize(.mini)
|
.controlSize(.mini)
|
||||||
.padding(.horizontal, 12)
|
.padding(.horizontal, 12)
|
||||||
.padding(.top, 6)
|
.padding(.top, 6)
|
||||||
.help("Best-effort: pushes the real items off the menu bar so they only live here. Reliable when SimpleTopBar starts at login.")
|
.help("Best-effort: pushes other apps' icons off the menu bar so they only live here. Apple's Wi-Fi, Spotlight, Clock, Battery and Control Center stay visible; macOS won't let any third-party app move them.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
VERSION="${1:-0.2.2}"
|
VERSION="${1:-0.2.3}"
|
||||||
|
|
||||||
swift build -c release
|
swift build -c release
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user