Introduction

Overview

Talon aims to bring programming, realtime video gaming, command line, and full desktop computer proficiency to people who have limited or no use of their hands, and vastly improve productivity and wow-factor of anyone who can use a computer.

Join the Slack to talk, get hyped, or for help with the public beta.

Beta Info:

  • Requires macOS El Capitan (10.11) or newer. Windows/Linux support is on the feature roadmap.
  • Powerful voice control (can use Dragon 6, or a free speech recognition engine that comes with Talon).
  • Multiple algorithms for eye tracking mouse control (depends on a single Tobii 4C).
  • Noise recognition system (pop and hiss).
  • Scriptable with Python 3.5 (via embedded pypy).
  • Talon will run fine without an eye tracker, or if you don’t have a speech recognition engine set up. Only the respective features will fail to work in that case.

Getting Started

  1. Install Talon.
  2. Run the Talon app.
  3. Add some scripts to ~/.talon/user to add voice commands and other behaviour to Talon (see the Getting Scripts section below).
  4. If you have Dragon, start it up and then say “Go to sleep”. If you don’t have Dragon, there is a builtin free engine that is enabled by default when you install a language from the Speech Recognition menu.
  5. Run tail -f ~/.talon/talon.log in a terminal for debug output.
  6. Further reading (outdated): Dwighthouse’s Unofficial Docs.

Using the Talon REPL

While Talon is running, it provides a REPL. You can connect by running:

~/.talon/.venv/bin/repl

Getting Scripts

If you would like to get started quickly, you can clone the entire community repository into your ~/.talon/user directory: talon_community.

If you would like minimal official examples to explore the different APIs for writing your own code, take a look at Official Examples.

API Reference

(incomplete)

talon.app

app.notify(title: str, subtitle: str, body: str, sound: bool)

Display a desktop notification, optionally playing a sound.

from talon import app

app.notify(body='Hello world')
app.notify('Hello world',
           'Welcome to Talon',
           'Enjoy your stay.', sound=True)

talon.applescript

applescript.check(source: str)

Check AppleScript source for syntax errors. Raises applescript.ApplescriptErr.

applescript.run(source: str) → str

Run AppleScript source. Raises applescript.ApplescriptErr on error. Returns a raw AppleScript encoding of the script’s result.

from talon import applescript

applescript.run(r'''
tell application "System Events"
    display notification "Hello world."
end tell
''')

talon.audio

noise.register(topic, cb: function)

Register a noise callback. Valid topics:

  • "" - an empty string registers the callback for all noises.
  • "hiss_start"
  • "hiss_end"
  • "pop"
noise.unregister(topic: str, cb: function)

Unregister a noise callback.

from talon import audio

def on_noise(noise):
    print(noise)
audio.noise.register('', on_noise)

talon.clip

System clipboard interface.

clip.get() → str

Get the contents of the clipboard.

clip.set(contents: str)

Set the contents of the clipboard.

clip.serial() → int

The clipboard serial increments on each clipboard update and can be used to see if the clipboard has changed.

clip.await_change(timeout=0.5, serial=None) → str

Wait for the clipboard contents to change and return the new contents.

Parameters:
  • timeout (float) – if the clipboard hasn’t changed after this many seconds, returns None
  • serial (int) – if not provided, defaults to serial()
Return type:

str or None

from talon import clip

s = clip.get()
print(s)
s = clip.await_change()
print(s)
clip.set(s.upper() + ' clipboard test')

talon.ctrl

ctrl.key_press(key, ...)

Simulate a key press. To press and hold, pass down=True. To release, pass up=True

Parameters:
  • key (str) – The key to press. Can be any symbol your keyboard can type, as well as any special key from Key Names.
  • cmd, shift, ctrl, alt, fn (bool) – modifier keys to apply
  • down, up (bool) – hold or release the key
  • hold (int) – duration in microseconds to hold the key down
  • wait (int) – duration in microseconds to wait between key presses
ctrl.mouse(x, y, dx=0, dy=0)

Move the mouse.

Parameters:
  • x, y (int) – absolute mouse position
  • dx, dy (int) – relative mouse movement
mouse_pos -> (x, y)

Get the cursor’s current position.

ctrl.mouse_click(x=None, y=None, button=0, times=1, ...)

Click the mouse. If x and y are not None, click at coordinates (x, y). Otherwise, click at the current mouse position.

Parameters:
  • x, y (int) – absolute mouse position, can be omitted to click in the current position
  • button (int) – 0 is left click, 1 is right, 2 is middle, 3+ are additional mouse buttons
  • times (int) –
  • down, up (bool) – hold or release the button
  • hold (int) – duration in microseconds to hold the mouse button
  • wait (int) – duration in microseconds to wait between clicks
mouse_buttons_down -> list

Returns which mouse buttons are currently pressed as a list of numbers starting with 0.

ctrl.mouse_scroll(y=0, x=0)
Parameters:
  • y (int) – vertical distance (positive values move down)
  • x (int) – horizontal distance (positive values move right)
from talon import ctrl

ctrl.key_press()
Key Names
Name Alternate
alt  
backspace bksp
capslock  
cmd  
ctrl  
delete del
down  
end  
escape esc
f1  
f2  
f3  
f4  
f5  
f6  
f7  
f8  
f9  
f10  
f11  
f12  
f13  
f14  
f15  
f16  
f17  
f18  
f19  
f20  
fn  
help  
home  
left  
mute  
pageup pgup
pagedown pgdown
return  
enter  
right  
ralt  
rctrl  
rshift  
shift  
space  
tab  
up  
voldown  
volup  
keypad_clear  
keypad_enter  
keypad_decimal  
keypad_plus  
keypad_divide  
keypad_minus  
keypad_equals  
keypad_0  
keypad_1  
keypad_2  
keypad_3  
keypad_4  
keypad_5  
keypad_6  
keypad_7  
keypad_8  
keypad_9  

talon.fs

fs.watch(path, cb)

Watch path for changes and call cb(path: str, exists: bool) when they occur.

fs.unwatch(path, cb)

Remove cb from the set of callbacks being watched for path.

from talon import fs

def on_change(path, exists):
    if exists:
        print('changed', path)
    else:
        print('deleted', path)

fs.watch('/path/to/stuff', on_change)

Indices and tables