1 Commits
Author SHA1 Message Date
TZGyn 5a4e2fbda2 Keep Wi-Fi visible when hiding other menu bar icons
Hiding pushed Wi-Fi off along with the third-party app icons. Tune the
spacer boundary to sit just left of Wi-Fi so apps disappear while the
Apple Wi-Fi, Spotlight, Clock, Battery and Control Center icons remain.

💘 Generated with Crush

Assisted-by: Crush:deepseek-v4.1-flash
2026-09-27 00:39:00 +08:00
4 changed files with 31 additions and 19 deletions
+12 -7
View File
@@ -115,14 +115,19 @@ no control over this, so the app creates its own `NSStatusItem` and:
## Hiding other menu bar items ## Hiding other menu bar items
`MenuBarHider` creates a zero-width spacer `NSStatusItem` at launch and grows its `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. length to `hiddenLength` (10_000) to push the icons on its left off-screen. Its
Verified with `--diag-hide`: preferred position controls where the hidden/kept boundary lands:
- All third-party apps' icons go to x < 0 (cmux, Kapture, moomoo, WireGuard, - Seed **250** (default) puts the boundary just left of Wi-Fi, so every
TextInputMenuAgent, Now Playing) and so does Wi-Fi. third-party app icon goes to x < 0 (cmux, Kapture, moomoo, WireGuard,
- **Spotlight, Clock, Battery and Control Center stay**: macOS pins them to the TextInputMenuAgent, Now Playing) while **Wi-Fi (x≈1173), Spotlight, Clock,
far right, and a third-party item can never be inserted to their right, so the Battery, Control Center and our hamburger stay visible**.
spacer has nothing to push them with. Do not try to "fix" this; it is a macOS - 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. constraint, not a bug.
## Gotchas ## Gotchas
+11 -7
View File
@@ -33,15 +33,19 @@ the app dies, macOS removes the spacer automatically.
What it can and cannot hide: What it can and cannot hide:
- It hides **other third-party apps' icons** (and can also catch some Apple - It hides **other third-party apps' icons** (cmux, Kapture, WireGuard, input
items such as Wi-Fi). source, Now Playing, …) so only your apps' icons leave the bar.
- It **cannot** hide **Spotlight, Clock, Battery, or Control Center**. macOS - It **keeps Wi-Fi, Spotlight, Clock, Battery and Control Center**. The spacer's
reserves the far right of the menu bar for those, and a third-party app cannot boundary is tuned (preferred position 250) to fall just left of Wi-Fi, so the
place its item to their right, so there is nothing to push them with. (This is Apple items on the right stay visible. macOS reserves that far-right area: a
the same limit Bartender and Ice hit; they cover the area with their own third-party item can never be placed to the right of it, so those icons cannot
overlay bar instead.) 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 - Newly launched apps are placed to the left of the spacer, so they are hidden
automatically. 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
+7 -4
View File
@@ -167,10 +167,13 @@ final class MenuBarHider: ObservableObject {
guard spacer == nil else { return } guard spacer == nil else { return }
let name = "SimpleTopBarHider" let name = "SimpleTopBarHider"
let key = "NSStatusItem Preferred Position \(name)" let key = "NSStatusItem Preferred Position \(name)"
// Seed just left of the hamburger so growing the spacer pushes the // The boundary between "hidden" and "kept" falls just left of Wi-Fi at
// third-party icons on its left off-screen while ours stays put. // ~250, so the other apps hide while Apple's Wi-Fi/Clock/Battery/Control
if UserDefaults.standard.object(forKey: key) == nil { // Center/Spotlight stay visible. `debug.spacerPos` overrides the seed.
UserDefaults.standard.set(150.0, forKey: key) 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.autosaveName = name
+1 -1
View File
@@ -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 other apps' icons off the menu bar so they only live here. Apple's Spotlight, Clock, Battery and Control Center stay pinned on the right and cannot be moved by any third-party app.") .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.")
} }
} }
} }