Help - scripting with applescript & shell script

I use the App Focus for my "Do not Disturb" settings and have created something with scripts.
Since I am a beginner in scripting, I would be very happy if someone could tell me if this is all so right:

do shell script "open focus://focus"
delay 2.5
set curVolume to get volume settings
if output muted of curVolume is false then
   set volume with output muted
else
   set volume without output muted
end if
delay 1
tell application "System Events"
   activate
   set theTime to text returned of (display dialog "Wie lange soll es aktiviert bleiben?" with title "Focus App" default answer "" buttons {"Cancel", "Start"} default button 2)
   delay theTime * 60
end tell
set curVolume to get volume settings
if output muted of curVolume is false then
   set volume with output muted
else
   set volume without output muted
end if
delay 1.5
do shell script "open focus://unfocus"
delay 2
tell application "System Events"
   keystroke "d" using {command down, option down}
   delay 6
   keystroke "d" using {command down, option down}
end tell

The script works perfectly. I just don't know if it's in the right shape.
I'm grateful for any help.

I've included your script below, in which I've added some annotations on how it may be improved. I've commented out using a hashtag (#) lines of code that belong to you, for which I've substituted a suggested improvement. I will have included a short explanation, and these lines begin with --. Feel free to change or disregard what you please:

Here's the adjusted script without the comments and slightly re-ordered to make a bit more logical but without actually affecting the functioning in any way:

set volume output muted (not output muted of (get volume settings))

set theTime to text returned of ¬
	(display dialog ("Wie lange soll es aktiviert bleiben?") ¬
		with title ("Focus App") ¬
		default answer ("") ¬
		buttons {"Cancel", "Start"} ¬
		default button 2)

open location "focus://focus"
delay theTime * 60
open location "focus://unfocus"

set volume output muted (not output muted of (get volume settings))
tell application "System Events" to set autohide of dock preferences to false
-- OR: tell application "System Events" to tell dock preferences to set autohide to not autohide
1 Like

thank you very much @CJK for your feedback :clap::+1:
Your script works fine. I had made a lot of things very cumbersome.

I made a change to the dock. The dock is hidden by default. It should only be displayed for a few seconds when "Focus" is closed, so that I can see whether there are any messages/messages (badges).

I still have one request for you. I have extended your script by the possibilities:

  • Hide the desktop items
  • activate the "Do not Disturb" mode

Is my addition of the form properly designed? I would like to thank you for your suggestions.

set volume output muted (not output muted of (get volume settings))

set spacechar to ASCII character 32
do shell script "ls -Ol ~/Desktop/" -- Read chflags in ls
if result contains "staff" & spacechar & spacechar & "hidden" then
do shell script "chflags nohidden ~/Desktop/"
else
do shell script "chflags hidden ~/Desktop/
"
end if

tell application "System Events" to tell process "SystemUIServer"
key down option
click menu bar item 1 of menu bar 1
key up option
end tell

set theTime to text returned of ¬
(display dialog ("Wie lange soll es aktiviert bleiben?") ¬
with title ("Focus App") ¬
default answer ("") ¬
buttons {"Cancel", "Start"} ¬
default button 2)

open location "focus://focus"
delay theTime * 60
open location "focus://unfocus"

set volume output muted (not output muted of (get volume settings))

set spacechar to ASCII character 32
do shell script "ls -Ol ~/Desktop/" -- Read chflags in ls
if result contains "staff" & spacechar & spacechar & "hidden" then
do shell script "chflags nohidden ~/Desktop/"
else
do shell script "chflags hidden ~/Desktop/
"
end if

tell application "System Events" to tell process "SystemUIServer"
key down option
click menu bar item 1 of menu bar 1
key up option
end tell

tell application "System Events" to set autohide of dock preferences to false
delay 7
tell application "System Events" to set autohide of dock preferences to true

Only a couple of small adjustments, as it was a big improvement over your first script. You've employed some fairly advanced AppleScript techniques, which is quite impressive.

Again, the lines of original code that I have changed are commented out with #, but this time I've decided to add my annotations in regular text below each change, splitting the code up into chunks as I go:

# set volume output muted (not output muted of (get volume settings))
set volume with output muted

My assumption now is that, while you are "focussed", you want distractions minimised, and therefore computer sound to be OFF. Therefore, it didn't make sense to toggle the sound, in case it was already muted to begin with.

# set spacechar to ASCII character 32 -- Not needed

There's a builtin constant for ASCII character 32 called space. So, in the following line, you could have written if result contains "staff" & space & space & "hidden" then, although you could just as easily write it using actual spaces, i.e. if result contains "staff hidden" then. However, I've removed that line altogether.

# do shell script "ls -Ol ~/Desktop/" -- Read chflags in ls
# if result contains "staff" & spacechar & spacechar & "hidden" then
# do shell script "chflags nohidden ~/Desktop/ <em>"
# else
# do shell script "chflags hidden ~/Desktop/</em> "
# end if
do shell script "ls -Ol ~/Desktop | egrep -i 'staff\\s+hidden\\s+\\d+' " & ¬
	"&& chflags nohidden ~/Desktop/* || chflags hidden ~/Desktop/*"

It seems like you were trying to hide the desktop items, however your present code wasn't doing this because you missed off a * at the end of the chflags commands, indicating that you want the settings to apply to the contents of ~/Desktop/* rather than the folder itself (attempting to hide the folder doesn't hide the items it contains).

Additionally, rather than call do shell script twice, I combined the whole 6 lines of AppleScript into a single line of bash script that carries out exactly the same toggling of desktop item visibilities.

However, as earlier, I'm not sure if toggling is the action you want to perform. Am I right in thinking that you want to hide the items at the start of your focus period, then show them again when the focus period has ended ? If so, replace my do shell script line with this one instead:

do shell script "chflags hidden ~/Desktop/*"

Nothing more than that is required.

tell application "System Events" to tell process "SystemUIServer"
key down option
click menu bar item 1 of menu bar 1
key up option
end tell

set theTime to text returned of ¬
(display dialog ("Wie lange soll es aktiviert bleiben?") ¬
with title ("Focus App") ¬
default answer ("") ¬
buttons {"Cancel", "Start"} ¬
default button 2)

open location "focus://focus"
delay theTime * 60
open location "focus://unfocus"

# set volume output muted (not output muted of (get volume settings))
set volume without output muted

Again, I'm assuming that, after your focus period has finished, you'll want the sound back on, in which case that new edit is more appropriate than the toggling of volume.

# set spacechar to ASCII character 32
# do shell script "ls -Ol ~/Desktop/" -- Read chflags in ls
# if result contains "staff" &amp; spacechar &amp; spacechar &amp; "hidden" then
# do shell script "chflags nohidden ~/Desktop/ <em>"
# else
# do shell script "chflags hidden ~/Desktop/</em> "
# end if
do shell script "chflags nohidden ~/Desktop/*"

Same as before, but this line will unhide the desktop items. If you want them toggled instead, you can use the other do shell script command I included earlier, namely:

do shell script "ls -Ol ~/Desktop | egrep -i 'staff\\s+hidden\\s+\\d+' " & ¬
	"&& chflags nohidden ~/Desktop/* || chflags hidden ~/Desktop/*"

Also, you had declared set spacechar to ASCII character 32 for a second time, which is redundant. Generally speaking, if you've set a variable once in the script, and you're not changing its value, you don't need to set it a second time (provided you're in the same scope as the first variable declaration).

tell application "System Events" # to tell process "SystemUIServer"
    key down option
    click menu bar item 1 of menu bar 1 of process "SystemUIServer"
    key up option
# end tell

# tell application "System Events" to set autohide of dock preferences to false
    set autohide of dock preferences to false
    delay 7
# tell application "System Events" to set autohide of dock preferences to true
    set autohide of dock preferences to true
end tell

All I did there was to combine the remaining lines into a single block, given that they were all commands that were being sent to System Events.


So the final script with my suggested edits in place, looks like this:

set volume with output muted -- mute volume
do shell script "chflags hidden ~/Desktop/*" -- hide desktop icons
tell application "System Events" to tell process "SystemUIServer"
	key down option
	click menu bar item 1 of menu bar 1 --toggle do not disturb
	key up option
end tell

set theTime to text returned of ¬
	(display dialog ("Wie lange soll es aktiviert bleiben?") ¬
		with title ("Focus App") ¬
		default answer ("") ¬
		buttons {"Cancel", "Start"} ¬
		default button 2)

open location "focus://focus" -- start focus
delay theTime * 60
open location "focus://unfocus" -- stop focus

set volume without output muted -- unmute volume
do shell script "chflags nohidden ~/Desktop/*" -- unhide desktop icons
tell application "System Events"
	key down option
	click menu bar item 1 of menu bar 1 of process "SystemUIServer"
	key up option
	
	set autohide of dock preferences to false -- show dock
	delay 7
	set autohide of dock preferences to true -- hide dock
end tell

And, finally, hiding the desktop icons doesn't affect the hard disks visible on the desktop. I wasn't sure whether you wanted those specifically to remain visible, or whether you'd prefer them to be hidden as well, to produce a completely empty desktop. If you'd like to be able to hide everything, include the disk drives, then you can use this line of code in place of the do shell script lines currently being used:

do shell script "defaults write com.apple.finder " & ¬
	"CreateDesktop -bool false; " & ¬
	"killall Finder"

That will hide the desktop icons and disk drives; to show them again, use exactly the same line but replace false with true.

1 Like

wowwww... I didn't expect such a detailed explanation. I am very grateful to you for the time you have taken :+1:

Your assumptions were right. I want to hide icons and hard drives when activating the Focus App. By deactivating the sound and activating the Do not Disturb I then have a really trouble-free working mode.

My script was running too, but I didn't feel good about it.
Thank you again for your comments.