// type a keysym, applying a slice of modifiers func KeysymType(keysym C.KeySym, modifiers []string) error { // As XTestFakeKeyEvent does not use current keyboard layout, // we map each keysym to type to an unused keycode to circumvent this bug nkeysyms := C.int(5) keysyms := make([]C.KeySym, nkeysyms) for i, _ := range keysyms { keysyms[i] = keysym } var err error keycode, err := x.UnusedKeycode() if err != nil { return err } C.XChangeKeyboardMapping(x.dpy, C.int(keycode), nkeysyms, &keysyms[0], 1) x.XSync() // apply modifiers for _, modifier := range modifiers { bytes := []byte(modifier) mkeysym := C.XStringToKeysym((*C.char)(unsafe.Pointer(&bytes[0]))) mkeycode := C.XKeysymToKeycode(x.dpy, mkeysym) C.XTestFakeKeyEvent(x.dpy, C.uint(mkeycode), 1, 0) } // hit/release the keycode associated to desired keysym C.XTestFakeKeyEvent(x.dpy, C.uint(keycode), 1, 0) C.XTestFakeKeyEvent(x.dpy, C.uint(keycode), 0, 0) // release modifiers for _, modifier := range modifiers { bytes := []byte(modifier) mkeysym := C.XStringToKeysym((*C.char)(unsafe.Pointer(&bytes[0]))) mkeycode := C.XKeysymToKeycode(x.dpy, mkeysym) C.XTestFakeKeyEvent(x.dpy, C.uint(mkeycode), 0, 0) } x.XSync() // release unused keycode for i, _ := range keysyms { keysyms[i] = 0 } C.XChangeKeyboardMapping(x.dpy, C.int(keycode), nkeysyms, &keysyms[0], 1) x.XSync() return nil }
func sendKey(disp *C.struct__XDisplay, strname string) { if disp == nil { fmt.Println("no X11 display available") return } var mod _Ctype_KeyCode if strings.HasPrefix(strname, "Ctrl+") { strname = strname[len("Ctrl+"):] modkey := "Control_L" mod = C.XKeysymToKeycode(disp, C.XStringToKeysym(C.CString(modkey))) if debug { fmt.Printf("send key %T (Control) code=%v\n", mod, mod) } C.XTestFakeKeyEvent(disp, C.uint(mod), 1, 0) C.XFlush(disp) } chstr := C.CString(strname) keysym := C.XStringToKeysym(chstr) keycode := C.XKeysymToKeycode(disp, keysym) if debug { fmt.Printf("send key (%s) sym=%v code=%v\n", strname, keysym, keycode) } C.XTestFakeKeyEvent(disp, C.uint(keycode), 1, 0) C.XFlush(disp) C.XTestFakeKeyEvent(disp, C.uint(keycode), 0, 0) C.XFlush(disp) if debug { fmt.Printf("hit key %v (keysym %v keycode %v)\n", strname, keysym, keycode) } fmt.Printf("mod is == %v\n", mod) if mod != 0 { C.XTestFakeKeyEvent(disp, C.uint(mod), 0, 0) C.XFlush(disp) } }
func main() { var dpy *C.Display var attr C.XWindowAttributes var start C.XButtonEvent var ev C.XEvent var ch *C.char if dpy != C.XOpenDisplay(ch) { return } C.XGrabKey( dpy, C.int(C.XKeysymToKeycode(dpy, C.XStringToKeysym(C.CString("F1")))), C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.GrabModeAsync, C.GrabModeAsync, ) C.XGrabButton( dpy, 1, C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.ButtonPressMask|C.ButtonReleaseMask|C.PointerMotionMask, C.GrabModeAsync, C.GrabModeAsync, C.None, C.None, ) C.XGrabButton( dpy, 3, C.Mod1Mask, C.XDefaultRootWindow(dpy), 1, C.ButtonPressMask|C.ButtonReleaseMask|C.PointerMotionMask, C.GrabModeAsync, C.GrabModeAsync, C.None, C.None, ) start.subwindow = C.None for { C.XNextEvent(dpy, &ev) if unionToInt(ev) == C.KeyPress && unionToXKeyEvent(ev).subwindow != C.None { C.XRaiseWindow(dpy, unionToXKeyEvent(ev).subwindow) } else if unionToInt(ev) == C.ButtonPress && unionToXButtonEvent(ev).subwindow != C.None { C.XGetWindowAttributes(dpy, unionToXButtonEvent(ev).subwindow, &attr) start = *unionToXButtonEvent(ev) } else if unionToInt(ev) == C.MotionNotify && start.subwindow != C.None { xdiff := unionToXButtonEvent(ev).x_root - start.x_root ydiff := unionToXButtonEvent(ev).y_root - start.y_root var toDiffX C.int var toDiffY C.int if start.button == 1 { toDiffX = xdiff toDiffY = ydiff } var toWidth C.int var toHeight C.int if start.button == 3 { toWidth = xdiff toHeight = ydiff } C.XMoveResizeWindow( dpy, start.subwindow, attr.x+toDiffX, attr.y+toDiffY, max(1, attr.width+toWidth), max(1, attr.height+toHeight)) } else if unionToInt(ev) == C.ButtonRelease { start.subwindow = C.None } } }
// type a FnKey func (fkey *FnKey) Type(modifiers []string) error { bytes := []byte(fkey.value) keysym := C.XStringToKeysym((*C.char)(unsafe.Pointer(&bytes[0]))) return KeysymType(keysym, modifiers) }