May 162008
 


I just bought a cheap Frisby illuminated keyboard on eBay. Not only is it illuminated, but it has a scrollwheel, volume knob, and like 20 extra buttons (in addition to the usual 16 or so function keys). The only thing it lacks is indicator lights for the Caps Lock, Num Lock, and Scroll Lock keys.

When I first plugged it into my Mac, it didn’t work. Well, actually, it did. In fact, the scroll wheel, volume knob, and mute button all “just worked”. But the keyboard wouldn’t light up. The instructions that came with the keyboard (all 1/8 page of them) indicated that the Scroll Lock key was the On/Off switch for the keyboard’s backlight. Pushing it didn’t do anything, even when pressed in combo with Shift, Ctrl, Alt, Windows/Command, or any gaggle of the above. But, when I first plugged the keyboard into the USB port (or into a powered USB hub), it did light up for about 1/2 second or so. What was going on?

A lot of googling led me to believe that this problem is fairly common on Macs, Linux PCs, and even under Windows, although not many people have found a solution.

Here’s apparently what’s going on: The Frisby keyboard (along with many other budget illuminated keyboards) uses the Scroll Lock key as a switch for the backlight because it essentially replaces the Scroll Lock indicator light with the entire keyboard backlight. At first glance, this seems like a clever idea, except for a couple of problems: Some applications (Excel for one) and gadgets (many low-price KVM switches) also make use of the Scroll Lock key, and expect it to be available. Worse, some operating systems (Mac OS X mainly) don’t really know about or care about the Scroll Lock key and don’t support it; OS X doesn’t keep track of the Scroll Lock’s on/off toggle state, and doesn’t tell the keyboard to turn the Scroll Lock LED on and off. So, when the Frisby keyboard is hooked up to a Mac, pressing the Scroll Lock key is ignored by OS X, and thus OS X never tells the keyboard to turn the backlight on. Doh.

Well, once I figured this out, I was faced with a choice: return the keyboard for a refund, or try to figure out how to get the Mac to support the Scroll Lock key. As with many eBay bargains, the price of the keyboard wasn’t much more than the shipping cost, so if I paid for the shipping to return it, I’d only net a few bucks after getting my refund. So, that was enough of an excuse for me to start hacking away at the problem.

After many false starts and dead ends, I stumbled across a wonderful product called ControllerMate. CM plugs into OS X and allows it to see inputs from various USB gadgets like joysticks and game controllers. CM also supports all of the standard keys and buttons from USB keyboards and mice, plus a ton of esoteric ones. It uses a “connect the blocks” graphical design system to let you assign key / button presses to various sorts of actions, including things like: running AppleScript scripts; telling keyboard lights to turn on and off (!); sending single keystrokes (in other words, remapping keys on the keyboard–handy for Windows-Mac “switchers” and those with keyboards that are missing some of the function keys); sending strings of key presses, mouse movements/clicks, and delays (shades of QuicKeys, which it would be an excellent adjunct to); application launches; and nifty add-ons like logic and arithmetic. ControllerMate is free to try out, and $15 to buy, which is an incredible bargain.

I was able to use ControllerMate to build a simple connection of three blocks:

Scroll Lock keypress
|
V
“Toggle” Logic Block
|
V
Scroll Lock Light on / off.

ControllerMate then runs in the background under OS X, watches the Scroll Lock key, keeps track of it’s on/off state with the “Toggle”, and tells the keyboard’s Scroll Lock light (aka the keyboard backlight) to stay on after I press the Scroll Lock key, then stay off after I press it again. In other words, to make the Mac treat the Scroll Lock key like a Windows PC does. Problem solved!

I also used CM to program functions for all of the zillion extra buttons the keyboard has. Some of the buttons were simple. For example, I made the button with a picture of a calculator on it tell the Finder to launch the Calculator app. Others are a little more complicated. For example, the Play/Pause button tells the Finder to launch iTunes (or select iTunes if it is already running), and then sends a “spacebar” keystroke, which is what iTunes uses for play/pause. This way, the Play/Pause button works correctly even if I press it while running another application.

The one button that stumped me so far is the “Email” button. I’d like to have it use the Google Notifier toolbar’s menu item to “Go To Inbox”. I’ve messed around for quite a while trying to get an AppleScript script that reliably does this, but it is proving very difficult, since the name of the menu item is actually “Go to Inbox – 12 Unread”, where of course “12” changes all the time, since it’s the number of unread messages, and GN’s heirarchy of menus and items is mostly unnamed. Plus, GN’s AppleScript API doesn’t have a function / call / whatever for “Go To Inbox”.

Another AppleScripted button that seemed to work for a while but doesn’t today attempts to have the Finder open up a window with the Applications folder selected. Here’s the AppleScript script that sorta kinda sometimes works:

tell application “Finder”
activate
end tell

tell application “System Events”
tell process “Finder”
tell menu bar 1
tell menu bar item “Go”
tell menu 1
click menu item “Applications”
end tell
end tell
end tell
end tell
end tell

Anyways, the keyboard ended up having one more serious problem. It would stop responding after the Mac went to sleep and woke back up. I discovered that having CM do a USB bus probe made the keyboard work again, and didn’t seem to have any harmful side effects. So, the question became: How to tell the Mac to do some sort of USB bus probe after waking from sleep mode?

The best answer I’ve come up with so far is a hacky combination of Apple’s developer tool called “USB Prober” (included free with XCode, which is included with most–all?–Macs on the installer disks, and which lives in /Developer/Applications/Utilities), an AppleScript script that tells it to run and then immediately quit, and another nifty (and free!) application called SleepWatcher. SW runs in the background on the Mac, and is able to run shell scripts immediately before the Mac sleeps and directly after it wakes up.

So, I made the following simple AppleScript script, which I saved as an Application, turned on the “Run Only” flag, turned off the “Startup Screen” flag, and named “USBProberRunNQuit.app”:

tell application “USB Prober”
quit
end tell

tell application “USB Prober”
activate
end tell

tell application “USB Prober”
quit
end tell

It is run by a one-line shell script called “.wakeup” in my home directory:

/Users/joviko/USBProberRunNQuit.app

So, when my Mac wakes up, SleepWatcher runs the “.wakeup” script, which runs my “USBProberRunNQuit.app” AppleScript app, which runs Apple’s USB Prober app, which probes the USB bus then immediately quits, which makes the Frisby keyboard work. Simple, eh?

 Posted by at 7:57 AM