def register_keystroke_handler(self, keystring, method, context=WMActions.root_context): """ Register a callback for a keystroke Args: keystring: string, format is 'mod1+mod2+modN+key' such as 'alt+j' method: method to be called """ data = keystring.split("+") mod_list = data[:-1] key = data[-1] modifier_mask = 0 keysym = XK.string_to_keysym(key) #print "%s => %s" % (key, keysym) if keysym == X.NoSymbol: print "%r is not a valid keysym" % key return keycode = self.display.keysym_to_keycode(keysym) for mod in mod_list: # Rename "alt" to "Alt_L" and such. if mod in ("alt", "super", "meta"): mod = mod.capitalize() + "_L" modkey = self.display.keysym_to_keycode(XK.string_to_keysym(mod)) if modkey in self.modifier_map: modifier_mask |= self.modifier_map[modkey] else: print "Invalid modifier key: '%s' (check xmodmap output)" % mod if context == WMActions.root_context: for screen in self.screens.itervalues(): self.grab_key(screen.root, keysym, modifier_mask) keybinding = (context, keysym, modifier_mask) print "Registered keystroke '%s' as %r)" % (keystring, keybinding,) self.keybindings[keybinding] = method
def lookup_character_value(self, character): """ Looks up the keysym for the character then returns the keycode mapping and modifier for that keysym. """ ch_keysym = XK.string_to_keysym(character) ch_mask = 0 if ch_keysym == 0: if character in SPECIAL_X_KEYSYMS: ch_keysym = XK.string_to_keysym(SPECIAL_X_KEYSYMS[character]) elif len(character) == 1: ch_keysym = ord(character) ch_keycodes = self.display.keysym_to_keycodes(ch_keysym) if len(ch_keycodes) == 0 and len(character) == 1: ch_keycodes = self.display.keysym_to_keycodes(ord(character.lower())) ch_mask ^= X.LockMask if len(ch_keycodes) > 0: ch_keycode, mask = self.__findUsableKeycode(ch_keycodes) if ch_keycode == None or mask == None: return None, None else: ch_mask ^= mask else: return None, None if ch_mask ^ 4 < 4: ch_mask ^= 4 ch_mask ^= self.modmasks[self.alt_gr_key] return ch_keycode, ch_mask
def __init__(self) -> None: self.active_keys = { XK.string_to_keysym(key): False for key in SETTINGS.keybindings } self.modifying_keys = { XK.string_to_keysym(key): False for key in SETTINGS.keybinding_modifier } self.zp = ZoneProfile.from_file() self.coordinates = Coordinates() self.display = Display() self.root = self.display.screen().root self.context = self.display.record_create_context( 0, [record.AllClients], [ { "core_requests": (0, 0), "core_replies": (0, 0), "ext_requests": (0, 0, 0, 0), "ext_replies": (0, 0, 0, 0), "delivered_events": (0, 0), "device_events": (X.KeyReleaseMask, X.ButtonReleaseMask), "errors": (0, 0), "client_started": False, "client_died": False, } ], ) self.display.record_enable_context(self.context, self.handler) self.display.record_free_context(self.context)
def send_paste_keypress(self): # TODO: configuration option for paste key-sequence? ctrl = self.display.keysym_to_keycode(XK.string_to_keysym("Control_L")) shift = self.display.keysym_to_keycode(XK.string_to_keysym("Shift_L")) v = self.display.keysym_to_keycode(XK.string_to_keysym("v")) if self.new_clip: ins = self.display.keysym_to_keycode(XK.string_to_keysym("Insert")) self.display.xtest_fake_input(X.KeyPress, shift) self.display.xtest_fake_input(X.KeyPress, ins) self.display.xtest_fake_input(X.KeyRelease, ins) self.display.xtest_fake_input(X.KeyRelease, shift) else: term = self.name in self.terminals or "bash" in self.name if term: self.display.xtest_fake_input(X.KeyPress, shift) self.display.xtest_fake_input(X.KeyPress, ctrl) self.display.xtest_fake_input(X.KeyPress, v) self.display.xtest_fake_input(X.KeyRelease, v) self.display.xtest_fake_input(X.KeyRelease, ctrl) if term: self.display.xtest_fake_input(X.KeyRelease, shift) self.display.sync() # need to give xlib time to do it's thing as the calls are asyncronous if self.old_text: gobject.timeout_add(200, self.reset_clipboard, self.old_text) # self.reset_clipboard (self.old_text) else: gobject.timeout_add(200, self.clear_clipboard)
def __get_keysym(self, key): keysym = XK.string_to_keysym(key) if keysym == 0: # Unfortunately, although this works to get the correct keysym # i.e. keysym for '#' is returned as "numbersign" # the subsequent display.keysym_to_keycode("numbersign") is 0. keysym = XK.string_to_keysym(self._special_X_keysyms[key]) return keysym
def find_key(key): if key == 18: return d.keysym_to_keycode(XK.string_to_keysym('Left')) elif key == 50: return d.keysym_to_keycode(XK.string_to_keysym('Right')) elif key == 34: return d.keysym_to_keycode(XK.string_to_keysym('Home')) else: return 0
def _xlib_get_keycode(self, key) : keysym = XK.string_to_keysym(key) if keysym == 0: try: keysym = XK.string_to_keysym(special_X_keysyms[key]) except KeyError: return None keycode = self.disp.keysym_to_keycode(keysym) return keycode
def lookup_character_value(self, character): """ Looks up the keysym for the character then returns the keycode mapping for that keysym. """ ch_keysym = XK.string_to_keysym(character) if ch_keysym == 0: ch_keysym = XK.string_to_keysym(SPECIAL_X_KEYSYMS[character]) return self.display.keysym_to_keycode(ch_keysym)
def _xlib_get_keycode(self, key): keysym = XK.string_to_keysym(key) if keysym == 0: try: keysym = XK.string_to_keysym(special_X_keysyms[key]) except KeyError: return None keycode = self.disp.keysym_to_keycode(keysym) return keycode
def _get_keysym(cls, ch): keysym = XK.string_to_keysym(ch) if keysym == 0: # Unfortunately, although this works to get the correct keysym # i.e. keysym for '#' is returned as "numbersign" # the subsequent display.keysym_to_keycode("numbersign") is 0. #print "b:" + cls._special_X_keysyms[ch] keysym = XK.string_to_keysym(cls._special_X_keysyms[ch]) #print "keysim:" + str(keysym) return keysym
def setup_funnylocks(self): nlock_key = self.dpy.keysym_to_keycode(XK.string_to_keysym("Num_Lock")) slock_key = self.dpy.keysym_to_keycode(XK.string_to_keysym("Scroll_Lock")) mapping = self.dpy.get_modifier_mapping() mod_names = "Shift Lock Control Mod1 Mod2 Mod3 Mod4 Mod5".split() for modname in mod_names: index = getattr(X, "%sMapIndex" % modname) mask = getattr(X, "%sMask" % modname) if nlock_key and nlock_key in mapping[index]: self.nlock = mask if slock_key and slock_key in mapping[index]: self.slock = mask
def setup_funnylocks(self): nlock_key = self.dpy.keysym_to_keycode(XK.string_to_keysym("Num_Lock")) slock_key = self.dpy.keysym_to_keycode( XK.string_to_keysym("Scroll_Lock")) mapping = self.dpy.get_modifier_mapping() mod_names = "Shift Lock Control Mod1 Mod2 Mod3 Mod4 Mod5".split() for modname in mod_names: index = getattr(X, "%sMapIndex" % modname) mask = getattr(X, "%sMask" % modname) if nlock_key and nlock_key in mapping[index]: self.nlock = mask if slock_key and slock_key in mapping[index]: self.slock = mask
def __init__(self, main_instance): """ Constructor """ gobject.GObject.__init__(self) threading.Thread.__init__(self) self.setDaemon(True) self.running = False self.main = main_instance try: XK.load_keysym_group("xf86") except ImportError, err: log.warn("Xlib backend needs python-xlib 0.15rc1 or higher\n") raise ImportError(str(err))
def string_to_keycode(key): #'\r':'Return' for Shift+Return will trigger "\r" and enter string_to_keycode() refer: https://github.com/SavinaRoja/PyKeyboard/blob/master/pykeyboard/x11.py keys_special={' ':'space','\t':'Tab','\r':'Return','\n':'Return','\b':'BackSpace','\e':'Escape', '!':'exclam','#':'numbersign','%':'percent','$':'dollar','&':'ampersand','"':'quotedbl', '\'':'apostrophe','(':'parenleft',')':'parenright','*':'asterisk','=':'equal','+':'plus', ',':'comma','-':'minus','.':'period','/':'slash',':':'colon',';':'semicolon','<':'less', '>':'greater','?':'question','@':'at','[':'bracketleft',']':'bracketright','\\':'backslash', '^':'asciicircum','_':'underscore','`':'grave','{':'braceleft','|':'bar','}':'braceright', '~':'asciitilde' } key_sym=XK.string_to_keysym(key) if key_sym==0: key_sym=XK.string_to_keysym(keys_special[key]) return disp.keysym_to_keycode(key_sym)
def _keycode(self, sym): if isinstance(sym, str): sym = XK.string_to_keysym(sym) result = self._keycodes.get(sym, None) if result is None: self._keycodes[sym] = result = self.display.keysym_to_keycode(sym) return result
def handle_keypress_sym(self, k): name = XK.keysym_to_string(k) if k in self.modifier_map: self.modifier_map[k] = True return # in buffer mvmt if k == XK.XK_Right and self.is_ctrl(): self.shift_cursor_end_word() elif k == XK.XK_Right: self.shift_cursor_right() elif k == XK.XK_Left and self.is_ctrl(): self.shift_cursor_start_word() elif k == XK.XK_Left: self.shift_cursor_left() # del bk elif k == XK.XK_Delete: self.forward_delete() elif k == XK.XK_BackSpace: self.backward_delete() # printable char elif name is not None: if self.is_ctrl() and is_well_known_ctrl_hotkey(name): self.reset_buff() else: c = name.upper() if self.is_shift() else name self.type_char(c) else: print("other", k, name) self.reset_buff()
def __init__( self, _, action): # (keycode,mapping) => [callback_id, calls] # dictionaries, for handling repeats and cleanups of repeats if not self.XKs: for i in dir(XK): if i.startswith("XK_") and not callable(i): # pylint: disable-msg=E1101 self.XKs[i.lower()[3:]] = XK.__getattribute__(i) # pylint: enable-msg=E1101 self.logger = logging.getLogger("LBRC.Listener.X11Event") self.repeathandler = [] self.cleanup = [] self.commands = [] self.repeat_freq = 0 self.repeat_func = lambda x, n: x self.repeat_commands = [] self.type = 'Generic Event' self.uinput_dev = None self.uinputbridge = None if not 'map_to' in action: self.logger.warning("Definition for XInput without mapping") return if action['type'] == 'mouseaxis': self._init_mouseaxis(action) elif action['type'] == 'mousebutton': self._init_mousebutton(action) elif action['type'] == 'key': self._init_keypress(action)
def str2keycode(cls, code, key=''): """Convert key as string(s) into (modifiers, keycode) pair. There must be both modifier(s) and key persenti. If you send both modifier(s) and key in one string, they must be separated using '-'. Modifiers must be separated using '-'. Keys are case insensitive. If you want to use upper case use Shift modifier. Only modifiers defined in __KEY_MODIFIERS are valid. For example: "Ctrl-A", "Super-Alt-x" """ code = code.split('-') if not key: key = code[-1] masks = code[:-1] else: masks = code # TODO: Check this part... not sure why it looks like that... modifiers = 0 if masks[0]: for mask in masks: if not mask in cls.__KEY_MODIFIERS.keys(): continue modifiers = modifiers | cls.__KEY_MODIFIERS[mask] else: modifiers = X.AnyModifier keysym = XK.string_to_keysym(key) keycode = cls.__DISPLAY.keysym_to_keycode(keysym) cls.__KEYCODES[keycode] = key return (modifiers, keycode)
def on_snippets_completed(self, text): self.snippets.hide() if text is not None: pyperclip.copy(text) keysym = XK.string_to_keysym('V') keycode = self.display.keysym_to_keycode(keysym) ev = protocol.event.KeyPress( time=int(time.time()), root=self.display.screen().root, window=self.focus, root_x=0, root_y=0, event_x=0, event_y=0, same_screen=0, child=X.NONE, state=X.ControlMask, detail=keycode ) self.display.send_event(self.focus, ev) self.display.sync() time.sleep(1) pyperclip.copy(self.cb_cache) return True
def main(options): # current display pid_file = '/var/lock/easyxmotion.pid' # kill any old versions that are still running, # we do it this way so the current one has input focus. # might be a better way to just exit and give focus to the old one. try: with open(pid_file, 'r') as fp: pid = int(fp.read()) try: os.kill(pid, signal.SIGTERM) except OSError: #other isn't running pass except IOError: # first ever run pass with open(pid_file, 'w') as fp: fp.write(str(os.getpid())) osds, windows = display_osd(options) disp = Display() root = disp.screen().root root.change_attributes(event_mask = X.KeyPressMask) root.grab_keyboard(False, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) event = disp.next_event() keycode = event.detail if event.type == X.KeyPress: key = XK.keysym_to_string(disp.keycode_to_keysym(keycode, 0)) if key and key in string.lowercase and string.lowercase.index(key) < len(windows): windows[string.lowercase.index(key)].activate(timestamp) disp.ungrab_keyboard(X.CurrentTime) sys.exit()
def emulateWritingString(d, cmd, delay, k=None): ''' Processes a string by writing it to the screen with a certain delay ''' for c in cmd: if k is not None: # Emulate the key. emulateSpecialKey(d, k, delay) keysym = XK.string_to_keysym(c) if keysym == 0: # Its a symbol, not a letter. emulateSpecialKey(d, c, delay) else: # It's a letter keycode = d.keysym_to_keycode(keysym) # If it's uppercase, we press shift. if c.isupper(): xtest.fake_input(d, X.KeyPress, kmap[u'shift_l']) # Its even a specialer key :P if keycode == 0: emulateSpecialKey(d, c, delay) else: xtest.fake_input(d, X.KeyPress, keycode) d.flush() time.sleep(delay) xtest.fake_input(d, X.KeyRelease, keycode) # Delay time between letters # time.sleep(0.025) # If it's uppercase, we release shift. if c.isupper(): xtest.fake_input(d, X.KeyRelease, kmap[u'shift_l']) d.flush()
def __init__(self, display, path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "default.json")): self.config = {} # Load and parse JSON config with open(path) as data_file: raw_config = json.load(data_file) # Iterate through the items in the object for dkey, value in raw_config.iteritems(): # If a value is not a list type, ignore it if type(value) is not list: logging.error("Key configurations must be listed in arrays.") continue # Convert all of the key strings into their proper codes self.config[dkey] = [] for key in value: code = XK.string_to_keysym(key) # If the returned code is 0, then it could not be found by XK if code is 0: self.config[dkey] = None logging.warning("Key ("+code+") was not recognized by XK") break else: self.config[dkey].append(display.keysym_to_keycode(code))
def start(self): mod = self.MOD_MASK dpy = Display() keys = {} for key, name in self.KEY_MAP.items(): keys[key] = dpy.keysym_to_keycode(XK.string_to_keysym(key)) root = dpy.screen().root for key, code in keys.items(): root.grab_key(code, mod, 1, X.GrabModeAsync, X.GrabModeAsync) root.grab_button( 1, mod, 1, X.ButtonPressMask | X.ButtonReleaseMask | X.PointerMotionMask, X.GrabModeAsync, X.GrabModeAsync, X.NONE, X.NONE) root.grab_button( 3, mod, 1, X.ButtonPressMask | X.ButtonReleaseMask | X.PointerMotionMask, X.GrabModeAsync, X.GrabModeAsync, X.NONE, X.NONE) self.dpy = dpy self.keys = keys self.root = root self.WM_PROTOCOLS = dpy.intern_atom("WM_PROTOCOLS") self.WM_DELETE_WINDOW = dpy.intern_atom("WM_DELETE_WINDOW") self._loop()
def handler(self, reply): """ Self function is called when a xlib event is fired """ data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value(data, self.disp.display, None, None) if event.type == X.KeyPress: if event.detail == 36: self.record("enter") elif event.detail == 22: self.record("backspace") elif event.detail == 37: self.record("control") elif event.detail == 64: self.record("alt") elif event.detail == 108: self.record("alt-gr") key = XK.keysym_to_string( self.disp.keycode_to_keysym(event.detail, event.state)) if key: self.record(key)
def wait(p_keys_list): """Block the whole keyboard!!! And wait until some key from p_keys_list is pressed. By now p_keys_list is a list of strings, so use single ascii symbols. There is a way out of this hell - hit 'Escape'. The function returns hit button`s string representation Eg. for p_keys_list == ['1','2','3'] the function will hand untill 1,2 or 3 key is preseed or Escape is pressed.""" ds = display window.grab_keyboard(1, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) while True: ev = ds.next_event() if ev.type == X.KeyPress: keysym = ds.keycode_to_keysym(ev._data['detail'], 0) keystr = XK.keysym_to_string(keysym) print("Got keysym/keystr: "+str(keysym)+ ' / '+str(keystr)) if keystr in p_keys_list: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return keystr elif str(keysym) in p_keys_list: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return keysym elif keysym == 65307: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return 'Escape'
def wait(p_keys_list): """Block the whole keyboard!!! And wait until some key from p_keys_list is pressed. By now p_keys_list is a list of strings, so use single ascii symbols. There is a way out of this hell - hit 'Escape'. The function returns hit button`s string representation Eg. for p_keys_list == ['1','2','3'] the function will hand untill 1,2 or 3 key is preseed or Escape is pressed.""" ds = display window.grab_keyboard(1, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) while True: ev = ds.next_event() if ev.type == X.KeyPress: keysym = ds.keycode_to_keysym(ev._data['detail'], 0) keystr = XK.keysym_to_string(keysym) print("Got keysym/keystr: " + str(keysym) + ' / ' + str(keystr)) if keystr in p_keys_list: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return keystr elif str(keysym) in p_keys_list: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return keysym elif keysym == 65307: ds.ungrab_keyboard(X.CurrentTime) ds.flush() return 'Escape'
def __init__(self, modifiers, key, action, *args, **kwargs): self.modifiers, self.key = modifiers, key self.action, self.args, self.kwargs = action, args, kwargs self.keysym = XK.string_to_keysym(key) if self.keysym == 0: raise QTileError("Unknown key: %s" % key) self.modmask = utils.translateMasks(self.modifiers)
def __init__(self, keycode, modifiers, keysym): """Create an event instance. Arguments: keycode -- The keycode that identifies a physical key. modifiers -- An 8-bit mask. A set bit means the corresponding modifier is active. See Xlib.X.ShiftMask, Xlib.X.LockMask, Xlib.X.ControlMask, and Xlib.X.Mod1Mask through Xlib.X.Mod5Mask. keysym -- The symbol obtained when the key corresponding to keycode without any modifiers. The KeyboardEmulation class does not track modifiers such as Shift and Control. """ self.keycode = keycode self.modifiers = modifiers self.keysym = keysym # Only want printable characters. if keysym < 255 or keysym in (XK.XK_Return, XK.XK_Tab): self.keystring = XK.keysym_to_string(keysym) if self.keystring == '\x00': self.keystring = None else: self.keystring = None
def parse_keys(self, display, config): commands = ['next_window', 'prev_window', 'kill_window', 'split_horizontal', 'split_vertical', 'next_stack', 'prev_stack', 'kill_stack'] for command in commands: key_def = getattr(config.keys, command) (modifier, key) = key_def.split('+') # TODO Handle multiple modifiers if modifier == 'Mod4': mod_mask = X.Mod4Mask elif modifier == 'Mod3': mod_mask = X.Mod3Mask elif modifier == 'Mod2': mod_mask = X.Mod2Mask elif modifier == 'Mod1': mod_mask = X.Mod1Mask else: logging.critical("Command '%s' uses unknown modifier '%s'", command, modifier) sys.exit(1) keycode = display.keysym_to_keycode(XK.string_to_keysym(key)) self.keymap[(mod_mask, keycode)] = command
def parse_keystring(self, keystring): keys = keystring.split(" + ") if len(keys) == 1: keyval = XK.string_to_keysym(keys[0].upper()) modifier_mask = 0 else: keyval = XK.string_to_keysym(keys[-1].upper()) modifier_mask = 0 if "Ctrl" in keys[0:-1]: modifier_mask |= X.ControlMask if "Alt" in keys[0:-1]: modifier_mask |= X.Mod1Mask # modifier_mask |= X.ShiftMask return (keyval, modifier_mask)
def main(options): # current display pid_file = "/var/lock/easyxmotion.pid" # kill any old versions that are still running, # we do it this way so the current one has input focus. # might be a better way to just exit and give focus to the old one. try: with open(pid_file, "r") as fp: pid = int(fp.read()) try: os.kill(pid, signal.SIGTERM) except OSError: # other isn't running pass except IOError: # first ever run pass with open(pid_file, "w") as fp: fp.write(str(os.getpid())) osds, windows = display_osd(options) disp = Display() root = disp.screen().root root.change_attributes(event_mask=X.KeyPressMask) root.grab_keyboard(False, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) event = disp.next_event() keycode = event.detail if event.type == X.KeyPress: key = XK.keysym_to_string(disp.keycode_to_keysym(keycode, 0)) if key and key in string.lowercase and string.lowercase.index(key) < len(windows): windows[string.lowercase.index(key)].activate(timestamp) disp.ungrab_keyboard(X.CurrentTime) sys.exit()
def string_to_keycode(self, key): codes_mod=[50,62,64,108,37,105] names_mod=['Shift_L', 'Shift_R', 'Alt_L', 'Alt_R', 'Control_L', 'Control_R'] if key in names_mod: return codes_mod[names_mod.index(key)] keys_special={' ':'space','\t':'Tab','\n':'Return','\r':'BackSpace','\e':'Escape', '!':'exclam','#':'numbersign','%':'percent','$':'dollar','&':'ampersand','"':'quotedbl', '\'':'apostrophe','(':'parenleft',')':'parenright','*':'asterisk','=':'equal','+':'plus', ',':'comma','-':'minus','.':'period','/':'slash',':':'colon',';':'semicolon','<':'less', '>':'greater','?':'question','@':'at','[':'bracketleft',']':'bracketright','\\':'backslash', '^':'asciicircum','_':'underscore','`':'grave','{':'braceleft','|':'bar','}':'braceright', '~':'asciitilde' } key_sym=XK.string_to_keysym(key) if key_sym==0: key_sym=XK.string_to_keysym(keys_special[key]) return self.disp.keysym_to_keycode(key_sym)
def send_hotkey(self, *keys): for key in keys: if key not in self.keyboardMapping: logging.warning('WARNING! Key {} is not supported.'.format(key)) return for key in keys: c = self.keyboardMapping[key][0] keysym = XK.string_to_keysym(c) code = self.d.keysym_to_keycode(keysym) fake_input(self.d, X.KeyPress, code) for key in reversed(keys): c = self.keyboardMapping[key][0] keysym = XK.string_to_keysym(c) code = self.d.keysym_to_keycode(keysym) fake_input(self.d, X.KeyRelease, code) time.sleep(0.3) self.d.sync()
def key_spec_to_keycode_modifier_mask(self, key_spec): modifiers, key = parse_modifier_mask(key_spec) keysym = XK.string_to_keysym(key) keycode = self.dpy.keysym_to_keycode(keysym) if keycode not in self.keycode_to_char.keys(): self.keycode_to_char[keycode] = key modifier_mask = reduce(lambda x, y: x | y, modifiers, 0) return key, keycode, modifier_mask
def set_key_aliases(self): keystrings = [ "x", "q", "minus", "equal", "bracketleft", "bracketright", "backslash", "slash", "F1", "Tab", "Escape", "space", "Return", "BackSpace" ] for keystring in keystrings: self.key_alias[keystring] = self.dpy.keysym_to_keycode(XK.string_to_keysym(keystring))
def interpret_keysym(keysym): '''Convert keysym to keyname''' if keysym in KEYSYM_TABLE: # Special keys return KEYSYM_TABLE[keysym] else: # Other keys (if not found, `None` will be returned) return XK.keysym_to_string(keysym)
def __init__(self): """Prepare to emulate keyboard events.""" self.display = display.Display() self.modifier_mapping = self.display.get_modifier_mapping() # Determine the backspace keycode. backspace_keysym = XK.string_to_keysym('BackSpace') self.backspace_keycode, mods = self._keysym_to_keycode_and_modifiers( backspace_keysym)
def hold_button(key): number = display.keysym_to_keycode(XK.string_to_keysym(key)) display.sync() fake_input(display, X.KeyPress, number, X.CurrentTime) yield fake_input(display, X.KeyRelease, number, X.CurrentTime) display.sync() display.flush()
def string_to_keysym(self, s): k = self.keysyms[s] if not k: k = self.keysyms["XK_" + s] if k: return k k = XK.string_to_keysym(s) return k
def str2keycode(cls, key): """Parse keycode.""" keysym = XK.string_to_keysym(key) keycode = cls.__DISPLAY.keysym_to_keycode(keysym) cls.__KEYCODES[keycode] = key if keycode == 0: raise ValueError('No key specified!') return keycode
def mapKey(self, key): if key in self.control_key_map: return self.control_key_map[key] keysym = XK.string_to_keysym(key) if keysym != 0: return keysym return self.map.get(key, None)
def toNativeKeycode(self, key): ''' Returns the X11 native keycode for a QT Key ''' keysim = XK.string_to_keysym(QKeySequence(key).toString()) if keysim == X.NoSymbol: keysim = int(key) #endif return keysim
def parse_key(k): (*parts, sym) = k.split("-") modmask = 0 for mod in parts: modmask |= mods[mod] keysym = XK.string_to_keysym(sym) if keysym == 0: print("Invalid key '%s'" % parts) return (keysym, modmask)
def type_char(self, char): # Try to get keysym (works for non-special keys, returns 0 otherwise) keysym = XK.string_to_keysym(char) if (keysym == 0): keysym = XK.string_to_keysym(special_X_keysyms[char]) keycode = self.disp.keysym_to_keycode(keysym) # Does this char require shift? if (ord(char) >= 0x41 and ord(char) <= 0x51) or "~!@#$%^&*()_+{}|:\"<>?".find(char) >= 0: self.press_button(VK_SHIFT) self.type_button(keycode) self.release_button(VK_SHIFT) else: self.type_button(keycode)
def press(key): keys = re.findall("([\w\d]+)", key) for key, event in chain(zip(keys, repeat(X.KeyPress)), zip(reversed(keys), repeat(X.KeyRelease))): number = display.keysym_to_keycode(XK.string_to_keysym(key)) display.sync() fake_input(display, event, number, X.CurrentTime) display.sync() display.flush()
def parse_keystring(keystring): keys = keystring.split("+") modifier_mask = 0 if len(keys) == 1: keyval = XK.string_to_keysym(keys[0].upper()) else: keyval = XK.string_to_keysym(keys[-1].lower()) if "Ctrl" in keys[0:-1]: modifier_mask |= X.ControlMask if "Alt" in keys[0:-1]: modifier_mask |= X.Mod1Mask if "Shift" in keys[0:-1]: modifier_mask |= X.ShiftMask keycode = local_dpy.keysym_to_keycode(keyval) return (keycode, modifier_mask)
def interpret_keyname(keyname): '''Convert keyname to list of keysyms''' if keyname in KEYSYM_TABLE_INV: # Special keys return KEYSYM_TABLE_INV[keyname] else: # Other keys keysym = XK.string_to_keysym(keyname) return [keysym]
def __send_key(self, x_event, key_code): key = key_code.X11 if key is None: print("key not defined on X11!") pass d = Display() x11key = d.keysym_to_keycode(XK.string_to_keysym(key)) fake_input(d, x_event, x11key) d.sync()
def asciivalue(self, keysym): asciinum = XK.string_to_keysym(self.lookup_keysym(keysym)) if asciinum < 256: return asciinum else: return 0
def do_key_press(keys, target=None): """ executes a keypress :param keys: argument tuple containing one or several modifier keys, and the key to press :param target: list containing name(s) of the target window the key to pass as a parameter has to be taken from Xlib.XK library """ log.debug("do_key_press") root = disp.screen().root keys = map(lambda k: XK.string_to_keysym(k) if isinstance(k, basestring) else k, keys) for key in keys: if not key in XK.__dict__.values(): return False pointer_info = request.QueryPointer(display = disp.display, window = root) root_xpos, root_ypos = (pointer_info._data['root_x'], pointer_info._data['root_y']) targetwindow = disp.get_input_focus().focus if targetwindow.get_wm_name() is None and targetwindow.get_wm_class() is None: targetwindow = targetwindow.query_tree().parent ret = targetwindow.translate_coords(root, root_xpos, root_ypos) target_xpos = ret.x target_ypos = ret.y if target and targetwindow.get_wm_class(): for t in target: if t in targetwindow.get_wm_class(): break else: log.info("Window '%s' not found in target(s) %s" % (targetwindow.get_wm_class(), target)) return False def send_key(display, window, keycodes): '''Send a KeyPress and KeyRelease event''' if not type(keycodes) in (tuple, list): keycodes = (keycodes,) # send with modifier for keycode in keycodes: xtest.fake_input(window, X.KeyPress, display.keysym_to_keycode(keycode)) for keycode in reversed(keycodes): xtest.fake_input(window, X.KeyRelease, display.keysym_to_keycode(keycode)) display.sync() send_key(disp, root, keys) return True
def keycode_to_string(self, key_code): codes_mod=[50,62,64,108,37,105,113,111,114,116,110,115,112,117,118,119,107, 67,68,69,70,71,72,73,74,75,76,95,96 ] names_mod=['Shift_L', 'Shift_R', 'Alt_L', 'Alt_R', 'Control_L', 'Control_R', 'Left', 'Up', 'Right', 'Down', 'Home', 'End', 'Page_Up', 'Page_Down', 'Insert', 'Delete', 'Print', 'F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12' ] if key_code in codes_mod: return names_mod[codes_mod.index(key_code)] #2nd: 0 is unshifted, 1 is shifted, 2 is alt grid, and 3 is shiftalt grid return XK.keysym_to_string(self.disp.keycode_to_keysym(key_code, 0))
def __init__(self, display=None): PyKeyboardMeta.__init__(self) self.display = Display(display) self.root = self.display.screen().root XK.load_keysym_group('xkb') altList = self.display.keysym_to_keycodes(XK.XK_ISO_Level3_Shift) self.__usable_modifiers = (0, 1) for code, offset in altList: if code == 108 and offset == 0: self.__usable_modifiers += (4, 5) break mapping = self.display.get_modifier_mapping() self.modmasks = {} for keyname in MODIFIERS: keysym = XK.string_to_keysym(keyname) keycodes = self.display.keysym_to_keycodes(keysym) found = False for keycode, lvl in keycodes: for index, mask in MASK_INDEXES: if keycode in mapping[index]: self.modmasks[keycode] = mask found = True if found: break self.flags = { 'Shift': X.ShiftMask, 'Lock': X.LockMask, 'Ctrl': X.ControlMask, 'Alt': 0, 'AltGr': self.modmasks[altList[0][0]], 'Hankaku': 0} self.special_key_assignment()
def init_x11(self): from Xlib import X, XK from Xlib.display import Display disp = Display() root = disp.screen().root root.change_attributes(event_mask=X.KeyPressMask) self.WINDOW_KEY = disp.keysym_to_keycode(XK.string_to_keysym("n")) root.grab_key(self.WINDOW_KEY, X.AnyModifier, 1, X.GrabModeAsync, X.GrabModeAsync) import threading t = threading.Thread(target=lambda: self.process_x11(disp)) t.daemon = True t.start()