I’m trying to set up my stock Calendar to hide/show specific calendars when I change focus modes (and various other times). As far as I can tell, there is no way to do this via AppleScript (at least, not in the Calendar AppleScript dictionary in Script Editor) or through UI scripting (no menu items for it).
Does anyone know of an AppleScript, terminal command, shell script, etc that will programmatically “check” or “uncheck” a calendar’s visibility?
By figuring out the distances from the upper left corner of the window to the centers of the checkboxes and combining that with the upper left coordinates of the window, I can get AppleScript to click a box this way:
-- Coordinates of calendar checkboxes relative to the window
set xAny to 25
set yWork to 71
set yHome to yWork + 28
set yFamily to yHome + 28
set ySpecial to yFamily + 28
set yFed to ySpecial + 28
tell application "Calendar"
activate
delay 1
set calWindow to bounds of front window
end tell
set xClick to (item 1 of calWindow) + xAny
set yClick to (item 2 of calWindow) + ySpecial
tell application "System Events"
tell application process "Calendar"
click at {xClick, yClick}
end tell
end tell
This is hardly ideal, as it doesn’t check to see if the box is checked or not before clicking. Also, you have to activate Calendar.
If you have Keyboard Maestro, you can use its Click at Image action.
Thanks, @drdrang. I may try the AppleScript version. I started doing the click-at-image stuff in KM, but it got real messy real fast. (I have like 30 calendars). Especially when trying to deal with whether it was already checked or not. Seems like x/yClick or Click at Image are the only options for now. (Ideally, I would just use Fantastical’s calendar sets, but my work’s Exchange server blocks 3rd party calendar apps. )
You can select and click by row – row 3 in this example, which is the second calendar under the group “On My Mac”:
tell application "System Events"
tell application process "Calendar"
set t to checkbox 1 of UI element 1 of row 3 of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1
set v to value of t
if v = 1 then
click t
end if
end tell
end tell
Allowing you to test if the checkbox is already ticked or not – making this calendar invisible if it is already visible.
Checking each row to see if “text field 1” = your calendar name would allow a script to work even if you added and deleted calendars.
It was so long ago that I can’t remember exactly when this was… I can see lots of old scripts of mine from 2004 that targeted the UI, so think that it must have been around that time?
Followed quickly after by a number of Obj-C scripts that date from 2005.
So I was mistaken. The “exciting days” were in the previous decade!
Here, long after the fact, is a simple solution that takes a numeric keyboard shortcut from some other program (e.g., Keyboard Maestro, BetterTouchTool, Shorcuts), toggling the visibility of the nth calendar. For example, ⌘1 to toggle the first calendar.
set triggerKey to 1 --pass input from some keyboard shortcut app
tell application "System Events"
tell process "Calendar"
set calCheckboxes to checkboxes of UI elements of ¬
rows of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window "Calendar"
set calCheckboxes to my Flatten_List(calCheckboxes)
click item triggerKey of calCheckboxes
end tell
end tell
on Flatten_List(aList)
if class of aList is not list then
return {aList}
else if length of aList is 0 then
return aList
else
return Flatten_List(first item of aList) & (Flatten_List(rest of aList))
end if
end Flatten_List
tell application "System Events" to tell (process "Calendar") ¬
to tell UI elements of rows of outline 1 of scroll area 1 ¬
of splitter group 1 of splitter group 1 of window 1 ¬
to click checkbox triggerKey