def xlib_send_string(text, window=None): """ Send a string to a window by remapping the keyboard. Slow, but works with all Unicode characters. """ if type(text) is not str: text = text.decode("utf8") if not window: window = xlib_get_active_window() display = xlib_get_display() original_mapping = display.get_keyboard_mapping(254, 1) try: for character in text: display.change_keyboard_mapping( 254, [[xlib_unicode_cp_to_keysym(ord(character))] * len(original_mapping[0])]) display.sync() for m_type in (Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease): ev = m_type(time=0, child=0, state=0, root=window.query_tree().root, window=window, same_screen=1, \ root_x=0, root_y=0, event_x=0, event_y=1, detail=254) window.send_event(ev) display.sync() time.sleep(0.05) pass finally: display.change_keyboard_mapping(254, original_mapping)
def _initialize(self, display): # Get the keyboard mapping to be able to translate events details to # key codes min_keycode = display.display.info.min_keycode keycode_count = display.display.info.max_keycode - min_keycode + 1 self._keyboard_mapping = display.get_keyboard_mapping( min_keycode, keycode_count)
def xlib_send_string(text, window=None): """ Send a string to a window by remapping the keyboard. Slow, but works with all Unicode characters. """ if type(text) is not unicode: text = text.decode("utf8") if not window: window = xlib_get_active_window() display = xlib_get_display() original_mapping = display.get_keyboard_mapping(254, 1) try: for character in text: display.change_keyboard_mapping(254, [ [xlib_unicode_cp_to_keysym(ord(character))] * len(original_mapping[0]) ]) display.sync() for m_type in (Xlib.protocol.event.KeyPress, Xlib.protocol.event.KeyRelease): ev = m_type(time=0, child=0, state=0, root=window.query_tree().root, window=window, same_screen=1, \ root_x=0, root_y=0, event_x=0, event_y=1, detail=254) window.send_event(ev) display.sync() time.sleep(0.05) pass finally: display.change_keyboard_mapping(254, original_mapping)
def remap_keys(remap): """ Remap keycode -> keysym for function keys The keycode -> keysym mapping is so that the keycode generated when the F1 key is pressed sends the F25 keysym. But to do that you need to know the keycodes for F1-10, for Linux on x86 the keycode for F1 is 67 but for other platforms it could be different. So the code looks up the keycode mapped to F1 keysym if that is non zero (i.e. F1 is mapped) I map that keycode to F1 or F25 as required, if F1 is not mapped I lookup the keycode for F25 and if that is non zero I map that keycode to F1 or F25 as required. If F1 and F25 are not mapped to any keycode I use 67 as the keycode for the F1 key. The code assumes that the keycodes for F1-10 are sequential which may not be true for all platforms. A more robust solution may be found by accessing the keyboard layout somehow but I haven't had time to look yet. """ display = Xlib.display.Display() # only keycodes 8 to 255 are defined first_keycode = 8 keymaps_orig = display.get_keyboard_mapping(first_keycode, 255 - first_keycode) keymaps = list(keymaps_orig) if remap == True: keysym = 65494 else: keysym = 65470 keycode_F1 = display.keysym_to_keycode(65470) keycode_F25 = display.keysym_to_keycode(65494) # set first_fkeycode to a sensible default incase F1 and F25 are not mapped first_fkeycode = 67 if keycode_F1 > 0: first_fkeycode = keycode_F1 elif keycode_F25 > 0: first_fkeycode = keycode_F25 for i in range(0, 10): keymaps[(i + first_fkeycode - first_keycode)][0] = keysym + i keymaps[(i + first_fkeycode - first_keycode)][2] = keysym + i keymaps[(i + first_fkeycode - first_keycode)][4] = keysym + i display.change_keyboard_mapping(first_keycode, keymaps, onerror = None) display.sync() display.close()
def remap_keys(remap): """ Remap keycode -> keysym for function keys The keycode -> keysym mapping is so that the keycode generated when the F1 key is pressed sends the F25 keysym. But to do that you need to know the keycodes for F1-10, for Linux on x86 the keycode for F1 is 67 but for other platforms it could be different. So the code looks up the keycode mapped to F1 keysym if that is non zero (i.e. F1 is mapped) I map that keycode to F1 or F25 as required, if F1 is not mapped I lookup the keycode for F25 and if that is non zero I map that keycode to F1 or F25 as required. If F1 and F25 are not mapped to any keycode I use 67 as the keycode for the F1 key. The code assumes that the keycodes for F1-10 are sequential which may not be true for all platforms. A more robust solution may be found by accessing the keyboard layout somehow but I haven't had time to look yet. """ display = Xlib.display.Display() # only keycodes 8 to 255 are defined first_keycode = 8 keymaps_orig = display.get_keyboard_mapping(first_keycode, 255 - first_keycode) keymaps = list(keymaps_orig) if remap == True: keysym = 65494 else: keysym = 65470 keycode_F1 = display.keysym_to_keycode(65470) keycode_F25 = display.keysym_to_keycode(65494) # set first_fkeycode to a sensible default incase F1 and F25 are not mapped first_fkeycode = 67 if keycode_F1 > 0: first_fkeycode = keycode_F1 elif keycode_F25 > 0: first_fkeycode = keycode_F25 for i in range(0, int(number_of_suggestions)): keymaps[(i + first_fkeycode - first_keycode)][0] = keysym + i keymaps[(i + first_fkeycode - first_keycode)][2] = keysym + i keymaps[(i + first_fkeycode - first_keycode)][4] = keysym + i display.change_keyboard_mapping(first_keycode, keymaps, onerror = None) display.sync() display.close()
def keyboard_mapping(display): """Generates a mapping from *keysyms* to *key codes* and required modifier shift states. :param Xlib.display.Display display: The display for which to retrieve the keyboard mapping. :return: the keyboard mapping """ mapping = {} shift_mask = 1 << 0 group_mask = alt_gr_mask(display) # Iterate over all keysym lists in the keyboard mapping min_keycode = display.display.info.min_keycode keycode_count = display.display.info.max_keycode - min_keycode + 1 for index, keysyms in enumerate( display.get_keyboard_mapping(min_keycode, keycode_count)): key_code = index + min_keycode # Normalise the keysym list to yield a tuple containing the two groups normalized = keysym_normalize(keysyms) if not normalized: continue # Iterate over the groups to extract the shift and modifier state for groups, group in zip(normalized, (False, True)): for keysym, shift in zip(groups, (False, True)): if not keysym: continue shift_state = 0 \ | (shift_mask if shift else 0) \ | (group_mask if group else 0) # Prefer already known lesser shift states if keysym in mapping and mapping[keysym][1] < shift_state: continue mapping[keysym] = (key_code, shift_state) return mapping
def keyboard_mapping(display): """Generates a mapping from *keysyms* to *key codes* and required modifier shift states. :param Xlib.display.Display display: The display for which to retrieve the keyboard mapping. :return: the keyboard mapping """ mapping = {} shift_mask = 1 << 0 group_mask = alt_gr_mask(display) # Iterate over all keysym lists in the keyboard mapping min_keycode = display.display.info.min_keycode keycode_count = display.display.info.max_keycode - min_keycode + 1 for index, keysyms in enumerate(display.get_keyboard_mapping( min_keycode, keycode_count)): key_code = index + min_keycode # Normalise the keysym list to yield a tuple containing the two groups normalized = keysym_normalize(keysyms) if not normalized: continue # Iterate over the groups to extract the shift and modifier state for groups, group in zip(normalized, (False, True)): for keysym, shift in zip(groups, (False, True)): if not keysym: continue shift_state = 0 \ | (shift_mask if shift else 0) \ | (group_mask if group else 0) # Prefer already known lesser shift states if keysym in mapping and mapping[keysym][1] < shift_state: continue mapping[keysym] = (key_code, shift_state) return mapping