diff --git a/README.md b/README.md index 1caf283..7615e84 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,28 @@ # dotool -dotool reads commands from stdin and simulates keyboard and pointer events. -It works everywhere on Linux, including in X11, Wayland and TTYs. +dotool reads actions from stdin and simulates keyboard/mouse input using +Linux's uinput module. It works system-wide, including in X11, Wayland +and TTYs. ## Install From Source -With `go` and `libxkbcommon-dev` installed, run: +With `go`, `libxkbcommon-dev` and `scdoc` installed, run: sudo ./install.sh -## Permission - -dotool requires permission to `/dev/uinput` to create the virtual input -devices, and a udev rule grants this to users in group input. - -You could try: - - echo type hello | dotool - -and if need be, you can run: - - sudo groupadd -f input - sudo usermod -a -G input $USER - -and re-login and trigger the udev rule or just reboot. - ## Usage -See `dotool --help`, but this greets the world: - - echo 'type Sup, Lads!' | dotool - -and this screams for three seconds: - - { echo keydown A; sleep 3; echo key H shift+1; } | dotool - -There is an initial delay registering the virtual devices, but you can -keep writing commands to the same instance or use the daemon and client, -`dotoold` and `dotoolc`. - - dotoold & - echo type super | dotoolc - echo type speedy | dotoolc - -## Keyboard Layouts - -dotool will type gobbledygook if your environment has assigned it a different -keyboard layout than it's simulating keycodes for. You can match them up -with the environment variables `DOTOOL_XKB_LAYOUT` and `DOTOOL_XKB_VARIANT`. - - echo type azerty | DOTOOL_XKB_LAYOUT=fr dotool +See the [manpage](doc/dotool.1.scd). ## Numen and Contact dotool was written for [Numen](https://numenvoice.org), which has a [chat on Matrix](https://matrix.to/#/#numen:matrix.org) you're welcome to join. -You can also send questions, thoughts or patches by composing an email to +You can also send questions or patches by composing an email to [~geb/public-inbox@lists.sr.ht](https://lists.sr.ht/~geb/public-inbox). -## Support Me +## Support My Work 👀 [Thank you!](https://liberapay.com/geb) diff --git a/doc/dotool.1.scd b/doc/dotool.1.scd new file mode 100644 index 0000000..516332e --- /dev/null +++ b/doc/dotool.1.scd @@ -0,0 +1,132 @@ +dotool(1) + +# NAME + +*dotool* - uinput tool + +# SYNOPSIS + +*dotool* < _actions_ + +# DESCRIPTION + +*dotool* reads actions from stdin and simulates keyboard/mouse input using +Linux's uinput module. + +# PERMISSION + +*dotool* requires write permission to */dev/uinput*, which is granted to +users in group *input* by a udev rule. + +You can test: + + *echo type hello | dotool* + +and if need be, you could add your user to group *input* with: + + *groupadd -f input*++ +*usermod -a -G input $USER* + +and then it's foolproof to reboot to make the group and rule effective. + +# KEYBOARD LAYOUTS + +*dotool* may type gobbledygook if it's simulating keycodes for a different +keyboard layout than your environment is expecting. + +You can have *dotool* simulate keycodes for whatever layout by setting the +environment variables *DOTOOL_XKB_LAYOUT* and *DOTOOL_XKB_VARIANT*. For +example: + + *echo type azerty | DOTOOL_XKB_LAYOUT=fr dotool* + +Currently the *type* action has only heuristic support for dead keys. + +# OPTIONS + +*-h*, *--help* + Print help and exit. + +*--keyboard-name=*_NAME_ + Specify the name to give the virtual keyboard device. + +*--list-keys* + Print the possible Linux keys and exit. + +*--list-x-keys* + Print the possible XKB keys and exit. + +*--version* + Print the version and exit. + +# ACTIONS + +*key* _CHORD_...++ +*keydown* _CHORD_...++ +*keyup* _CHORD_... + Press and/or release each _CHORD_. A _CHORD_ is a key or a key with + modifiers, such as *a*, *shift+a* or *ctrl+shift+a*. + + The supported modifiers are *super*, *ctrl*, *alt* and *shift*. + + Keys can be specified by Linux names, XKB names prefixed with + *x:*, or Linux keycodes prefixed with *k:*. The Linux names are + case-insensitive, except uppercase character keys also simulate + shift. This example types *!!!* with the *us* layout: + + *echo key shift+1 x:exclam shift+k:2 | dotool* + +*type* _TEXT_ + Type _TEXT_. + +*click* *left*/*middle*/*right*++ +*buttondown* *left*/*middle*/*right*++ +*buttonup* *left*/*middle*/*right* + Press and/or release a mouse button. + +*wheel* _AMOUNT_++ +*hwheel* _AMOUNT_ + Scroll a vertical/horizontal mouse wheel by a positive or negative + _AMOUNT_. + +*mouseto* _X_ _Y_ + Jump the cursor to the position _X_ _Y_, where _X_ and _Y_ are + percentages between 0.0 and 1.0. + +*mousemove* _X_ _Y_ + Move the cursor relative to its current position. + +*keydelay* _MILLISECONDS_++ +*keyhold* _MILLISECONDS_++ +*typedelay* _MILLISECONDS_++ +*typehold* _MILLISECONDS_ + Set the delay between/holding each key with the *key*\* actions/*type* + action. + + The default *keydelay* and *typedelay* is 2ms, and the default + *keyhold* and *typehold* is 8ms. + +# LONG-RUNNING INSTANCE + +Each instance of *dotool* has an initial delay registering the virtual +devices, but you can keep writing actions to a long-running instance. The +daemon and client, *dotoold* and *dotoolc*, let you do this with a pipe +behind the scenes, for example: + + *dotoold &*++ +*echo type super | dotoolc*++ +*echo type speedy | dotoolc* + +# EXAMPLES + +This greets the world: + + *echo 'type Sup, Lads!' | dotool* + +This screams for roughly three seconds: + + *{ echo keydown A; sleep 3; echo key H shift+1; } | dotool* + +# AUTHOR + +John Gebbie diff --git a/dotool.go b/dotool.go index add8b2a..cc93d94 100644 --- a/dotool.go +++ b/dotool.go @@ -18,9 +18,9 @@ import ( var Version string func usage() { - fmt.Println(`dotool reads commands from stdin and simulates keyboard and pointer events. + fmt.Println(`dotool reads actions from stdin and simulates keyboard/mouse input using uinput. -The commands are: +The supported actions are: key CHORD... keydown CHORD... keyup CHORD... @@ -28,62 +28,21 @@ The commands are: click left/middle/right buttondown left/middle/right buttonup left/middle/right - wheel AMOUNT (a positive AMOUNT is up, a negative is down) - hwheel AMOUNT (a positive AMOUNT is right, a negative is left) - mouseto X Y (where X and Y are percentages between 0.0 and 1.0) - mousemove X Y (where X and Y are the number of pixels to move) - keydelay MILLISECONDS (default: 2) - keyhold MILLISECONDS (default: 8) - typedelay MILLISECONDS (default: 2) - typehold MILLISECONDS (default: 8) + wheel AMOUNT + hwheel AMOUNT + mouseto X Y + mousemove X Y + keydelay MILLISECONDS + keyhold MILLISECONDS + typedelay MILLISECONDS + typehold MILLISECONDS +--keyboard-name=NAME Specify the name to give the virtual keyboard device. +--list-keys Print the possible Linux keys and exit. +--list-x-keys Print the possible XKB keys and exit. +--version Print the version and exit. -dotool is installed with a udev rule to allow users in group input to run -it without root permissions. - -You can add yourself to group input by running: - - sudo groupadd -f input - sudo usermod -a -G input $USER - -It's foolproof to reboot to make the rule effective. - - -Keys can be specified by Linux names, XKB names prefixed with x:, or Linux -keycodes prefixed with k:. The Linux names are case-insensitive, except -uppercase character keys also simulate shift. - -The modifiers are: super, ctrl, alt and shift. - - echo key shift+1 x:exclam shift+k:2 | dotool - - -There is an initial delay registering the virtual devices, but you can keep -writing commands to the same instance or use the daemon and client, dotoold -and dotoolc. - - { echo keydown A; sleep 3; echo key H shift+1; } | dotool - - dotoold & - echo type super | dotoolc - echo type speedy | dotoolc - - -dotool will type gobbledygook if your environment has assigned it a different -keyboard layout than it's simulating keycodes for. You can match them up -with the environment variables DOTOOL_XKB_LAYOUT and DOTOOL_XKB_VARIANT. - - echo type azerty | DOTOOL_XKB_LAYOUT=fr dotool - - ---list-keys - Print the possible Linux keys and exit. - ---list-x-keys - Print the possible XKB keys and exit. - ---version - Print the version and exit.`) +See 'man dotool' for the documentation.`) } func fatal(a ...any) {