300
.venv/lib/python3.9/site-packages/pyautogui/_pyautogui_x11.py
Normal file
300
.venv/lib/python3.9/site-packages/pyautogui/_pyautogui_x11.py
Normal file
@@ -0,0 +1,300 @@
|
||||
# NOTE - It is a known issue that the keyboard-related functions don't work on Ubuntu VMs in Virtualbox.
|
||||
|
||||
import pyautogui
|
||||
import sys
|
||||
import os
|
||||
from pyautogui import LEFT, MIDDLE, RIGHT
|
||||
|
||||
from Xlib.display import Display
|
||||
from Xlib import X
|
||||
from Xlib.ext.xtest import fake_input
|
||||
import Xlib.XK
|
||||
|
||||
BUTTON_NAME_MAPPING = {LEFT: 1, MIDDLE: 2, RIGHT: 3, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7}
|
||||
|
||||
|
||||
if sys.platform in ('java', 'darwin', 'win32'):
|
||||
raise Exception('The pyautogui_x11 module should only be loaded on a Unix system that supports X11.')
|
||||
|
||||
#from pyautogui import *
|
||||
|
||||
"""
|
||||
Much of this code is based on information gleaned from Paul Barton's PyKeyboard in PyUserInput from 2013, itself derived from Akkana Peck's pykey in 2008 ( http://www.shallowsky.com/software/crikey/pykey-0.1 ), itself derived from her "Crikey" lib.
|
||||
"""
|
||||
|
||||
def _position():
|
||||
"""Returns the current xy coordinates of the mouse cursor as a two-integer
|
||||
tuple.
|
||||
|
||||
Returns:
|
||||
(x, y) tuple of the current xy coordinates of the mouse cursor.
|
||||
"""
|
||||
coord = _display.screen().root.query_pointer()._data
|
||||
return coord["root_x"], coord["root_y"]
|
||||
|
||||
|
||||
def _size():
|
||||
return _display.screen().width_in_pixels, _display.screen().height_in_pixels
|
||||
|
||||
|
||||
|
||||
def _vscroll(clicks, x=None, y=None):
|
||||
clicks = int(clicks)
|
||||
if clicks == 0:
|
||||
return
|
||||
elif clicks > 0:
|
||||
button = 4 # scroll up
|
||||
else:
|
||||
button = 5 # scroll down
|
||||
|
||||
for i in range(abs(clicks)):
|
||||
_click(x, y, button=button)
|
||||
|
||||
|
||||
def _hscroll(clicks, x=None, y=None):
|
||||
clicks = int(clicks)
|
||||
if clicks == 0:
|
||||
return
|
||||
elif clicks > 0:
|
||||
button = 7 # scroll right
|
||||
else:
|
||||
button = 6 # scroll left
|
||||
|
||||
for i in range(abs(clicks)):
|
||||
_click(x, y, button=button)
|
||||
|
||||
|
||||
def _scroll(clicks, x=None, y=None):
|
||||
return _vscroll(clicks, x, y)
|
||||
|
||||
|
||||
def _click(x, y, button):
|
||||
assert button in BUTTON_NAME_MAPPING.keys(), "button argument not in ('left', 'middle', 'right', 4, 5, 6, 7)"
|
||||
button = BUTTON_NAME_MAPPING[button]
|
||||
|
||||
_mouseDown(x, y, button)
|
||||
_mouseUp(x, y, button)
|
||||
|
||||
|
||||
def _moveTo(x, y):
|
||||
fake_input(_display, X.MotionNotify, x=x, y=y)
|
||||
_display.sync()
|
||||
|
||||
|
||||
def _mouseDown(x, y, button):
|
||||
_moveTo(x, y)
|
||||
assert button in BUTTON_NAME_MAPPING.keys(), "button argument not in ('left', 'middle', 'right', 4, 5, 6, 7)"
|
||||
button = BUTTON_NAME_MAPPING[button]
|
||||
fake_input(_display, X.ButtonPress, button)
|
||||
_display.sync()
|
||||
|
||||
|
||||
def _mouseUp(x, y, button):
|
||||
_moveTo(x, y)
|
||||
assert button in BUTTON_NAME_MAPPING.keys(), "button argument not in ('left', 'middle', 'right', 4, 5, 6, 7)"
|
||||
button = BUTTON_NAME_MAPPING[button]
|
||||
fake_input(_display, X.ButtonRelease, button)
|
||||
_display.sync()
|
||||
|
||||
|
||||
def _keyDown(key):
|
||||
"""Performs a keyboard key press without the release. This will put that
|
||||
key in a held down state.
|
||||
|
||||
NOTE: For some reason, this does not seem to cause key repeats like would
|
||||
happen if a keyboard key was held down on a text field.
|
||||
|
||||
Args:
|
||||
key (str): The key to be pressed down. The valid names are listed in
|
||||
pyautogui.KEY_NAMES.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
if key not in keyboardMapping or keyboardMapping[key] is None:
|
||||
return
|
||||
|
||||
if type(key) == int:
|
||||
fake_input(_display, X.KeyPress, key)
|
||||
_display.sync()
|
||||
return
|
||||
|
||||
needsShift = pyautogui.isShiftCharacter(key)
|
||||
if needsShift:
|
||||
fake_input(_display, X.KeyPress, keyboardMapping['shift'])
|
||||
|
||||
fake_input(_display, X.KeyPress, keyboardMapping[key])
|
||||
|
||||
if needsShift:
|
||||
fake_input(_display, X.KeyRelease, keyboardMapping['shift'])
|
||||
_display.sync()
|
||||
|
||||
|
||||
def _keyUp(key):
|
||||
"""Performs a keyboard key release (without the press down beforehand).
|
||||
|
||||
Args:
|
||||
key (str): The key to be released up. The valid names are listed in
|
||||
pyautogui.KEY_NAMES.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
"""
|
||||
Release a given character key. Also works with character keycodes as
|
||||
integers, but not keysyms.
|
||||
"""
|
||||
if key not in keyboardMapping or keyboardMapping[key] is None:
|
||||
return
|
||||
|
||||
if type(key) == int:
|
||||
keycode = key
|
||||
else:
|
||||
keycode = keyboardMapping[key]
|
||||
|
||||
fake_input(_display, X.KeyRelease, keycode)
|
||||
_display.sync()
|
||||
|
||||
|
||||
# Taken from PyKeyboard's ctor function.
|
||||
_display = Display(os.environ['DISPLAY'])
|
||||
|
||||
|
||||
""" Information for keyboardMapping derived from PyKeyboard's special_key_assignment() function.
|
||||
|
||||
The *KB dictionaries in pyautogui map a string that can be passed to keyDown(),
|
||||
keyUp(), or press() into the code used for the OS-specific keyboard function.
|
||||
|
||||
They should always be lowercase, and the same keys should be used across all OSes."""
|
||||
keyboardMapping = dict([(key, None) for key in pyautogui.KEY_NAMES])
|
||||
keyboardMapping.update({
|
||||
'backspace': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('BackSpace')),
|
||||
'\b': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('BackSpace')),
|
||||
'tab': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Tab')),
|
||||
'enter': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Return')),
|
||||
'return': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Return')),
|
||||
'shift': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Shift_L')),
|
||||
'ctrl': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Control_L')),
|
||||
'alt': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Alt_L')),
|
||||
'pause': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Pause')),
|
||||
'capslock': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Caps_Lock')),
|
||||
'esc': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Escape')),
|
||||
'escape': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Escape')),
|
||||
'pgup': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Page_Up')),
|
||||
'pgdn': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Page_Down')),
|
||||
'pageup': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Page_Up')),
|
||||
'pagedown': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Page_Down')),
|
||||
'end': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('End')),
|
||||
'home': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Home')),
|
||||
'left': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Left')),
|
||||
'up': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Up')),
|
||||
'right': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Right')),
|
||||
'down': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Down')),
|
||||
'select': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Select')),
|
||||
'print': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Print')),
|
||||
'execute': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Execute')),
|
||||
'prtsc': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Print')),
|
||||
'prtscr': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Print')),
|
||||
'prntscrn': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Print')),
|
||||
'printscreen': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Print')),
|
||||
'insert': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Insert')),
|
||||
'del': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Delete')),
|
||||
'delete': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Delete')),
|
||||
'help': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Help')),
|
||||
'win': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Super_L')),
|
||||
'winleft': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Super_L')),
|
||||
'winright': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Super_R')),
|
||||
'apps': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Menu')),
|
||||
'num0': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_0')),
|
||||
'num1': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_1')),
|
||||
'num2': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_2')),
|
||||
'num3': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_3')),
|
||||
'num4': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_4')),
|
||||
'num5': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_5')),
|
||||
'num6': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_6')),
|
||||
'num7': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_7')),
|
||||
'num8': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_8')),
|
||||
'num9': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_9')),
|
||||
'multiply': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Multiply')),
|
||||
'add': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Add')),
|
||||
'separator': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Separator')),
|
||||
'subtract': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Subtract')),
|
||||
'decimal': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Decimal')),
|
||||
'divide': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('KP_Divide')),
|
||||
'f1': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F1')),
|
||||
'f2': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F2')),
|
||||
'f3': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F3')),
|
||||
'f4': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F4')),
|
||||
'f5': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F5')),
|
||||
'f6': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F6')),
|
||||
'f7': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F7')),
|
||||
'f8': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F8')),
|
||||
'f9': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F9')),
|
||||
'f10': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F10')),
|
||||
'f11': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F11')),
|
||||
'f12': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F12')),
|
||||
'f13': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F13')),
|
||||
'f14': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F14')),
|
||||
'f15': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F15')),
|
||||
'f16': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F16')),
|
||||
'f17': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F17')),
|
||||
'f18': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F18')),
|
||||
'f19': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F19')),
|
||||
'f20': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F20')),
|
||||
'f21': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F21')),
|
||||
'f22': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F22')),
|
||||
'f23': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F23')),
|
||||
'f24': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('F24')),
|
||||
'numlock': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Num_Lock')),
|
||||
'scrolllock': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Scroll_Lock')),
|
||||
'shiftleft': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Shift_L')),
|
||||
'shiftright': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Shift_R')),
|
||||
'ctrlleft': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Control_L')),
|
||||
'ctrlright': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Control_R')),
|
||||
'altleft': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Alt_L')),
|
||||
'altright': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Alt_R')),
|
||||
# These are added because unlike a-zA-Z0-9, the single characters do not have a
|
||||
' ': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('space')),
|
||||
'space': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('space')),
|
||||
'\t': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Tab')),
|
||||
'\n': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Return')), # for some reason this needs to be cr, not lf
|
||||
'\r': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Return')),
|
||||
'\e': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('Escape')),
|
||||
'!': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('exclam')),
|
||||
'#': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('numbersign')),
|
||||
'%': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('percent')),
|
||||
'$': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('dollar')),
|
||||
'&': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('ampersand')),
|
||||
'"': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('quotedbl')),
|
||||
"'": _display.keysym_to_keycode(Xlib.XK.string_to_keysym('apostrophe')),
|
||||
'(': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('parenleft')),
|
||||
')': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('parenright')),
|
||||
'*': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('asterisk')),
|
||||
'=': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('equal')),
|
||||
'+': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('plus')),
|
||||
',': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('comma')),
|
||||
'-': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('minus')),
|
||||
'.': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('period')),
|
||||
'/': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('slash')),
|
||||
':': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('colon')),
|
||||
';': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('semicolon')),
|
||||
'<': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('less')),
|
||||
'>': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('greater')),
|
||||
'?': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('question')),
|
||||
'@': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('at')),
|
||||
'[': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('bracketleft')),
|
||||
']': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('bracketright')),
|
||||
'\\': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('backslash')),
|
||||
'^': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('asciicircum')),
|
||||
'_': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('underscore')),
|
||||
'`': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('grave')),
|
||||
'{': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('braceleft')),
|
||||
'|': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('bar')),
|
||||
'}': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('braceright')),
|
||||
'~': _display.keysym_to_keycode(Xlib.XK.string_to_keysym('asciitilde')),
|
||||
})
|
||||
|
||||
# Trading memory for time" populate winKB so we don't have to call VkKeyScanA each time.
|
||||
for c in """abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890""":
|
||||
keyboardMapping[c] = _display.keysym_to_keycode(Xlib.XK.string_to_keysym(c))
|
Reference in New Issue
Block a user