Zephyros Racket API

In the recent past, I wanted to control the OS X window manager from racket like I could on Linux using the X11 library. I found a very sweet Github project called zephyros that implemented a large number of vital routines (vital for managing windows anyway) and provided a simple protocol using json. Since it would be convenient to have a racket module, I wrote a wrapper around it.

The zephyros protocol has the following format:

routine_name receiver args*

A routine_name is something like “move_window”. A receiver is an object identifier that we are trying to instruct (so if we want to move window 1 to location (x, y), the API call looks like (move-window 1 ’(x y))). The receiver is typically null for routines that cause no state change.

So, our racket API calls look like:

(routine-name receiver args*)

The zephyros API is asynchronous but I prefer having nothing to do with this callback business so routines that return a response are exposed as functions that return values.

There is a general pattern to the routines defined: send a message with the right arguments, poll for a response if there is any and return the response (or perform the right state changes). So, we have this macro that takes a protocol string and a list of symbols corresponding to the args and then defines a function.

And this exports a function clipboard-contents that can be invoked like so (clipboard-contents).

Using macros that look a lot like this I was able to define routines that perform an action, return values, poll for events and build a clean API that exports zephyros functionality. You can see the final codebase here.