macotron.app
List running apps, launch or switch to an app by bundle ID, hide or quit it, and choose a command from its menu bar. Apps are named by bundle ID, such as com.apple.Safari.
macotron.keyboard.on("Open Calendar", "ctrl+opt+c", () => {
macotron.app.launch("com.apple.iCal");
});
Running apps
list(): Array<{ name: string; bundleID: string; pid: number }>
Every running process that has a bundle ID, which includes background apps and menu bar apps. name is the app's display name.
frontmost(): { name: string; bundleID: string; pid: number } | null
The app in front. Macotron itself is skipped: while a Macotron panel or the launcher has focus, this returns the app that was in front before it. Returns null when there is no such app yet.
Installed apps
path(bundleID: string): string | null
Where the app with that bundle ID is installed, such as "/Applications/Safari.app", or null when Launch Services knows no such app. The app does not have to be running.
info(path: string): { bundleID, name, version, build, path } | null
Reads the app bundle at path. version is the version users see (CFBundleShortVersionString) and build the build number (CFBundleVersion); either is null when the bundle does not declare it. Returns null when path is not a bundle. Each call reads the bundle from disk, so an app that has updated reports its new version.
const path = macotron.app.path("com.apple.Safari");
const info = path && macotron.app.info(path);
console.log(info?.name, info?.version);
For other keys in an app's Info.plist, read it with macotron.plist.
Launching and switching
launch(bundleID: string): boolean
Brings the app to the front, opening it first if it is not running. When the app is already running with windows, Macotron activates it directly, which is fast. A menu bar app goes through Launch Services instead, so it gets the reopen event it uses to show its window or panel.
It returns false when no app with that bundle ID is installed, and true otherwise.
switch(bundleID: string): boolean
The same as launch().
Hiding and quitting
Omit the bundle ID to act on the frontmost app. Macotron never counts itself as the frontmost app here.
hide(bundleID?: string): boolean
Hides the app, like Command-H. Returns false when the app is not running.
quit(bundleID?: string): boolean
Asks the app to quit, like Command-Q. The app can still show a save dialog or refuse. Returns false when the app is not running or does not accept the request.
Menus
menu(path: string[], bundleID?: string): boolean
Chooses a menu bar item, such as ["File", "New Window"]. Omit the bundle ID to use the frontmost app.
Each name must match the item's title exactly, in the app's language. A trailing … or ... is optional, so "Save As" matches Save As…. Returns true when the item was pressed, and false when the app is not running or a name in the path does not match.
menu() needs Accessibility permission. Without it, every call returns false.
macotron.app.menu(["View", "Enter Full Screen"], "com.apple.Safari");
Events
All three events carry { name, bundleID, pid }. None fires for Macotron itself.
app:activated
Fires when an app comes to the front.
app:launched
Fires when an app starts.
app:terminated
Fires when an app quits.
macotron.on("app:activated", ({ bundleID }) => {
if (bundleID === "com.apple.dt.Xcode") macotron.notify.toast("Focus time");
});
See also
- macotron.window to move and focus windows.
- macotron.ax for other Accessibility work.
- The
focus-idle.jsplugin, which reacts toapp:activated.