Design a site like this with WordPress.com
Get started

SwiftDialog: Make Dialog the Active Window

A Simple Realization

I was playing with the open command today, and realized that open -a "AppName" will bring an application’s windows to the forefront if that application is already running.

When I’m building SwiftDialog workflows, I will often lose track of my active Dialog window as I have text editors, browsers, and Terminal windows I’ve dragged over it. Using open -a "Dialog" from any running Terminal will bring my “work in progress” Dialog window to the front of my screen.

An Idea for Using This in a Script

SwiftDialog has the --ontop or -p argument which allows you to keep a Dialog window on top of all other windows until the Dialog window is quit or dismissed, but what if you want to allow users to continue using their device, and just remind them periodically “Hey, remember that Dialog window? I’m still here!”

This might be useful for trying to get users to do something that’s not imminently urgent, but still important (reboot, save their work, provide feedback, or any of the other 100s of reasons people use the awesome SwiftDialog project.)

So how can we use the open command in a looping function so that our Dialog window keeps coming back to the forefront until the user has clicked a button?

Proof of Concept

#!/bin/zsh
# I use set -x while testing scripts to get extra-verbose output
set -x

# Define how many seconds to wait before Dialog is brought back to the foremost window
sleepTimer="5"

# Define our file paths
dialogPath="/usr/local/bin/dialog"
dialogStopFile="/var/tmp/dialogStop.log"

# Define our messaging for this proof of concept
dialogTitle="Put other windows in front of me, but..."
dialogMessage="I keep coming back every $sleepTimer seconds"

# Check if our "Stop File" already exists
# and delete it if it's already there
# Keep reading comments below for this to make sense
if [ -e "$dialogStopFile" ]; then
   rm -r "$dialogStopFile"
fi

# This function contains the primary logic of this proof of concept
function dialogFront()
{
    #Check if our "stop file" exists. Until it exists, do the things
    until [ -e "$dialogStopFile" ]; do
        # Bring our Dialog window to the front
        open -a "Dialog"
        # Wait the defined amount of time before doing it again.
        sleep "$sleepTimer"
    done
}

# Now call our function. 
# End this with an & which tells your script:
# "Don't wait for me to finish move on and keep processing more commands."
dialogFront &

# Now lets draw our actual dialog window. I use backslashes to make this more readable
$dialogPath \
--title "$dialogTitle" \
--message "$dialogMessage" \

# Our dialog window has been closed. Create our "Stop File", which will in turn break our "until" loop
touch "$dialogStopFile"

# We are done
exit 

Testing This Out

Copy/paste the code block into a script, and execute it. While the script is running, pull other windows on top of the Dialog window and hide it. Watch as it comes to the front of your screen every $sleepTimer seconds.

Writing Out a File Instead of Using a Variable

In bash/zsh, functions run in a “sub shell” and as a result, updating variables in your “main shell” does not effect the running environment of the “sub shell”. This goes both ways, and variables you set within your function or “sub shell” are not automatically brought into the running environment of your “main shell”.

There are certainly more eloquent ways of explaining this, but I’m self-taught so I don’t always know the proper nomenclature of concepts even after I have a tentative grasp of them. Here’s a StackOverflow comment that gets into a bit of detail.

I knew this would be a challenge once I started writing my proof of concept script, but I still tried using variables set later in the script to affect the “until” loop. No dice, I couldn’t get this to work. If you have a better method for this than writing a file to disk leave a comment below or message me on Slack.

SwiftDialog by Bart Reardon

If you’ve not yet come across this amazing contribution to the Mac Admins community, I strongly recommend checking it out. SwiftDialog is a way to make great looking interactive windows to give your macOS scripts a user interface and user experience. https://github.com/bartreardon/swiftDialog

I keep a set of Swift Dialog Example scripts on the Second Son Consulting github (and the proof of concept in this blog may make it’s way there in the future): https://github.com/SecondSonConsulting/swiftDialogExamples

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s