Has anyone found a way to ascertain the current Focus Mode status via any method short of using Keyboard Maestro to read the pixels of Control Center?
@RosemaryOrchard was using a change in focus to set a variable in Data Jar via a Shortcut automation. That data can then be referenced. You could write to an alternate location if required by your script of choice.
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.)
On i*OS you can trigger a shortcut when a focus mode is enabled/disabled.
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.
Wow! Thatās very clever but also awful.
Agreed. It should be a built in action.
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.
Thanks and youāre welcome.
Cool! Thanks to @jsnell too - Iām glad itās helpful. It was a fun little puzzle for me to learn a bit more JXA as well.
Whatās especially nice about @akerrās script is that it teaches us how to get the focus mode using any language. The code is very clear.
@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.
Hereās another handy tip that I just learned today:
defaults read com.apple.controlcenter "NSStatusItem Visible FocusModes"
If that returns 0
then there is no focus mode on.
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.
Any chance to set the focus mode via script?
Welcome! Probably easiest by creating a Shortcut with the Set Focus action and running with shortcuts
.
Thank you akerr! This is greatā¦
Hi! First post hereā¦just made an account to thank @akerr and all the others pitching in. Hereās the icloud link to the Shortcut I made with your help:
iCloud Shortcut: Toggle Focus Mode
It checks whether thereās a Focus Mode running. If there is, it turns focus off. If itās off, it prompts you to select which Mode you want to turn on.
I finally used this in BetterTouchTool on a button for the TouchBar.
OH THIS IS PERFECT TIMING!
I just made a Stream Deck / Keyboard Maestro button for showing what is the current active Focus Mode, if any.
The next step was going to be how to do exactly what this Shortcut does.
Once I have a chance to test it a bit more, I will release it for the community to use.