Updated to Mac OS Monterey and the Do Not Disturb touch bar button doesn't react to the changed state. The function of the button itself works but the icon on the touch bar is stuck on alternate button icon.
and help would be appreciated thanks!
Updated to Mac OS Monterey and the Do Not Disturb touch bar button doesn't react to the changed state. The function of the button itself works but the icon on the touch bar is stuck on alternate button icon.
and help would be appreciated thanks!
Bump! Anyone?
unfortunately there is currently no way to get the do not disturb state on Monterey. If I find a way I’ll update BTT to support it, but it doesn’t look like Apple included something that can be accessed by third party apps.
Thats really unfortunate Thanks for the reply!
Have you already looked here?
Where is the Focus Status API | Apple Developer Forums
Quote:
import Intents
/// Retrieve the current authorization status: INFocusStatusAuthorizationStatus
INFocusStatusCenter.default.authorizationStatus
/// Request authorization to check Focus Status
INFocusStatusCenter.default.requestAuthorization { status in
/// Provides a INFocusStatusAuthorizationStatus
}
/// Check if Focus is enabled. INFocusStatusAuthorizationStatus must be .authorized
INFocusStatusCenter.default.focusStatus.isFocused
According to the documentation, it applies to iOS 15, watchOS 8.0 and Catalyst, but the corresponding API seems to be already present on macOS 12. However, I could not retrieve a status so far (return is always: false):
use framework "Foundation"
set sc to current application's INFocusStatusCenter's defaultCenter()
return sc's focusStatus's isFocused as boolean
--> false
Apparently you have to request authorization and be registered as a communication app beforehand.
Yes, the "be registered as a communication app" part is killing it for BTT unfortunately. Apple would not approve that.
Ah wait, it seems that this is an entitlement that does not need apple approval! I was doing so much with special entitlements that need Apple approval lately, I didn't think about it being an entitlement anybody could use
In this case this might work, I'll have a look!
Here is an AppleScript which returns the current focus status.
If no focus is active, "No Focus" is returned (can be changed in the script). Otherwise the name of the active focus. Works also if the focus is set by a trigger (App, Schedule).
Note: If multiple schedules are stored that currently apply, the first focus that matches the schedule is returned.
use scripting additions
use framework "Foundation"
property ca : a reference to current application
getFocusStatus()
--> No Focus
--> Do Not Disturb
--> Personal
--> Work
--> Sleep
--> etc…
------- handler -------
on getFocusStatus()
set config to readJSONFile("~/Library/DoNotDisturb/DB/ModeConfigurations.json")'s |data|'s firstObject()'s modeConfigurations
set assert to readJSONFile("~/Library/DoNotDisturb/DB/Assertions.json")'s |data|'s firstObject()
if (assert's valueForKey:"storeAssertionRecords") is not missing value then
return (config's valueForKey:(assert's storeAssertionRecords's firstObject()'s assertionDetails's assertionDetailsModeIdentifier))'s mode's |name| as text
else
set now to ((current date)'s hours) * 60 + ((current date)'s minutes)
repeat with k in (config's allKeys()) as list
set configuration to (config's valueForKey:k)
repeat with i from 0 to ((configuration's triggers's triggers's |count|()) - 1)
set trigger to (configuration's triggers's triggers's objectAtIndex:i)
if trigger's enabledSetting as integer is 2 then
if (trigger's valueForKey:"timePeriodWeekdays") is not missing value then
if (do shell script "echo $(((" & (trigger's timePeriodWeekdays as integer) & " & ((2**($(date +%u) - 1)))) != 0))") = "1" then
set startTime to (trigger's timePeriodStartTimeHour as integer) * 60 + (trigger's timePeriodStartTimeMinute as integer)
set endTime to (trigger's timePeriodEndTimeHour as integer) * 60 + (trigger's timePeriodEndTimeMinute as integer)
if (startTime < endTime) then
if now ≥ startTime and now < endTime then
return configuration's mode's |name| as text
end if
else if (startTime > endTime) then
if now ≥ startTime or now < endTime then
return configuration's mode's |name| as text
end if
end if
end if
end if
end if
end repeat
end repeat
return "No Focus"
end if
end getFocusStatus
on readJSONFile(filePath)
set filePath to (ca's NSString's stringWithString:filePath)'s stringByExpandingTildeInPath()
set theURL to ca's NSURL's fileURLWithPath:filePath
set theData to ca's NSData's dataWithContentsOfURL:theURL
set theString to ca's NSString's alloc()'s initWithData:theData encoding:(ca's NSUTF8StringEncoding)
set {x, e} to ca's NSJSONSerialization's JSONObjectWithData:((ca's NSString's stringWithString:theString)'s dataUsingEncoding:(parent's NSUTF8StringEncoding)) options:0 |error|:(reference)
return (ca's NSArray's arrayWithObject:x)'s firstObject()
end readJSONFile
This works but something strange is going on. Using BetterTouchTool's "Toogle Do Not Disturb" action with this script does not trigger the Alternate Color Regex. The button's function itself works to toggle DND but the script only returns "Do Not Disturb" as a result if you turn on DND manually by clicking the moon -> Do Not Disturb in the menu bar.
Seems like BTT toggle is only kind of half toggling DND or something..
You are right! As far as the focus is set via the control center or a trigger (except by a schedule), then a storeAssertionRecord entry is set in the Assertions.json file. In case of a schedule, it is not set, so I go through all schedules and check if they are valid. When set by BTT, no storeAssertionRecord is set either.
I'll look later to see if I can find another meaningful entry somewhere in the files that indicates focus status.
PS: As workaround You can use a shortcut to enable the focus:
tell application "Shortcuts Events"
run shortcut "Shortcut-Name"
end tell
Really appreciate your help with this!
shortcut workaround - not quite sure how to create a Focus Mode shortcut that toggles upon run rather than just turns on or turns off...
Apple obviously forgot that too (there is no status query)! I would create two shortcuts (Focus-On and Focus-Off) and ask the script before, which one you have to take.
Or you can use this: Toggle-Focus (Shortcut)
Thanks so much for this