func initKeyboardMapping() { const ( keyLo = 8 keyHi = 255 ) km, err := xp.GetKeyboardMapping(xConn, keyLo, keyHi-keyLo+1).Reply() if err != nil { log.Fatal(err) } if km == nil { log.Fatal("couldn't get keyboard mapping") } n := int(km.KeysymsPerKeycode) if n < 2 { log.Fatalf("too few keysyms per keycode: %d", n) } for i := keyLo; i <= keyHi; i++ { keysyms[i][0] = km.Keysyms[(i-keyLo)*n+0] keysyms[i][1] = km.Keysyms[(i-keyLo)*n+1] } toGrabs := []xp.Keysym{wmKeysym} if doAudioActions { toGrabs = append(toGrabs, xkAudioLowerVolume, xkAudioMute, xkAudioRaiseVolume) } for _, toGrab := range toGrabs { keycode := xp.Keycode(0) for i := keyLo; i <= keyHi; i++ { if keysyms[i][0] == toGrab || keysyms[i][1] == toGrab { keycode = xp.Keycode(i) } } if keycode == 0 { if toGrab != wmKeysym { continue } log.Fatalf("could not find the window manager key %s", keysymString(toGrab)) } if err := xp.GrabKeyChecked(xConn, false, rootXWin, xp.ModMaskAny, keycode, xp.GrabModeAsync, xp.GrabModeAsync).Check(); err != nil { log.Fatal(err) } } // Disable Caps Lock if it is the wmKeysym. if wmKeysym == xkCapsLock { // On Ubuntu 12.04, disabling Caps Lock involved the equivalent of // `xmodmap -e "clear lock"`. On Ubuntu 14.04, XKB has replaced xmodmap, // possibly because this facilitates per-window keyboard layouts, so the // equivalent of `xmodmap -e "clear lock"` doesn't work. As of October // 2014, github.com/BurntSushi/xgb doesn't support XKB, so we exec the // setxkbmap program instead of speaking the X11 protocol directly to // disable Caps Lock. if err := exec.Command("setxkbmap", "-option", "caps:none").Run(); err != nil { log.Fatalf("setxkbmap failed: %v", err) } } }
func GrabKeyChecked(c *xgb.Conn, win xproto.Window, mods uint16, key xproto.Keycode) error { var err error for _, m := range IgnoreMods { err = xproto.GrabKeyChecked(c, true, win, mods|m, key, xproto.GrabModeAsync, xproto.GrabModeAsync).Check() if err != nil { return err } } return nil }
// GrabChecked Grabs a key with mods on a particular window. // This is the same as Grab, except that it issue a checked request. // Which means that an error could be returned and handled on the spot. // (Checked requests are slower than unchecked requests.) // This will also grab all combinations of modifiers found in xevent.IgnoreMods. func GrabChecked(xu *xgbutil.XUtil, win xproto.Window, mods uint16, key xproto.Keycode) error { var err error for _, m := range xevent.IgnoreMods { err = xproto.GrabKeyChecked(xu.Conn(), true, win, mods|m, key, xproto.GrabModeAsync, xproto.GrabModeAsync).Check() if err != nil { return err } } return nil }