# 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 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 ' ) ) ,
' 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 ( ' Super_L ' ) ) ,
' 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 ) )