I’m still on the quest for the perfect free kiosk app for Mac OS X. I’ve used Plainview to good effect in several exhibits. I’ve used Opera in one, and I’m using Firefox with R-Kiosk in another. Which program to use depends a lot on the nature of the web page(s) to be displayed in the kiosk and the way the user expects to interact with the kiosk.
For the Firefox kiosk, I needed a sure-fire way to reload the home page after a certain amount of idle time. The trouble is that Firefox doesn’t lend itself to be controlled via AppleScript. A lot of poking around led me to learn about AppleScript System Events being able to simulate a keypress, that Option-Home will make Firefox load the home page, and that there’s a really handy little application called Full Key Codes that tells you what the key code is for any key you press on a Mac.
That let me put together this handy little Python script that watches how long it’s been since a user has done something. First it waits until there’s been any user activity at all, then it waits until there’s been no activity for 90 seconds. Then it uses osascript to run a little bit of AppleScript that sends Option-Home (key code 115) to Firefox.
I suspect there’s a way to eliminate the osascript by using the Python objc module, but this is good enough for me…
#!/usr/bin/env python #======================================================================== # # idle.py - makes Firefox load home page after user inactivity # # Set the value of 'timeout' to the number of seconds of idle # time you want to allow before reloading the home page # # Comment out the calls to status() if you don't want to see any # messages # #======================================================================== from subprocess import Popen from time import sleep from Quartz.CoreGraphics import * # From /System/Library/Frameworks/IOKit.framework/Versions/A/Headers/hidsystem/IOLLEvent.h NX_ALLEVENTS = int(4294967295) # 32-bits, all on. # Set this value to the number of seconds of idle time before # resetting Firefox timeout = 90.0 def status(state, last, idle): """Print out some info about where we are """ print "%10s %.1f %.1f" % (state, last, idle) def getIdleTime(): """Get number of seconds since last user input""" idle = CGEventSourceSecondsSinceLastEventType(1, NX_ALLEVENTS) return idle def doReset(): """Use osascript to tell Firefox to reload the home page""" reset = """/usr/bin/osascript \ -e 'tell application "Firefox"' \ -e ' activate' \ -e 'end tell' \ -e 'tell application "System Events"' \ -e ' key code 115 using option down' \ -e 'end tell' """ Popen(reset, shell=True) sleep(1) # Prevent osascript keypress from triggering below last = 0.0 idle = 0.0 while True: # These two lines can also be at the very end if you don't want to # load the home page once when the program starts status('--- RESET', last, idle) doReset() idle = getIdleTime() last = idle # Wait for user activity while idle >= last: status('wait', last, idle) sleep(1) idle = getIdleTime() # Wait for idle to become bigger than timeout while idle < timeout: status('triggered', last, idle) sleep(1) idle = getIdleTime()
