Hmm, unfortunately that solution seems to be “if you always set your focus mode with a shortcut you can also write that status somewhere and read it later,” which is not really what I mean. I’m looking for a standalone way to detect the current focus mode on macOS Monterey…
(I should also note that on macOS, you can’t set an automation to run when Focus mode changes.)
I believe focus modes sync across devices, so setting the focus mode on the Mac can set it on another device, which can trigger the shortcut automation. This can then be used to set your own indicator, which can be synced across devices and then queried on the Mac.
This is the case I use. I actually set these automations up on my Pushcut automation server, because that will never bother me by running extra automations.
I was looking for this too and, after some digging, ended up writing the following in Javascript for Automation (JXA). It works with the JXA action in Shortcuts and should work in Keyboard Maestro, Alfred, Script Editor, Automator, osascript etc. The output is the name of the current focus mode, if any.
const app = Application.currentApplication()
app.includeStandardAdditions = true
function getJSON(path) {
const fullPath = path.replace(/^~/, app.pathTo('home folder'))
const contents = app.read(fullPath)
return JSON.parse(contents)
}
function run() {
let focus = "No focus" // default
const assert = getJSON("~/Library/DoNotDisturb/DB/Assertions.json").data[0].storeAssertionRecords
const config = getJSON("~/Library/DoNotDisturb/DB/ModeConfigurations.json").data[0].modeConfigurations
if (assert) { // focus set manually
const modeid = assert[0].assertionDetails.assertionDetailsModeIdentifier
focus = config[modeid].mode.name
} else { // focus set by trigger
const date = new Date
const now = date.getHours() * 60 + date.getMinutes()
for (const modeid in config) {
const triggers = config[modeid].triggers.triggers[0]
if (triggers && triggers.enabledSetting == 2) {
const start = triggers.timePeriodStartTimeHour * 60 + triggers.timePeriodStartTimeMinute
const end = triggers.timePeriodEndTimeHour * 60 + triggers.timePeriodEndTimeMinute
if (start < end) {
if (now >= start && now < end) {
focus = config[modeid].mode.name
}
} else if (start > end) { // includes midnight
if (now >= start || now < end) {
focus = config[modeid].mode.name
}
}
}
}
}
return focus
}
THANK YOU! This is awesome, and just what I was hoping was built-in to macOS.
Edited to Add
For those new to jxa, you can save this in Script Editor, just be sure to change the language to “JavaScript” at the top of the window. It can then be saved as a .scpt file.
If you want to use it with osascript without making a .scpt file, then you have to use the -l (That’s a lowercase -L) flag and specify the language, as osascript assumes plain-text is AppleScript. For example, I put the code into a plain-text file named whichfocus.jxa and ran it like this:
osascript -l JavaScript ./whichfocus.jxa
and it worked great.
Andrew - you might consider posting this as a Github gist so others can discover it.
@akerr 's script is super useful. If it is helpful to anyone, the solution I’ve been using is to just have a value in data jar that I update using shortcuts automation any time the focus mode changes. Then I can do automation with that.
If that returns 1 then there is some focus mode on.
Still need @akerr’s solution if you want to know which Focus Mode is on, but if you are just looking to turn something on or off, knowing the current ‘general’ state might be sufficient.
This is also useful for telling of your attempt at turning a focus mode on was successful or not. Check the defaults read after, and make sure that it says 1 and you know that something turned on at least.
I’d still love to find a simple shell-script friendly way to get the name of the Focus Mode, but for the time being I just made a wrapper script around the JXA solution.
New to this community, and TIL there’s a command line to run Shortcuts. That’s most excellent! I use ToothFairy to quickly connect to my AirPods—which I pretty much only have in my ears if I’m in a Zoom meeting—and now I can automatically set my Focus mode to Work when my AirPods connect.