rkeys
v0.12.0
Published
A platform for creating tablet/HTML5 virtual-keyboard apps to send keystrokes to remote X11
Downloads
11
Maintainers
Readme
rkeys
A platform for creating tablet/HTML5 virtual-keyboard apps to send keystrokes to remote X11:
- define virtual keyboards or keypads with a bit of jade and stylus
- define chords and sequences with delays and auto-repeat
- use the built-in mixins and templates to minimise your code
- enhance with LiveScript and Font Awesome icons
- assign keys to dynamically switch layouts
- context sensitivity - show/hide regions matching the active window title
- simulate mouse buttons and run shell commands
- add sound effects: server-side or (experimental) client-side
- emit special characters using compose-key sequences
install globally
With node.js installed on the target X11 box:
$ npm install -g rkeys # might need to prefix with sudo
run examples
$ rkeys
then navigate your remote tablet to http://your-rkeys-server:7000/example
:
See this example's jade, stylus and yaml. Also see some real-world examples.
create your first keypad
An rkeys app is a directory containing at least one jade file.
Create file bar.jade
in directory foo
and add the following lines:
extend /template/keys
block layout
+key('a')
Host the app by passing its directory on the rkeys command line $ rkeys foo
then navigate your tablet to http://your-rkeys-server:7000/bar
:
keys template
Most of the time you'll be laying out sets of keys and this is where the keys template comes in handy. It extends the base template with the Font Awesome icons along with the following:
+key mixin
Generate a single key comprised of an action and some label text.
The action is a keysym with or without the XK_
prefix,
a chord denoted by infix +
symbols,
a comma-delimited sequence of keysyms and/or chords,
or a command id with optional parameters.
The label text is displayed inside the key unless it contains font awesome
class names in which case an icon is displayed.
Some examples:
+key('a')
: emit a KeyPressa
on touchstart (down) and KeyReleasea
on touchend (up). Press and hold the key for native auto-repeat.+key('%')
: emit a percent symbol. Symbols are mapped to keysyms in the core command.yaml.+key('XK_Shift_L')
: simulate the left shift key by specifying an explicit keysym.+key('Shift_L')
: as above but with the optionalXK_
prefix dropped.+key('Shift_L', 'shift')
: show a user-friendly label.+key('Shift_L shift')
: as above using a shorter syntax.+key('Shift_L fa-chevron-up')
: replace label with a nice font awesome icon. A word starting withfa-
is treated as a font awesome class. Multiple font awesome classes can be specified.+key('C+S+A+F12')
: a chord emitting the KeyPress sequenceCtrl
Shift
Alt
andF12
on touchstart, followed by KeyRelease sequence in the same order on touchend. SpecifyS+
for Shift_L+,C+
for Control_L+ andA+
for Alt_L+. Press and hold for native auto-repeat.+key('C+S+A+F12 fold all')
: as above but with a nice label.+key('VBOX-HOST+m show virtualbox menu fa-navicon')
: a chord using a custom alias, some descriptive text (not displayed) and an icon.+key('a,b,3')
: emit the keystroke sequencea
b
3
on touchstart with no auto-repeat. A keystroke is a KeyPress immediately followed by a KeyRelease.+key('a,b,3,1000')
: as above but auto-repeating every second until touchend. Integers0
to9
denote digits whereas longer integers denote time delay in milliseconds. Here the trailing delay indicates time to auto-repeat.+key('a,500,b,500,3,1000')
: as above but with interim pauses of 0.5 seconds. This might be necessary if a sequence is firing too quickly for all keystrokes to take effect, for example if a slow application needs more time to react.+key('C+A+F3,05,Super_L+a fa-gear')
: emit two chords separated by a 5 millisecond delay.+key('button:3')
: invoke the button command with parameter3
to simulate the right mouse button.+key('button:3 fa-hand-o-down fa-flip-horizontal')
: as above but with a flipped font awesome icon.+key('button:3 right mouse button fa-hand-o-down fa-flip-horizontal')
: as above but with some descriptive text (not displayed).+key('layout:fn-keys')
: switch the layout tofn-keys
across all connected clients on touchstart, reverting back to the default layout on touchend.
+keys mixin
Generate a set of keys by invoking +key
multiple times.
Accepts either a single space-delimited string of actions or a list of strings
to apply to +key
in order. Any classes or attributes are applied to each +key
.
Some examples:
+keys('a b').z
: expands to+key('a').z
+key('b').z
+keys('a b c').z
: expands to+key('a').z
+key('b').z
+key('c').z
+keys('a', 'b').z
: expands to+key('a').z
+key('b').z
+keys('a b', 'c d').z
: expands to+key('a b').z
+key('c d').z
+keys('q w e r t y')
: expands to+key('q')
+key('w')
+key('e')
+key('r')
+key('t')
+key('y')
+keys('layout:fn fn', 'Shift_R shift').w-3.latchable
: expands to+key('layout:fn fn').w-3.latchable
+key('Shift_R shift').w-3.latchable
stylus mixins and stylesheet classes
The default minimal styling is easily overridden with the following mixins and classes:
- key-color(up, label-up, down, label-down) : set the label-foreground and/or key-background colours when in the up or down states. If you only specify up and label-up then these colours are swapped on down. Call this mixin at the root level to apply to all keys or from within a selector to apply to a subset of keys.
- key-size(k, gap-percent) : a mixin to override the default key size and/or gap between keys.
- .key-cols-n :
a set of adjacent keys will normally float left but you can
apply this class to their parent to arrange them into n columns.
n can be from 1 to 9, so
.key-cols-1
will produce a single vertical column of keys. - .h-n :
apply this class to a key to multiply its height by n where n is from 2 to 9.
For example
+key('a').h-2
will double the key's height. - .w-n :
apply this class to a key to multiply its width by n where n is from 2 to 9.
For example
+key('a').w-3
will triple the key's width. - .latchable :
normally a key is down only when you're touching it, reverting back to up
otherwise. Applying this class to a key allows it to remain down
even when you're not touching it, by dragging your finger sideways away from
the key before releasing it. Then simply tap the key to unlatch it.
A latchable
shift
key behaves rather like CapsLock on a traditional keyboard.
base template
The base template is the foundation of rkeys apps and includes the JavaScript libraries faye-websocket to communicate the user's keystrokes to the server, jquery to dynamically manipulate the user interface and lodash for general purpose functions. It includes the following jade mixins:
- +prevent-zoom : lock the zoom-level to prevent accidental pinch-zoom. Should be placed in the head section.
- +show-if(activeWindowTitle='regexp') : only show child content if the active window title matches the regular expression regexp.
In addition the following stylesheet classes are available for manipulating layouts:
- .layout.id : only show child content when the current layout's id is id. The default layout's id is default.
- .horizontal : arrange immediate children horizontally
- .vertical : arrange immediate children vertically
command configuration yaml
You can get more fancy by defining commands
in a yaml file (typically command.yaml
) placed in the app's directory.
Each definition has format id: command
where id
is a unique identifier
and command
is a string specifying what to do.
The first word of a command can specify a directive to alter the functionality:
- id: alias str : replace occurrences of id with str in all actions and commands. The standard naming convention for an alias id is all capitals.
- id: broadcast msg : send msg to all connected clients on rkeydown. Useful for keeping things synchronised in multi-tablet setups.
- id: [broadcast msg1, broadcast msg2] : broadcast msg1 on rkeydown and msg2 on rkeyup.
- id: button n : simulate mouse button n by emitting a ButtonPress on rkeydown and ButtonRelease on rkeyup.
- id: exec cmd : execute shell command cmd on rkeydown.
- id: javascript script : dynamically generate a command at runtime using JavaScript. The script must evaluate to an action or command string.
- id: livescript script : As above but using LiveScript.
- id: nop : no-operation. Useful as a placeholder to be redefined at runtime.
Examples:
abc: a b c
: A sequence can be delimited by spaces or commas.on: +c -d
: emit KeyPressc
and KeyReleased
on rkeydown. Explicit KeyPress/KeyRelease events are denoted by prefixes+
and-
respectively.HelloWorld: [H e l l o, +Shift_L w -Shift_L o r l d]
: emit the keystroke sequenceH
e
l
l
o
on rkeydown andW
o
r
l
d
on rkeyup. The square-bracket array has format [ rkeydown-sequence, rkeyup-sequence ], where each sequence is delimited by spaces.VBOX-HOST: alias Super_R
: define an alias for the VirtualBox host key.button: button $0
: simulate mouse button $0, where 1=left, 2=middle, 3=right, etc. This is defined in the core command.yaml.layout: [broadcast layout $0, broadcast layout default]
: instruct connected clients to switch to layout $0 on rkeydown, switching back to the default on rkeyup. This is defined in the core command.yaml.speakeys-onstart: exec qdbus-qt4 org.kde.simon /ActionManager triggerCommand 'Filter' 'pause' > /dev/null
: pause the Simon speech recognition engine.type: javascript '$0'.split('').join(',')
: Convert a string into a sequence of keystrokes and emit them. A more robust version is in the core command.yaml and is ideal for emitting short phrases and sentences.now: livescript (require \moment)!format 'DD/MM/YYYY_HH:mm:ss' .split '' .join ','
: Type the current date and time.
overriding default configuration at runtime
When rkeys starts, the core command.yaml is loaded first followed by any yaml
files discovered in directories supplied on the command line in the given order.
If a command-id appears multiple times then the last one takes precedence
thus allowing default configuration to be overridden at runtime.
For example if we launch rkeys via $ rkeys ./app-1 ./app-2 ~/.config
then if ./app-1/cmd.yaml contains foo: bar
and ~/.config/rkeys.yaml
contains foo: my-custom-command
then the latter definition 'wins'.
sidechaining server-side sound effects
The sidechain allows secondary commands to run alongside the primary
and is the best way to add low-latency server-side sound effects.
Whenever a rkeydown or rkeyup occurs the command-id is checked against
a sequence of /regular-expression/: command
rules and only
the first matching rule will run. Here's an example:
# sidechain in command.yaml
/^kde/: nop # make kde commands silent
/^(button|ffx)/: PLAY-SOUND SFX-BLIP
/^layout/: [ PLAY-SOUND SFX-TICK, PLAY-SOUND SFX-TOCK ]
/.*/: PLAY-SOUND SFX-NOISE # everything else
The built-in SFX-
aliases are defined in the core command.yaml but you can always
supply your own soundfiles (note that relative paths are relative to the source file).
You should redefine the PLAY-SOUND
alias to match your own system. So with SoX
installed you could include the following to play sounds at quarter volume:
PLAY-SOUND: alias exec play -V1 -q --volume 0.25
options
$ rkeys --help
Usage: rkeys [Options] [directory ...]
Options:
-h, --help output usage information
-V, --version output the version number
-g, --gen-ssl-cert generate a self-signed ssl certificate
-p, --port <port> listening port (default:7000)
-s, --servant-to <host[:port]> run as a servant in a guest virtual machine, forwarding active-window-changed events to the specified rkeys master host
-v, --verbosity <level> verbosity 0=min 2=max (default:1)
host over https
In a new empty directory either create a key.pem and cert.pem manually or do the following:
$ rkeys -g # generate using openssl. Follow the prompts.
Include this directory on the rkeys
command line to host over
https on port + 1 (default 7001) at https://your-rkeys-server:7001
.
developer build and run
$ git clone --branch=dev https://github.com/dizzib/rkeys.git
$ cd rkeys
$ npm install # install dependencies
$ npm test # build all and run tests
$ npm start # start the task runner and rkeys