// updateMaps runs in response to MappingNotify events. // It is responsible for making sure our view of the world's keyboard // and modifier maps is correct. (Pointer mappings should be handled in // a similar callback in the mousebind package.) func updateMaps(xu *xgbutil.XUtil, e xevent.MappingNotifyEvent) { keyMap, modMap := MapsGet(xu) // So we used to go through the old mapping and the new mapping and pick // out precisely where there are changes. But after allowing for a // one-to-many mapping from keysym to keycodes, this process became too // complex. So we're going to bust out our hammer and rebind everything // based on the initial key strings. if e.Request == xproto.MappingKeyboard { // We must ungrab everything first, in case two keys are being swapped. keys := keyKeys(xu) for _, key := range keys { Ungrab(xu, key.Win, key.Mod, key.Code) detach(xu, key.Evtype, key.Win) } // Wipe the slate clean. xu.KeybindsLck.Lock() xu.Keybinds = make(map[xgbutil.KeyKey][]xgbutil.CallbackKey, len(keys)) xu.Keygrabs = make(map[xgbutil.KeyKey]int, len(keys)) keyStrs := xu.Keystrings xu.KeybindsLck.Unlock() // Update our mappings before rebinding. KeyMapSet(xu, keyMap) ModMapSet(xu, modMap) // Now rebind everything in Keystrings for _, ks := range keyStrs { err := connect(xu, ks.Callback, ks.Evtype, ks.Win, ks.Str, ks.Grab, true) if err != nil { xgbutil.Logger.Println(err) } } } else { // We don't have to do something with MappingModifier like we do with // MappingKeyboard. This is due to us requiring that key strings use // modifier names built into X. (i.e., the names seen in the output of // `xmodmap`.) This means that the modifier mappings happen on the X // server side, so we don't *typically* have to care what key is // actually being pressed to trigger a modifier. (There are some // exceptional cases, and when that happens, we simply query on-demand // which keys are modifiers. See the RunKey{Press,Release}Callbacks // functions in keybind/callback.go for the deets.) KeyMapSet(xu, keyMap) ModMapSet(xu, modMap) } }