def compute_modifiers(self): if self.xkbmap_raw: with xsync: mod_mappings = X11Keyboard.get_modifier_mappings() self.xkbmap_mod_meanings = {} self.keycodes_for_modifier_keynames = {} for mod, mod_defs in mod_mappings.items(): for mod_def in mod_defs: for v in mod_def: if isinstance(v, int): l = self.keycodes_for_modifier_keynames.setdefault(mod, []) else: self.xkbmap_mod_meanings[v] = mod l = self.keynames_for_mod.setdefault(mod, []) if v not in l: l.append(v) else: log("compute_modifiers() xkbmap_mod_meanings=%s", self.xkbmap_mod_meanings) log("compute_modifiers() xkbmap_keycodes=%s", self.xkbmap_keycodes) if self.xkbmap_mod_meanings: #Unix-like OS provides modifier meanings: self.keynames_for_mod = get_modifiers_from_meanings(self.xkbmap_mod_meanings) elif self.xkbmap_keycodes: #non-Unix-like OS provides just keycodes for now: self.keynames_for_mod = get_modifiers_from_keycodes(self.xkbmap_keycodes, MAP_MISSING_MODIFIERS) if MAP_MISSING_MODIFIERS: map_missing_modifiers(self.keynames_for_mod) else: log.warn("Warning: client did not supply any modifier definitions") self.keynames_for_mod = {} log("compute_modifiers() keynames_for_mod=%s", self.keynames_for_mod) log("compute_modifiers() keycodes_for_modifier_keynames=%s", self.keycodes_for_modifier_keynames) log("compute_modifiers() mod_meanings=%s", self.xkbmap_mod_meanings)
def set_keymap(self, translate_only=False): if not self.enabled: return log( "set_keymap(%s) layout=%s, variant=%s, options=%s, print=%s, query=%s", translate_only, self.xkbmap_layout, self.xkbmap_variant, self.xkbmap_options, nonl(self.xkbmap_print), nonl(self.xkbmap_query)) if translate_only: self.keycode_translation = set_keycode_translation( self.xkbmap_x11_keycodes, self.xkbmap_keycodes) self.add_gtk_keynames() self.compute_modifier_keynames() self.compute_client_modifier_keycodes() return try: with xsync: clean_keyboard_state() do_set_keymap(self.xkbmap_layout, self.xkbmap_variant, self.xkbmap_options, self.xkbmap_print, self.xkbmap_query, self.xkbmap_query_struct) except: log.error("Error setting up new keymap", exc_info=True) log("set_keymap: xkbmap_print=%s, xkbmap_query=%s", nonl(self.xkbmap_print), nonl(self.xkbmap_query)) try: with xsync: #first clear all existing modifiers: clean_keyboard_state() if not self.xkbmap_raw: has_keycodes = bool(self.xkbmap_x11_keycodes) or bool( self.xkbmap_keycodes) assert has_keycodes, "client failed to provide any keycodes!" clear_modifiers(ALL_X11_MODIFIERS.keys() ) #just clear all of them (set or not) #now set all the keycodes: clean_keyboard_state() #first compute the modifier maps as this may have an influence #on the keycode mappings (at least for the from_keycodes case): if self.xkbmap_mod_meanings: #Unix-like OS provides modifier meanings: self.keynames_for_mod = get_modifiers_from_meanings( self.xkbmap_mod_meanings) elif self.xkbmap_keycodes: #non-Unix-like OS provides just keycodes for now: self.keynames_for_mod = get_modifiers_from_keycodes( self.xkbmap_keycodes, MAP_MISSING_MODIFIERS) if MAP_MISSING_MODIFIERS: map_missing_modifiers(self.keynames_for_mod) else: log.warn( "Warning: client did not supply any modifier definitions" ) self.keynames_for_mod = {} if bool(self.xkbmap_query): #native full mapping of all keycodes: self.keycode_translation = set_all_keycodes( self.xkbmap_x11_keycodes, self.xkbmap_keycodes, False, self.keynames_for_mod) else: #if the client does not provide a full native keymap with all the keycodes, #try to preserve the initial server keycodes and translate the client keycodes instead: #(used by non X11 clients like osx,win32 or HTML5) self.keycode_translation = set_keycode_translation( self.xkbmap_x11_keycodes, self.xkbmap_keycodes) self.add_gtk_keynames() #now set the new modifier mappings: clean_keyboard_state() log( "going to set modifiers, xkbmap_mod_meanings=%s, len(xkbmap_keycodes)=%s, keynames_for_mod=%s", self.xkbmap_mod_meanings, len(self.xkbmap_keycodes or []), self.keynames_for_mod) if self.keynames_for_mod: set_modifiers(self.keynames_for_mod) log("keynames_for_mod=%s", self.keynames_for_mod) self.compute_modifier_keynames() else: self.keycode_translation = {} log("keyboard raw mode, keycode translation left empty") log("keycode mappings=%s", X11Keyboard.get_keycode_mappings()) mod_mappings = X11Keyboard.get_modifier_mappings() self.xkbmap_mod_meanings = {} for mod, mod_defs in mod_mappings.items(): for mod_def in mod_defs: for v in mod_def: if type(v) == int: l = self.keycodes_for_modifier_keynames.setdefault( mod, []) else: self.xkbmap_mod_meanings[v] = mod l = self.keynames_for_mod.setdefault( mod, []) if v not in l: l.append(v) log("keynames_for_mod=%s", self.keynames_for_mod) log("keycodes_for_modifier_keynames=%s", self.keycodes_for_modifier_keynames) log("mod_meanings=%s", self.xkbmap_mod_meanings) self.compute_client_modifier_keycodes() log("keyname_for_mod=%s", self.keynames_for_mod) clean_keyboard_state() except: log.error("Error setting X11 keymap", exc_info=True)