Skip to content

Commit f037841

Browse files
malpernclaude
andcommitted
Rename barswitch to sketchybar-toggle and add prerequisite checks
Rename the project, binary, modules, and all references from barswitch to sketchybar-toggle for better discoverability in the SketchyBar ecosystem. Add PrerequisiteChecker that verifies topmost=window and menu bar auto-hide settings, integrated into --setup and as a non-fatal startup warning. Update README with both problem/solution demo GIFs, troubleshooting section, and topmost documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent f0c5fa1 commit f037841

16 files changed

+411
-87
lines changed

Package.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
import PackageDescription
44

55
let package = Package(
6-
name: "barswitch",
6+
name: "sketchybar-toggle",
77
platforms: [
88
.macOS(.v13)
99
],
1010
targets: [
1111
.target(
12-
name: "BarSwitchCore",
13-
path: "Sources/BarSwitchCore"
12+
name: "SketchyBarToggleCore",
13+
path: "Sources/SketchyBarToggleCore"
1414
),
1515
.executableTarget(
16-
name: "barswitch",
17-
dependencies: ["BarSwitchCore"],
18-
path: "Sources/BarSwitch"
16+
name: "sketchybar-toggle",
17+
dependencies: ["SketchyBarToggleCore"],
18+
path: "Sources/SketchyBarToggle"
1919
),
2020
.testTarget(
21-
name: "BarSwitchTests",
22-
dependencies: ["BarSwitchCore"],
23-
path: "Tests/BarSwitchTests"
21+
name: "SketchyBarToggleTests",
22+
dependencies: ["SketchyBarToggleCore"],
23+
path: "Tests/SketchyBarToggleTests"
2424
)
2525
]
2626
)

README.md

Lines changed: 101 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,105 @@
1-
# BarSwitch
1+
# SketchyBar Toggle
22

33
A lightweight macOS daemon that coordinates between [SketchyBar](https://github.com/FelixKratz/SketchyBar) and the native macOS menu bar.
44

5-
<p align="center">
6-
<img src="demo.gif" alt="The native macOS menu bar sliding down over SketchyBar, causing an ugly overlap" width="800">
7-
<br>
8-
<em>Without BarSwitch: the native menu bar appears on top of SketchyBar when you move the mouse to the top of the screen</em>
9-
</p>
10-
115
## The Problem
126

137
If you use SketchyBar with the native macOS menu bar set to "auto-hide," both bars fight for the same space at the top of the screen. When you move your mouse up to reveal the native menu bar, it slides down *over* SketchyBar, creating an ugly overlap. There's no built-in way to coordinate them.
148

15-
## What BarSwitch Does
9+
<p align="center">
10+
<img src="demo-problem.gif" alt="The native macOS menu bar sliding down over SketchyBar, causing an ugly overlap" width="800">
11+
<br>
12+
<em>Without SketchyBar Toggle: the native menu bar drops down on top of SketchyBar</em>
13+
</p>
1614

17-
BarSwitch watches your mouse position and:
15+
## The Solution
1816

19-
1. **Mouse approaches the top of the screen** — BarSwitch hides SketchyBar so the native menu bar can appear cleanly
20-
2. **Mouse moves away from the top** — BarSwitch slides SketchyBar back into view
17+
SketchyBar Toggle watches your mouse position and coordinates the two bars:
18+
19+
1. **Mouse approaches the top of the screen** — hides SketchyBar so the native menu bar can appear cleanly
20+
2. **Mouse moves away from the top** — slides SketchyBar back into view
2121

2222
The result: you get SketchyBar as your primary status bar, with seamless access to the native menu bar whenever you need it. The two never overlap.
2323

24+
<p align="center">
25+
<img src="demo-solution.gif" alt="SketchyBar Toggle seamlessly switching between SketchyBar and the native macOS menu bar" width="800">
26+
<br>
27+
<em>With SketchyBar Toggle: SketchyBar hides as the menu bar appears, then slides back into view</em>
28+
</p>
29+
2430
## Prerequisites
2531

2632
1. **[SketchyBar](https://github.com/FelixKratz/SketchyBar)** installed and running
27-
2. **macOS menu bar set to auto-hide**: System Settings > Control Center > "Automatically hide and show the menu bar" > select "Always" or "In Full Screen Only"
33+
2. **SketchyBar `topmost` set to `"window"`** — this ensures SketchyBar renders above the macOS menu bar. Without it, SketchyBar will render behind the menu bar and appear invisible even when sketchybar-toggle shows it.
34+
35+
In your SketchyBar config (Lua):
36+
```lua
37+
sbar.bar({ topmost = "window", ... })
38+
```
39+
40+
Or shell-based `sketchybarrc`:
41+
```bash
42+
sketchybar --bar topmost=window
43+
```
44+
45+
3. **macOS menu bar set to auto-hide**: System Settings > Control Center > "Automatically hide and show the menu bar" > select "Always" or "In Full Screen Only"
46+
47+
> **Tip:** After changing the auto-hide setting, you may need to run `killall Dock` for it to take effect.
2848
2949
## Install
3050

3151
### Homebrew (recommended)
3252

3353
```bash
34-
brew install malpern/tap/barswitch
54+
brew install malpern/tap/sketchybar-toggle
3555
```
3656

3757
### Build from source
3858

3959
```bash
40-
git clone https://github.com/malpern/barswitch.git
41-
cd barswitch
60+
git clone https://github.com/malpern/sketchybar-toggle.git
61+
cd sketchybar-toggle
4262
swift build -c release
4363
```
4464

4565
Then copy the binary somewhere on your PATH:
4666

4767
```bash
4868
# Apple Silicon (default Homebrew prefix)
49-
cp .build/release/barswitch /opt/homebrew/bin/
69+
cp .build/release/sketchybar-toggle /opt/homebrew/bin/
5070

5171
# Or Intel Mac
52-
cp .build/release/barswitch /usr/local/bin/
72+
cp .build/release/sketchybar-toggle /usr/local/bin/
5373
```
5474

5575
Requires Swift 5.9+ and macOS 13 (Ventura) or later.
5676

5777
### Grant Input Monitoring permission
5878

59-
BarSwitch needs **Input Monitoring** permission to track mouse position:
79+
SketchyBar Toggle needs **Input Monitoring** permission to track mouse position:
6080

61-
1. Run `barswitch` — macOS will prompt you to grant permission, or it will print an error
81+
1. Run `sketchybar-toggle` — macOS will prompt you to grant permission, or it will print an error
6282
2. Go to **System Settings > Privacy & Security > Input Monitoring**
63-
3. Add and enable the `barswitch` binary
64-
4. Restart barswitch after granting permission
83+
3. Add and enable the `sketchybar-toggle` binary
84+
4. Restart sketchybar-toggle after granting permission
6585

66-
You can verify with `barswitch --check-permissions`.
86+
You can verify with `sketchybar-toggle --check-permissions`.
6787

6888
## SketchyBar Configuration
6989

70-
BarSwitch works best when your SketchyBar bar settings allow for smooth hide/show transitions. BarSwitch controls your bar using:
90+
SketchyBar Toggle works best when your SketchyBar bar settings allow for smooth hide/show transitions. SketchyBar Toggle controls your bar using:
7191

7292
- `sketchybar --bar hidden=on` — to hide
7393
- `sketchybar --bar hidden=off y_offset=-50` followed by `sketchybar --animate sin 12 --bar y_offset=0` — to show with a slide-down animation
7494

75-
No changes to your SketchyBar config are required. BarSwitch works with any SketchyBar setup out of the box.
95+
### Required: `topmost = "window"`
96+
97+
Your SketchyBar config **must** include `topmost = "window"`. This tells SketchyBar to render above the native macOS menu bar. Without it, SketchyBar renders behind the menu bar and will appear invisible even when sketchybar-toggle un-hides it.
98+
99+
```lua
100+
-- In your bar config (e.g., bar.lua or init.lua)
101+
sbar.bar({ topmost = "window", ... })
102+
```
76103

77104
### Optional: transparent bar style
78105

@@ -81,6 +108,7 @@ If you want your SketchyBar to visually match the native macOS menu bar (transpa
81108
```lua
82109
-- bar.lua
83110
sbar.bar({
111+
topmost = "window", -- REQUIRED for sketchybar-toggle
84112
height = 35,
85113
margin = 0,
86114
y_offset = 0,
@@ -108,67 +136,67 @@ background = {
108136

109137
### Quick setup
110138

111-
Run `barswitch --setup` to detect your SketchyBar config format and get the exact line to add:
139+
Run `sketchybar-toggle --setup` to detect your SketchyBar config format and get the exact line to add:
112140

113141
```bash
114-
barswitch --setup
142+
sketchybar-toggle --setup
115143
```
116144

117145
### Recommended: launch from SketchyBar's config
118146

119-
The simplest way to auto-start BarSwitch is to launch it from your SketchyBar config. This way BarSwitch starts and stops with SketchyBar.
147+
The simplest way to auto-start sketchybar-toggle is to launch it from your SketchyBar config. This way it starts and stops with SketchyBar.
120148

121149
If you use a **Lua config** (`sketchybarrc` calls into Lua), add this to your `init.lua` or `sketchybarrc`:
122150

123151
```lua
124-
-- Kill any existing instance, then start barswitch in the background
125-
sbar.exec("pkill -x barswitch; barswitch &")
152+
-- Kill any existing instance, then start sketchybar-toggle in the background
153+
sbar.exec("pkill -x sketchybar-toggle; sketchybar-toggle &")
126154
```
127155

128156
If you use a **shell-based** `sketchybarrc`:
129157

130158
```bash
131-
# Start barswitch alongside SketchyBar
132-
pkill -x barswitch
133-
barswitch &
159+
# Start sketchybar-toggle alongside SketchyBar
160+
pkill -x sketchybar-toggle
161+
sketchybar-toggle &
134162
```
135163

136164
### Alternative: launchd plist
137165

138-
If you prefer BarSwitch to run independently (e.g., start at login regardless of SketchyBar), copy the included plist:
166+
If you prefer sketchybar-toggle to run independently (e.g., start at login regardless of SketchyBar), copy the included plist:
139167

140168
```bash
141-
cp com.barswitch.agent.plist ~/Library/LaunchAgents/
142-
launchctl load ~/Library/LaunchAgents/com.barswitch.agent.plist
169+
cp com.sketchybar-toggle.agent.plist ~/Library/LaunchAgents/
170+
launchctl load ~/Library/LaunchAgents/com.sketchybar-toggle.agent.plist
143171
```
144172

145-
> **Note:** Edit the plist if your binary isn't at `/usr/local/bin/barswitch` — update the path in `ProgramArguments`.
173+
> **Note:** Edit the plist if your binary isn't at `/usr/local/bin/sketchybar-toggle` — update the path in `ProgramArguments`.
146174
147175
To stop:
148176

149177
```bash
150-
launchctl unload ~/Library/LaunchAgents/com.barswitch.agent.plist
178+
launchctl unload ~/Library/LaunchAgents/com.sketchybar-toggle.agent.plist
151179
```
152180

153-
Logs are written to `/tmp/barswitch.log`.
181+
Logs are written to `/tmp/sketchybar-toggle.log`.
154182

155183
## Usage
156184

157185
```bash
158186
# Run with defaults
159-
barswitch
187+
sketchybar-toggle
160188

161189
# Custom thresholds
162-
barswitch --trigger-zone 10 --menu-bar-height 50 --debounce 150
190+
sketchybar-toggle --trigger-zone 10 --menu-bar-height 50 --debounce 150
163191

164192
# Show auto-start setup instructions
165-
barswitch --setup
193+
sketchybar-toggle --setup
166194

167195
# Check permissions
168-
barswitch --check-permissions
196+
sketchybar-toggle --check-permissions
169197

170198
# Print version
171-
barswitch --version
199+
sketchybar-toggle --version
172200
```
173201

174202
### Options
@@ -178,7 +206,7 @@ barswitch --version
178206
| `--trigger-zone <px>` | 10 | Distance from top of screen (in pixels) that triggers SketchyBar to hide |
179207
| `--menu-bar-height <px>` | 50 | Distance from top defining the menu bar zone — SketchyBar won't reappear until the mouse is below this |
180208
| `--debounce <ms>` | 150 | Delay in milliseconds before SketchyBar reappears, prevents flicker on rapid mouse movement |
181-
| `--setup` | | Detect SketchyBar config and show auto-start instructions |
209+
| `--setup` | | Check prerequisites and show auto-start instructions |
182210
| `--check-permissions` | | Check if Input Monitoring permission is granted |
183211
| `--version` | | Print version |
184212
| `--help` | | Show help |
@@ -191,9 +219,23 @@ barswitch --version
191219
- **Transitions feel slow**: decrease `--debounce` (e.g., `--debounce 100`)
192220
- **Flickering on rapid mouse movement**: increase `--debounce`
193221

222+
## Troubleshooting
223+
224+
**SketchyBar doesn't appear / renders behind the menu bar**
225+
Your SketchyBar config is missing `topmost = "window"`. Add it to your bar settings and restart SketchyBar (`brew services restart sketchybar`). See [Prerequisites](#prerequisites).
226+
227+
**Menu bar auto-hide setting doesn't take effect**
228+
After changing "Automatically hide and show the menu bar" in System Settings, run `killall Dock` to force macOS to apply the change immediately.
229+
230+
**sketchybar-toggle is running but nothing happens**
231+
Run `sketchybar-toggle --setup` to check prerequisites. The most common cause is a missing `topmost = "window"` setting in SketchyBar.
232+
233+
**SketchyBar stays hidden after sketchybar-toggle crashes or is force-killed**
234+
Run `sketchybar --bar hidden=off` to restore it manually. Under normal shutdown (Ctrl+C or SIGTERM), sketchybar-toggle restores SketchyBar automatically.
235+
194236
## How It Works
195237

196-
BarSwitch uses a passive [CGEventTap](https://developer.apple.com/documentation/coregraphics/cgevent) to monitor mouse movement at the Core Graphics level. This is event-driven (zero CPU when the mouse isn't moving) and works globally across all apps, including fullscreen.
238+
SketchyBar Toggle uses a passive [CGEventTap](https://developer.apple.com/documentation/coregraphics/cgevent) to monitor mouse movement at the Core Graphics level. This is event-driven (zero CPU when the mouse isn't moving) and works globally across all apps, including fullscreen.
197239

198240
The core logic is a simple state machine:
199241

@@ -208,27 +250,28 @@ SKETCHYBAR_HIDDEN
208250
→ slide SketchyBar back into view
209251
```
210252

211-
BarSwitch controls SketchyBar via its CLI (`sketchybar --bar hidden=on/off`) and uses SketchyBar's built-in animation system for smooth slide-down transitions.
253+
SketchyBar Toggle controls SketchyBar via its CLI (`sketchybar --bar hidden=on/off`) and uses SketchyBar's built-in animation system for smooth slide-down transitions.
212254

213-
On startup, BarSwitch restores SketchyBar to visible (in case a previous instance crashed with the bar hidden). On SIGTERM/SIGINT (Ctrl+C or `kill`), it restores visibility before exiting.
255+
On startup, sketchybar-toggle restores SketchyBar to visible (in case a previous instance crashed with the bar hidden). On SIGTERM/SIGINT (Ctrl+C or `kill`), it restores visibility before exiting.
214256

215257
## Architecture
216258

217259
```
218-
barswitch/
260+
sketchybar-toggle/
219261
├── Package.swift
220262
├── Sources/
221-
│ ├── BarSwitchCore/ # Library — all testable logic
222-
│ │ ├── BarController.swift # Protocol for bar control (enables mocking)
223-
│ │ ├── StateMachine.swift # State machine: visible ↔ hidden with debounce
224-
│ │ ├── EventTap.swift # CGEventTap setup + screen geometry
225-
│ │ ├── SketchyBarController.swift # Shells out to sketchybar CLI
226-
│ │ └── Config.swift # CLI argument parsing
227-
│ └── BarSwitch/
228-
│ └── main.swift # Entry point, signal handlers, run loop
263+
│ ├── SketchyBarToggleCore/ # Library — all testable logic
264+
│ │ ├── BarController.swift # Protocol for bar control (enables mocking)
265+
│ │ ├── StateMachine.swift # State machine: visible ↔ hidden with debounce
266+
│ │ ├── EventTap.swift # CGEventTap setup + screen geometry
267+
│ │ ├── SketchyBarController.swift # Shells out to sketchybar CLI
268+
│ │ ├── PrerequisiteChecker.swift # Verifies topmost, menu bar auto-hide
269+
│ │ └── Config.swift # CLI argument parsing
270+
│ └── SketchyBarToggle/
271+
│ └── main.swift # Entry point, signal handlers, run loop
229272
├── Tests/
230-
│ └── BarSwitchTests/ # 28 unit tests
231-
├── com.barswitch.agent.plist # launchd plist for auto-start
273+
│ └── SketchyBarToggleTests/ # Unit tests
274+
├── com.sketchybar-toggle.agent.plist # launchd plist for auto-start
232275
└── README.md
233276
```
234277

0 commit comments

Comments
 (0)