You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>
A lightweight macOS daemon that coordinates between [SketchyBar](https://github.com/FelixKratz/SketchyBar) and the native macOS menu bar.
4
4
5
-
<palign="center">
6
-
<imgsrc="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
-
11
5
## The Problem
12
6
13
7
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.
14
8
15
-
## What BarSwitch Does
9
+
<palign="center">
10
+
<imgsrc="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>
16
14
17
-
BarSwitch watches your mouse position and:
15
+
## The Solution
18
16
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
21
21
22
22
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.
23
23
24
+
<palign="center">
25
+
<imgsrc="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
+
24
30
## Prerequisites
25
31
26
32
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.
Requires Swift 5.9+ and macOS 13 (Ventura) or later.
56
76
57
77
### Grant Input Monitoring permission
58
78
59
-
BarSwitch needs **Input Monitoring** permission to track mouse position:
79
+
SketchyBar Toggle needs **Input Monitoring** permission to track mouse position:
60
80
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
62
82
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
65
85
66
-
You can verify with `barswitch --check-permissions`.
86
+
You can verify with `sketchybar-toggle --check-permissions`.
67
87
68
88
## SketchyBar Configuration
69
89
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:
71
91
72
92
-`sketchybar --bar hidden=on` — to hide
73
93
-`sketchybar --bar hidden=off y_offset=-50` followed by `sketchybar --animate sin 12 --bar y_offset=0` — to show with a slide-down animation
74
94
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
+
```
76
103
77
104
### Optional: transparent bar style
78
105
@@ -81,6 +108,7 @@ If you want your SketchyBar to visually match the native macOS menu bar (transpa
81
108
```lua
82
109
-- bar.lua
83
110
sbar.bar({
111
+
topmost="window", -- REQUIRED for sketchybar-toggle
84
112
height=35,
85
113
margin=0,
86
114
y_offset=0,
@@ -108,67 +136,67 @@ background = {
108
136
109
137
### Quick setup
110
138
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:
112
140
113
141
```bash
114
-
barswitch --setup
142
+
sketchybar-toggle --setup
115
143
```
116
144
117
145
### Recommended: launch from SketchyBar's config
118
146
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.
120
148
121
149
If you use a **Lua config** (`sketchybarrc` calls into Lua), add this to your `init.lua` or `sketchybarrc`:
122
150
123
151
```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
-**Flickering on rapid mouse movement**: increase `--debounce`
193
221
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
+
194
236
## How It Works
195
237
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.
197
239
198
240
The core logic is a simple state machine:
199
241
@@ -208,27 +250,28 @@ SKETCHYBAR_HIDDEN
208
250
→ slide SketchyBar back into view
209
251
```
210
252
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.
212
254
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.
214
256
215
257
## Architecture
216
258
217
259
```
218
-
barswitch/
260
+
sketchybar-toggle/
219
261
├── Package.swift
220
262
├── 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
0 commit comments