Technical details
How adflow for macOS measures, places and runs itself, what you can set on the command line, and what the server sends. None of this is needed to use it.
It behaves like system chrome.
No window elbowing its way forward. The bar sits in the strip macOS claims for itself anyway, and keeps to its measurements.
- OPENING
- By click only
Nothing expands on its own. The spot changes every 60 s in the compact state too, and the bar stays narrow while it does. One click expands and holds it open, the next collapses it.
- GEOMETRY
- Only the width moves
The height never changes. Widths follow the content. Compact: badge, brand, tagline, equalizer; expanded: plus body text, button and
✕. All of it is eased along smoothly, including on a spot change. - MEASUREMENTS
- Measured at runtime
screen.frame.maxY − screen.visibleFrame.maxY, falling back toNSStatusBar.thickness. On Macs with a notch the height comes out larger by itself; type, badge and button scale along viak = barHeight / 24. - LAYERING
- Above everything, on every Space
Window level above the menu bar. Position and height are set again on every resolution or display change. The bar stays flush against the edge.
- TIMING
- Progress line
A thin line runs along the bottom until the next spot. Right-click jumps ahead at once,
Escor✕quits. - BUILD
- One file, no baggage
Native, with Cocoa and ApplicationServices.
main.swift, compiled withswiftc -O. No packages, no bundle, no Dock icon.
It never covers your menus.
If the front app's menus reach far to the right (Xcode, Photoshop), or many status icons sit to their left, the display slides aside instead of lying on top. And only as far as it has to. Drag the sliders.
The position of the app menus and the status icons can only be read through the Accessibility API. The menu bar itself is a single window of the Window Server. Without permission everything works, but the display always stays centered. With permission it yields. If it fits nowhere, it centers itself in the largest gap so the overlap stays minimal and even.
Double-click. That is the setup.
The download is a finished program. You do not need a compiler, and you do not need the Terminal.
-
Open Adflow.app
It is in the file you downloaded. Double-click it like any other app. There is no installer and nothing to agree to.
-
Allow it once, in System Settings
Open System Settings, go to Privacy & Security, scroll down and click Open Anyway. That is a one-time step for the archive route; the one-line install skips it. After that the app starts normally, every time.
-
Enter your ID and passkey
The app asks for them itself, in a small window, right after the first start. Paste in the two lines you got with the download. You can also click Skip for now: the bar then shows demo spots and earns nothing.
The ready-made app runs on Macs with Apple Silicon, that is M1 and newer. On an older Intel Mac, use the one-line install in Terminal instead: it notices the Intel chip and builds the app for your Mac.
Once it runs
| Click the bar | opens it, click again and it closes |
| Right-click | jumps to the next spot |
| Esc, or the cross | quits |
If you would rather use the Terminal
None of this is necessary. It is here for people who want it, and for anyone who would rather build it from source.
Run from source
# start, recompiles when needed ~/adflow/macos/run.sh # or directly swiftc -O main.swift -o island && ./island
Account
./island --pair DIA-XXXXX-XXXXX XXXXX-XXXXX-XXXXX-XXXXX ./island --account ./island --logout
The same thing the app asks for in its own window. The passkey goes over
the wire exactly once; after that only a device token sits in
~/Library/Application Support/Adflow, readable by you alone.
Yielding to your menus
./island --setup
Opens the system dialog that grants the permission. Afterwards restart the
program that launches it, so Terminal.app, not island.
Without the permission everything still works, the bar just always stays
centered.
Placement
./island --offset 140 ./island --probe
--offset pushes the bar a fixed distance to the right,
negative to the left, and needs no permission. --probe shows for
20 seconds which app owns the menu bar and where the bar slides to.
--selftest and --snapshot preview.png exist too.
Nothing to configure.
The app fetches the current spots from the server when it starts, and again every 15 minutes. You never edit anything, and you never restart anything. If you want to run a spot yourself, you book one, same as any other advertiser.
What a spot looks like on the wire
For the curious. This is the JSON the app receives from
ads.php. Nothing here is anything you have to do.
{
"brand": "YOUR BRAND",
"tag": "Line under the name",
"body": "Line that appears only when the bar is open.",
"cta": "Button text",
"mark": "M", // letter in the badge
"accent": "#FF9F0A" // accent colour
}
- Always there
- brand, tag, accent
Without these a spot is skipped. If
markis missing, the first letter of the brand is used. - Optional
- body, cta
Left empty, the body line and the button simply do not appear. The bar then shows the brand and the line under it.
- If the server is unreachable
- It keeps running
The spots built into the program take over, so the bar always has something to show. Those do not earn anything, and nothing is reported.
Widths are not configured anywhere. The app measures the text and works out the two widths from it, which is why a longer brand name simply makes the bar wider.