Relieving Eye Strain through Better Scripting
Every time I get a new computer, I rewrite an application to remind myself
to take a break every 20 minutes. You see, I suffer from eye strain from
concentrating on the tiny little letters glowing on this monitor. This
unnatural situation really affects my vision, so I try to take a 30 second
break every 20 minutes or so.
But who can remember something that when you are busy debugging some
cryptic error message?
With the addition of this Mac, I decided to rewrite my EyeBreak
application. Why rewrite? I don't know, I guess I've never written it to my
satisfaction. Besides, it is such a simple program… why not try different
techniques?
Here's what I want… I want some annoying thing to show up in front of my
working environment that forces me to stop what I am doing. Once I make it
go away and take my break, I want to return to my running application…
but do it all over again in 20 minutes.
AppleScript
I'm intrigued with AppleScript… granted, I haven't used it enough to be
very proficient, but I love the idea that all my GUI applications are
scriptable. So, something like the following seems like it would work:
repeat
tell application "Finder"
activate
display dialog "OK… Time to take a break!"
delay 20 * 60
end tell
end repeat
However, I haven't tried it out because AppleScripts, when they are
running, show an icon in the Dock. And as you can tell, this will be
running forever… and if you are like me, your Dock is already so full of
icons that you can't find the one you're after.
Shell Script
But "Unix" scripts don't add an icon in the Dock. So, let's cobble up a
quite shell script to do the work:
while :
do
osascript -e 'say "Time to look away!" '
osascript -e 'tell application "Finder"' \
-e "activate" \
-e 'display dialog "Time! Look away!" ' \
-e 'end tell'
sleep 1200
done
This works by basically executing AppleScript commands (using the
osascript
command) and is very similar to the AppleScript
version above. Oh, and keep in mind that I use the '\' character to
indicate that I've broken the command line to be more readable for you,
gentle reader … but you'll can put them all on one line if you want.
But we have a problem with this script.
See that line that says activate
? If we have it in, then the "Finder"
becomes the foreground task. This means that if I push the "Return" key to
close the dialog, I still have to do something (like a mouse click) to
return to my originally foreground application.
But if I take it out, then the dialog box shows up behind the
other windows. That is even worse. However, we have another solution.
Perl Script
Perl is, by far, my favorite scripting language, and having it run on my
Mac is just glorious. What's more is there is some slick Mac-specific stuff
that I can do … like pop up a dialog box without resorting to asking the
Finder to that.
The downside is that you have to install the MacPerl library extensions
(yes, why aren't those installed by default). But once you've done that, you
now have a beautiful program that annoys you every 20 minutes:
use MacPerl;
use Mac::Speech;
$message = "Time to take a break!";
$backtowork = "O.K. Back to work.";
$breaktime = 20 * 60;
while (1) # Loop forever and ever
{
SpeakString($message); # Alert me verbally
MacPerl::Answer("$message");
# Don't continue unless it has stopped speaking.
sleep 1 while SpeechBusy();
sleep 30; # Sleep for duration of our break
SpeakString($backtowork); # Tell me break is over
sleep 1 while SpeechBusy(); # Wait for voice to stop
sleep $breaktime; # Sleep for 20 minutes until
} # the next break.
Starting it Up
Now the problem is just … well, starting up a command line program. Sure,
I could, after logging onto my Mac, fire up iTerm or my Terminal window and
run the perl script … but if I can't remember to look away, then how will
I ever remember to start it up?
First, I could put the script in my /Library/Scripts
folder and start
that up from the AppleScript menu. What would be nice is to add this script
to the "Startup Items" (you know, System Preferences -> Accounts). Too
bad that doesn't work they way you'd expect it.
Oops, excuse me, I was just reminded to take a break.
Update
Let's update the program a bit … doesn't this happen to every program?
You think of a nice thing and pretty soon, your simple 6 line script has
turned into a huge perl monster with big, pointy teeth.
But I noticed that if I put it on my scripting menu and ran it more than
once… well, let's just say I get a lot more breaks then.
So I modified the script to be a little smarter and allow you to actually
run the script multiple times, and each time, it just resets the timer …
and tells you so.
Download EyeBreak and save it as "EyeBreak" in your ~/Library/Scripts
folder. To get it to actually work, you have to do one more thing, and sorry
I don't know of any better solution but the geeky way. Open the "Terminal"
program and type the following:
cd Library/Scripts
chmod a+x EyeBreak
If you put it in the global Library directory, then put a single '/'
character in front of the word, Library, so it becomes:
cd /Library/Scripts
chmod a+x EyeBreak
Yeah, I haven't figured out how to use Finder to tell the system that a
text file really is a Unix script. But if you do this, you'll feel so much
more geeky, and isn't that what its all about?
One last thing … you might want to download this script and save it in
your Library/Scripts
folder as EyeBreak Stop. Yes, you'll need to issue
the following as well:
cd ~/Library/Scripts
chmod a+x 'EyeBreak Stop'
And now, you have a script that will stop the previous one from executing.
Tell others about this article: