Skip to content

Instantly share code, notes, and snippets.

@sakurai-youhei
Last active October 26, 2018 23:19
Show Gist options
  • Save sakurai-youhei/9f8d7bb46d5357f3367a6d46228603ed to your computer and use it in GitHub Desktop.
Save sakurai-youhei/9f8d7bb46d5357f3367a6d46228603ed to your computer and use it in GitHub Desktop.
Python wrapper for xte command
"""
xte v1.09
Generates fake input using the XTest extension, more reliable than xse
Author: Steve Slaven - http://hoopajoo.net
usage: xte [-h] [-i xinputid] [-x display] [arg ..]
-h this help
-i XInput2 device to use. List devices with 'xinput list'
-x send commands to remote X server. Note that some commands
may not work correctly unless the display is on the console,
e.g. the display is currently controlled by the keyboard and
mouse and not in the background. This seems to be a limitation
of the XTest extension.
arg args instructing the little man on what to do (see below)
if no args are passed, commands are read from stdin separated
by newlines, to allow a batch mode
Commands:
key k Press and release key k
keydown k Press key k down
keyup k Release key k
str string Do a bunch of key X events for each char in string
mouseclick i Click mouse button i
mousemove x y Move mouse to screen position x,y
mousermove x y Move mouse relative from current location by x,y
mousedown i Press mouse button i down
mouseup i Release mouse button i
sleep x Sleep x seconds
usleep x uSleep x microseconds
Some useful keys (case sensitive)
Home
Left
Up
Right
Down
Page_Up
Page_Down
End
Return
BackSpace
Tab
Escape
Delete
Shift_L
Shift_R
Control_L
Control_R
Meta_L
Meta_R
Alt_L
Alt_R
Multi_key
Depending on your keyboard layout, the "Windows" key may be one of the
Super_ keys or the Meta_ keys.
Sample, drag from 100,100 to 200,200 using mouse1:
xte 'mousemove 100 100' 'mousedown 1' 'mousemove 200 200' 'mouseup 1'
"""
from enum import Enum
from os import getenv
from subprocess import PIPE
from subprocess import Popen
from typing import Union
__all__ = ("Key", "Xte")
Key = Enum("Key", {k: k for k in map(str.strip, """\
Home
Left
Up
Right
Down
Page_Up
Page_Down
End
Return
BackSpace
Tab
Escape
Delete
Shift_L
Shift_R
Control_L
Control_R
Meta_L
Meta_R
Alt_L
Alt_R
Multi_key
""".splitlines())})
class Xte(Popen):
def __init__(self, *xinputid: int, server: str=getenv("DISPLAY", ""),
encoding: str="ascii", errors: str="ignore",
stdin: int=PIPE, **kwargs) -> None:
cmd = ["xte"]
for device in xinputid:
cmd += ["-i", str(device)]
if server:
cmd += ["-x", server]
Popen.__init__(self, cmd, stdin=stdin, encoding=encoding,
errors=errors, **kwargs)
def emit(self, *cmds: str) -> None:
print(*cmds, sep="\n", file=self.stdin, flush=True)
def key(self, k: Union[str, Key]) -> None:
"""Press and release key k"""
self.emit("key %s" % k)
def keydown(self, k: Union[str, Key]) -> None:
"""Press key k down"""
self.emit("keydown %s" % k)
def keyup(self, k: Union[str, Key]) -> None:
"""Release key k"""
self.emit("keyup %s" % k)
def __str(self, string: str) -> None:
"""Do a bunch of key X events for each char in string"""
self.emit("str %s" % string)
def mouseclick(self, i: int) -> None:
"""Click mouse button i"""
self.emit("mouseclick %d" % i)
def mousemove(self, x: int, y: int) -> None:
"""Move mouse to screen position x,y"""
self.emit("mousemove %d %d" % (x, y))
def mousermove(self, x: int, y: int) -> None:
"""Move mouse relative from current location by x,y"""
self.emit("mousermove %d %d" % (x, y))
def mousedown(self, i: int) -> None:
"""Press mouse button i down"""
self.emit("mousedown %d" % i)
def mouseup(self, i: int) -> None:
"""Release mouse button i"""
self.emit("mouseup %d" % i)
def sleep(self, x: int) -> None:
"""Sleep x seconds"""
self.emit("sleep %d" % x)
def usleep(self, x: int) -> None:
"""uSleep x microseconds"""
self.emit("usleep %d" % x)
str = __str
"""
Sample, drag from 100,100 to 200,200 using mouse1:
xte 'mousemove 100 100' 'mousedown 1' 'mousemove 200 200' 'mouseup 1'
"""
if __name__ == "__main__":
with Xte() as xte:
xte.mousemove(100, 100)
xte.mousedown(1)
xte.mousemove(200, 200)
xte.mouseup(1)
# Or xte.emit('mousemove 100 100',
# 'mousedown 1',
# 'mousemove 200 200',
# 'mouseup 1')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment