think logo

Site Info

Categories

Archives

Meta

Geo

Museum

Recent Posts

Recent Comments

 

March 2011
S M T W T F S
« Feb   May »
 12345
6789101112
13141516171819
20212223242526
2728293031  

Mac OS X user idle time in Python

March 3, 2011

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()

Spotlight for coders

March 1, 2011

Apologies to everyone who already knew this…

I just discovered something very cool. As an only occasional coder (Python, mostly, when I get the chance to write code), I don’t have a very good grasp of where all the header files for Mac OS X frameworks live.

Let’s say that you want to know where CGEventSourceSecondsSinceLastEventType is defined. Just hunt for it in Spotlight and it will turn up all the places it shows up in header files.

E.g.

/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs /iPhoneSimulator3.2.sdk/System/Library/Frameworks/ApplicationServices.framework /Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Headers

Or

/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks /IOKit.framework/Versions/A/Headers/hidsystem

Clicking on the Spotlight results opens the file in Xcode.

Who knew?