func parseKeyEnvent(X *xgbutil.XUtil, state uint16, detail xproto.Keycode) string { modStr := keybind.ModifierString(state) keyStr := keybind.LookupString(X, state, detail) if detail == 65 { keyStr = "Space" } if keyStr == "L1" { keyStr = "F11" } if keyStr == "L2" { keyStr = "F12" } value := "" modStr = deleteSpecialMod(modStr) if len(modStr) > 0 { value = convertModsToKeys(modStr) + ACCEL_DELIM + keyStr } else { value = keyStr } return value }
func (ct *CommandTray) keyPress() xevent.KeyPressFun { f := func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) { // print("Cake:\n") if !ct.is_focused { // print("Boom\n") return } mods, kc := keybind.DeduceKeyInfo(ev.State, ev.Detail) // print("Key Press:", mods, kc, "\n") switch { case keybind.KeyMatch(X, "Escape", mods, kc): ct.Blur() case keybind.KeyMatch(X, "Return", mods, kc): ct.activate() case keybind.KeyMatch(X, "Up", mods, kc): ct.selected -= 1 if ct.selected < 0 { ct.selected = len(ct.cmds) } ct.Draw() case keybind.KeyMatch(X, "Down", mods, kc): if len(ct.cmds) > 0 { ct.selected += 1 ct.selected %= len(ct.cmds) ct.Draw() } case keybind.KeyMatch(X, "BackSpace", mods, kc): if len(ct.input) > 0 { ct.input = ct.input[:len(ct.input)-1] ct.getCommands() ct.Draw() } default: s := keybind.LookupString(X, mods, kc) if len(s) == 1 { ct.input = append(ct.input, rune(strings.ToLower(s)[0])) ct.selected = 0 ct.getCommands() ct.Draw() } } } return xevent.KeyPressFun(f) }
func main() { X, _ := xgbutil.NewConn() keybind.Initialize(X) // should output "{" fmt.Println(string(keybind.LookupString(X, 1, 34))) // should output "[" fmt.Println(string(keybind.LookupString(X, 0, 34))) fmt.Println("---------------------------------------") // should output "A" fmt.Println(string(keybind.LookupString(X, 1, 38))) // should output "a" fmt.Println(string(keybind.LookupString(X, 0, 38))) }
// Add will convert a (modifiers, keycode) tuple taken directly from a // Key{Press,Release}Event to a single character string. // Note that sometimes this conversion will fail. When it fails, a message will // be logged and no text will be added. // // Note that sometimes the conversion should fail (like when the Shift key // is pressed), and other times it will fail because the xgbutil/keybind // package provides inadequate support for keyboard encodings. // // I suspect that languages other than English will completely fail here. // // If a work-around is desperately needed, use AddLetter. func (ti *Input) Add(mods uint16, kc xproto.Keycode) { s := keybind.LookupString(ti.X, mods, kc) if len(s) != 1 { logger.Lots.Printf("(*Input).Add: Could not translate string '%s' "+ "received from the keyboard to a single character.", s) return } ti.AddLetter(rune(s[0])) }
func (m *Manager) listenKeyEvents() { xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if e.Detail == 65 { keyStr = "space" } logger.Infof("KeyStr: %s, modStr: %s", keyStr, modStr) if !m.mediaKey.emitMediaSignal(modStr, keyStr, true) { modStr = deleteSpecialMod(modStr) value := "" if len(modStr) < 1 { value = keyStr } else { value = modStr + "-" + keyStr } info, ok := newKeycodeInfo(value) if !ok { return } if v, ok := getExecCommand(info); ok { // 不然按键会阻塞,直到程序推出 go doAction(v) } } }).Connect(X, X.RootWin()) xevent.KeyReleaseFun( func(X *xgbutil.XUtil, e xevent.KeyReleaseEvent) { modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if e.Detail == 65 { keyStr = "space" } //modStr = deleteSpecialMod(modStr) m.mediaKey.emitMediaSignal(modStr, keyStr, false) }).Connect(X, X.RootWin()) }
func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the keybind (mousebind) package is used, keybind.Initialize // *should* be called once. It isn't strictly necessary, but allows your // keybindings to persist even if the keyboard mapping is changed during // run-time. (Assuming you're using the xevent package's event loop.) // It also handles the case when your modifier map is changed. keybind.Initialize(X) // Create a new window. We will listen for key presses and translate them // only when this window is in focus. (Similar to how `xev` works.) win, err := xwindow.Generate(X) if err != nil { log.Fatalf("Could not generate a new window X id: %s", err) } win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel, 0xffffffff) // Listen for Key{Press,Release} events. win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) // Map the window. win.Map() // Notice that we use xevent.KeyPressFun instead of keybind.KeyPressFun, // because we aren't trying to make a grab *and* because we want to listen // to *all* key press events, rather than just a particular key sequence // that has been pressed. xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { // keybind.LookupString does the magic of implementing parts of // the X Keyboard Encoding to determine an english representation // of the modifiers/keycode tuple. // N.B. It's working for me, but probably isn't 100% correct in // all environments yet. log.Println("Key:", keybind.LookupString(X, e.State, e.Detail)) }).Connect(X, win.Id) // Finally, start the main event loop. This will route any appropriate // KeyPressEvents to your callback function. log.Println("Program initialized. Start pressing keys!") xevent.Main(X) }
func main() { X, err := xgbutil.NewConn() if err != nil { log.Println(err) return } //Initialize the keybind package keybind.Initialize(X) //Create a window win, err := xwindow.Generate(X) if err != nil { log.Fatalf("Could not generate a new window X id: %s", err) } win.Create(X.RootWin(), 0, 0, 1024, 768, xproto.CwBackPixel, 0x606060ff) // Listen for Key{Press,Release} events. win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) // Map the window. This is what makes it on the screen win.Map() //Make a ...callback... for the events and connect xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if len(modStr) > 0 { log.Printf("Key: %s-%s\n", modStr, keyStr) } else { log.Println("Key:", keyStr) } if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { if e.State&xproto.ModMaskControl > 0 { log.Println("Control-Escape detected. Quitting...") xevent.Quit(X) } } }).Connect(X, win.Id) //So here i'm going to try to make a image..' img := xgraphics.New(X, image.Rect(0, 0, 1024, 768)) err = img.XSurfaceSet(win.Id) if err != nil { log.Printf("Error while setting window surface to image %d: %s\n", win, err) } else { log.Printf("Window %d surface set to image OK\n", win) } // I /think/ XDraw actually sends data to server? img.XDraw() // I /think/ XPaint tells the server to paint image to window img.XPaint(win.Id) //Start the routine that updates the window go updater(img, win) //This seems to start a main loop for listening to xevents xevent.Main(X) }
func (w *Window) handleEvents() { var noX int32 = 1<<31 - 1 noX++ var lastX, lastY int32 = noX, 0 var button wde.Button downKeys := map[string]bool{} for { e, err := w.conn.WaitForEvent() if err != nil { fmt.Println("[go.wde X error] ", err) continue } switch e := e.(type) { case xproto.ButtonPressEvent: button = button | buttonForDetail(e.Detail) var bpe wde.MouseDownEvent bpe.Which = buttonForDetail(e.Detail) bpe.Where.X = int(e.EventX) bpe.Where.Y = int(e.EventY) lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- bpe case xproto.ButtonReleaseEvent: button = button & ^buttonForDetail(e.Detail) var bue wde.MouseUpEvent bue.Which = buttonForDetail(e.Detail) bue.Where.X = int(e.EventX) bue.Where.Y = int(e.EventY) lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- bue case xproto.LeaveNotifyEvent: var wee wde.MouseExitedEvent wee.Where.X = int(e.EventX) wee.Where.Y = int(e.EventY) if lastX != noX { wee.From.X = int(lastX) wee.From.Y = int(lastY) } else { wee.From.X = wee.Where.X wee.From.Y = wee.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- wee case xproto.EnterNotifyEvent: var wee wde.MouseEnteredEvent wee.Where.X = int(e.EventX) wee.Where.Y = int(e.EventY) if lastX != noX { wee.From.X = int(lastX) wee.From.Y = int(lastY) } else { wee.From.X = wee.Where.X wee.From.Y = wee.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- wee case xproto.MotionNotifyEvent: var mme wde.MouseMovedEvent mme.Where.X = int(e.EventX) mme.Where.Y = int(e.EventY) if lastX != noX { mme.From.X = int(lastX) mme.From.Y = int(lastY) } else { mme.From.X = mme.Where.X mme.From.Y = mme.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) if button == 0 { w.events <- mme } else { var mde wde.MouseDraggedEvent mde.MouseMovedEvent = mme mde.Which = button w.events <- mde } case xproto.KeyPressEvent: var ke wde.KeyEvent code := keybind.LookupString(w.xu, e.State, e.Detail) ke.Key = keyForCode(code) w.events <- wde.KeyDownEvent(ke) downKeys[ke.Key] = true kpe := wde.KeyTypedEvent{ KeyEvent: ke, Glyph: letterForCode(code), Chord: wde.ConstructChord(downKeys), } w.events <- kpe case xproto.KeyReleaseEvent: var ke wde.KeyUpEvent ke.Key = keyForCode(keybind.LookupString(w.xu, e.State, e.Detail)) delete(downKeys, ke.Key) w.events <- ke case xproto.ConfigureNotifyEvent: var re wde.ResizeEvent re.Width = int(e.Width) re.Height = int(e.Height) if re.Width != w.width || re.Height != w.height { w.width, w.height = re.Width, re.Height w.bufferLck.Lock() w.buffer.Destroy() w.buffer = xgraphics.New(w.xu, image.Rect(0, 0, re.Width, re.Height)) w.bufferLck.Unlock() w.events <- re } case xproto.ClientMessageEvent: if icccm.IsDeleteProtocol(w.xu, xevent.ClientMessageEvent{&e}) { w.events <- wde.CloseEvent{} } case xproto.DestroyNotifyEvent: case xproto.ReparentNotifyEvent: case xproto.MapNotifyEvent: case xproto.UnmapNotifyEvent: case xproto.PropertyNotifyEvent: default: fmt.Printf("unhandled event: type %T\n%+v\n", e, e) } } close(w.events) }
func (w *Window) handleEvents() { var noX int32 = 1<<31 - 1 noX++ var lastX, lastY int32 = noX, 0 var button wde.Button downKeys := map[string]bool{} for { e, err := w.conn.WaitForEvent() // if err != nil { // fmt.Println("err:", err) // } if err == io.EOF { break } xgbutil.BeSafe(&err) switch e := e.(type) { case xgb.ButtonPressEvent: button = button | buttonForDetail(e.Detail) var bpe wde.MouseDownEvent bpe.Which = buttonForDetail(e.Detail) bpe.Where.X = int(e.EventX) bpe.Where.Y = int(e.EventY) lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- bpe case xgb.ButtonReleaseEvent: button = button & ^buttonForDetail(e.Detail) var bue wde.MouseUpEvent bue.Which = buttonForDetail(e.Detail) bue.Where.X = int(e.EventX) bue.Where.Y = int(e.EventY) lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- bue case xgb.LeaveNotifyEvent: var wee wde.MouseExitedEvent wee.Where.X = int(e.EventX) wee.Where.Y = int(e.EventY) if lastX != noX { wee.From.X = int(lastX) wee.From.Y = int(lastY) } else { wee.From.X = wee.Where.X wee.From.Y = wee.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- wee case xgb.EnterNotifyEvent: var wee wde.MouseEnteredEvent wee.Where.X = int(e.EventX) wee.Where.Y = int(e.EventY) if lastX != noX { wee.From.X = int(lastX) wee.From.Y = int(lastY) } else { wee.From.X = wee.Where.X wee.From.Y = wee.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) w.events <- wee case xgb.MotionNotifyEvent: var mme wde.MouseMovedEvent mme.Where.X = int(e.EventX) mme.Where.Y = int(e.EventY) if lastX != noX { mme.From.X = int(lastX) mme.From.Y = int(lastY) } else { mme.From.X = mme.Where.X mme.From.Y = mme.Where.Y } lastX = int32(e.EventX) lastY = int32(e.EventY) if button == 0 { w.events <- mme } else { var mde wde.MouseDraggedEvent mde.MouseMovedEvent = mme mde.Which = button w.events <- mde } case xgb.KeyPressEvent: var ke wde.KeyEvent code := keybind.LookupString(w.xu, e.State, e.Detail) ke.Key = keyForCode(code) w.events <- wde.KeyDownEvent(ke) downKeys[ke.Key] = true kpe := wde.KeyTypedEvent{ KeyEvent: ke, Glyph: letterForCode(code), Chord: wde.ConstructChord(downKeys), } w.events <- kpe case xgb.KeyReleaseEvent: var ke wde.KeyUpEvent ke.Key = keyForCode(keybind.LookupString(w.xu, e.State, e.Detail)) delete(downKeys, ke.Key) w.events <- ke case xgb.ConfigureNotifyEvent: var re wde.ResizeEvent re.Width = int(e.Width) re.Height = int(e.Height) if re.Width != w.width || re.Height != w.height { w.width, w.height = re.Width, re.Height w.buffer = image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{re.Width, re.Height}}) w.events <- re } case xgb.ClientMessageEvent: if e.Format != 32 { break } name, err := xprop.AtomName(w.xu, e.Type) if err != nil { // TODO: log break } if name != "WM_PROTOCOLS" { break } name2, err := xprop.AtomName(w.xu, xgb.Id(e.Data.Data32[0])) if err != nil { // TODO: log break } if name2 == "WM_DELETE_WINDOW" { w.events <- wde.CloseEvent{} } case xgb.DestroyNotifyEvent: case xgb.ReparentNotifyEvent: case xgb.MapNotifyEvent: case xgb.UnmapNotifyEvent: case xgb.PropertyNotifyEvent: default: fmt.Printf("unhandled event: type %T\n%+v\n", e, e) } } close(w.events) }
func main() { // Connect to the X server using the DISPLAY environment variable. X, err := xgbutil.NewConn() if err != nil { log.Fatal(err) } // Anytime the keybind (mousebind) package is used, keybind.Initialize // *should* be called once. It isn't strictly necessary, but allows your // keybindings to persist even if the keyboard mapping is changed during // run-time. (Assuming you're using the xevent package's event loop.) // It also handles the case when your modifier map is changed. keybind.Initialize(X) // Create a new window. We will listen for key presses and translate them // only when this window is in focus. (Similar to how `xev` works.) win, err := xwindow.Generate(X) if err != nil { log.Fatalf("Could not generate a new window X id: %s", err) } win.Create(X.RootWin(), 0, 0, 500, 500, xproto.CwBackPixel, 0xffffffff) // Listen for Key{Press,Release} events. win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease) // Map the window. win.Map() // Notice that we use xevent.KeyPressFun instead of keybind.KeyPressFun, // because we aren't trying to make a grab *and* because we want to listen // to *all* key press events, rather than just a particular key sequence // that has been pressed. wid := win.Id if flagRoot { wid = X.RootWin() } xevent.KeyPressFun( func(X *xgbutil.XUtil, e xevent.KeyPressEvent) { // keybind.LookupString does the magic of implementing parts of // the X Keyboard Encoding to determine an english representation // of the modifiers/keycode tuple. // N.B. It's working for me, but probably isn't 100% correct in // all environments yet. modStr := keybind.ModifierString(e.State) keyStr := keybind.LookupString(X, e.State, e.Detail) if len(modStr) > 0 { log.Printf("Key: %s-%s\n", modStr, keyStr) } else { log.Println("Key:", keyStr) } if keybind.KeyMatch(X, "Escape", e.State, e.Detail) { if e.State&xproto.ModMaskControl > 0 { log.Println("Control-Escape detected. Quitting...") xevent.Quit(X) } } }).Connect(X, wid) // If we want root, then we take over the entire keyboard. if flagRoot { if err := keybind.GrabKeyboard(X, X.RootWin()); err != nil { log.Fatalf("Could not grab keyboard: %s", err) } log.Println("WARNING: We are taking *complete* control of the root " + "window. The only way out is to press 'Control + Escape' or to " + "close the window with the mouse.") } // Finally, start the main event loop. This will route any appropriate // KeyPressEvents to your callback function. log.Println("Program initialized. Start pressing keys!") xevent.Main(X) }