Howardism Musings from my Awakening Dementia
My collected thoughts flamed by hubris
Home PageSend Comment

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:
Click here to submit this page to Stumble It