예제 #1
0
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)
}
예제 #2
0
// connect is essentially 'Connect' for either KeyPress or KeyRelease events.
// Namely, it parses the key string, issues a grab request if necessary,
// sets up the appropriate event handlers for the main event loop, and attaches
// the callback to the keybinding state.
func connect(xu *xgbutil.XUtil, callback xgbutil.CallbackKey,
	evtype int, win xproto.Window, keyStr string, grab, reconnect bool) error {

	// Get the mods/key first
	mods, keycodes, err := ParseString(xu, keyStr)
	if err != nil {
		return err
	}

	// Only do the grab if we haven't yet on this window.
	for _, keycode := range keycodes {
		if grab && keyBindGrabs(xu, evtype, win, mods, keycode) == 0 {
			if err := GrabChecked(xu, win, mods, keycode); err != nil {
				// If a bad access, let's be nice and give a good error message.
				switch err.(type) {
				case xproto.AccessError:
					return fmt.Errorf("Got a bad access error when trying to "+
						"bind '%s'. This usually means another client has "+
						"already grabbed this keybinding.", keyStr)
				default:
					return fmt.Errorf("Could not bind '%s' because: %s",
						keyStr, err)
				}
			}
		}

		// If we've never grabbed anything on this window before, we need to
		// make sure we can respond to it in the main event loop.
		// Never do this if we're reconnecting.
		if !reconnect {
			var allCb xgbutil.Callback
			if evtype == xevent.KeyPress {
				allCb = xevent.KeyPressFun(runKeyPressCallbacks)
			} else {
				allCb = xevent.KeyReleaseFun(runKeyReleaseCallbacks)
			}

			// If this is the first Key{Press|Release}Event on this window,
			// then we need to listen to Key{Press|Release} events in the main
			// loop.
			if !connectedKeyBind(xu, evtype, win) {
				allCb.Connect(xu, win)
			}
		}

		// Finally, attach the callback.
		attachKeyBindCallback(xu, evtype, win, mods, keycode, callback)
	}

	// Keep track of all unique key connections.
	if !reconnect {
		addKeyString(xu, callback, evtype, win, keyStr, grab)
	}

	return nil
}
예제 #3
0
func grabKeyboardAndMouse(m *Manager) {
	if m == nil {
		return
	}

	//go func() {
	X, err := xgbutil.NewConn()
	if err != nil {
		logger.Info("Get New Connection Failed:", err)
		return
	}
	keybind.Initialize(X)
	mousebind.Initialize(X)

	err = keybind.GrabKeyboard(X, X.RootWin())
	if err != nil {
		logger.Info("Grab Keyboard Failed:", err)
		return
	}

	grabAllMouseButton(X)

	xevent.ButtonPressFun(
		func(X *xgbutil.XUtil, e xevent.ButtonPressEvent) {
			dbus.Emit(m, "KeyReleaseEvent", "")
			ungrabAllMouseButton(X)
			keybind.UngrabKeyboard(X)
			logger.Info("Button Press Event")
			xevent.Quit(X)
		}).Connect(X, X.RootWin())

	xevent.KeyPressFun(
		func(X *xgbutil.XUtil, e xevent.KeyPressEvent) {
			value := parseKeyEnvent(X, e.State, e.Detail)
			pressKeyStr = value
			dbus.Emit(m, "KeyPressEvent", value)
		}).Connect(X, X.RootWin())

	xevent.KeyReleaseFun(
		func(X *xgbutil.XUtil, e xevent.KeyReleaseEvent) {
			if strings.ToLower(pressKeyStr) == "super_l" ||
				strings.ToLower(pressKeyStr) == "super_r" {
				pressKeyStr = "Super"
			}

			dbus.Emit(m, "KeyReleaseEvent", pressKeyStr)
			pressKeyStr = ""
			ungrabAllMouseButton(X)
			keybind.UngrabKeyboard(X)
			logger.Infof("Key: %s\n", pressKeyStr)
			xevent.Quit(X)
		}).Connect(X, X.RootWin())

	xevent.Main(X)
	//}()
}
예제 #4
0
func (slct *Select) keyResponse() xevent.KeyPressFun {
	f := func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
		if !slct.showing {
			return
		}

		beforeLen := len(slct.input.Text)
		mods, kc := keybind.DeduceKeyInfo(ev.State, ev.Detail)

		slct.input.Add(mods, kc)

		switch {
		case keybind.KeyMatch(X, slct.config.BackspaceKey, mods, kc):
			slct.input.Remove()
		case keybind.KeyMatch(X, slct.config.CancelKey, mods, kc):
			slct.Hide()
			return
		case keybind.KeyMatch(X, slct.config.ConfirmKey, mods, kc):
			if slct.selected >= 0 && slct.selected < len(slct.items) {
				slct.items[slct.selected].choose()
				slct.Hide()
			} else if len(slct.items) == 1 {
				slct.items[0].choose()
				slct.Hide()
			}
			return
		case keybind.KeyMatch(X, "Tab", mods, kc) ||
			keybind.KeyMatch(X, "ISO_Left_Tab", mods, kc):

			if len(slct.items) == 0 {
				break
			}
			if mods&xproto.ModMaskShift > 0 {
				if slct.selected == -1 {
					slct.selected++
				}
				slct.selected = misc.Mod(slct.selected-1, len(slct.items))
			} else {
				slct.selected = misc.Mod(slct.selected+1, len(slct.items))
			}
			slct.highlight()
		}

		// If the length of the input changed, then re-evaluate completion
		if beforeLen != len(slct.input.Text) {
			slct.FilterItems(string(slct.input.Text))
			slct.selected = -1
			slct.highlight()
		}
	}
	return xevent.KeyPressFun(f)
}
예제 #5
0
func (msg *Message) keyResponse() xevent.KeyPressFun {
	f := func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
		if !msg.showing {
			return
		}

		mods, kc := keybind.DeduceKeyInfo(ev.State, ev.Detail)
		switch {
		case keybind.KeyMatch(X, msg.config.ConfirmKey, mods, kc):
			fallthrough
		case keybind.KeyMatch(X, msg.config.CancelKey, mods, kc):
			msg.Hide()
		}
	}
	return xevent.KeyPressFun(f)
}
예제 #6
0
파일: main.go 프로젝트: droundy/xgbutil
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)
}
예제 #7
0
파일: input.go 프로젝트: Pursuit92/wingo
func (inp *Input) keyResponse() xevent.KeyPressFun {
	f := func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
		if !inp.showing {
			return
		}

		mods, kc := keybind.DeduceKeyInfo(ev.State, ev.Detail)
		switch {
		case keybind.KeyMatch(X, "Up", mods, kc):
			if inp.historyIndex > 0 {
				inp.historyIndex--
				inp.input.SetString(inp.history[inp.historyIndex])
			}
		case keybind.KeyMatch(X, "Down", mods, kc):
			if inp.historyIndex < len(inp.history) {
				inp.historyIndex++
				if inp.historyIndex < len(inp.history) {
					inp.input.SetString(inp.history[inp.historyIndex])
				} else {
					inp.input.Reset()
				}
			}
		case keybind.KeyMatch(X, inp.config.BackspaceKey, mods, kc):
			inp.input.Remove()
		case keybind.KeyMatch(X, inp.config.ConfirmKey, mods, kc):
			if inp.do != nil {
				s := string(inp.input.Text)
				histLen := len(inp.history)

				// Don't added repeated entries.
				if histLen == 0 || s != inp.history[histLen-1] {
					inp.history = append(inp.history, s)
				}
				inp.do(inp, s)
			}
		case keybind.KeyMatch(X, inp.config.CancelKey, mods, kc):
			if inp.canceled != nil {
				inp.canceled(inp)
			}
			inp.Hide()
		default:
			inp.input.Add(mods, kc)
		}
	}
	return xevent.KeyPressFun(f)
}
예제 #8
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())
}
예제 #9
0
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)
}
예제 #10
0
파일: main.go 프로젝트: mkrull/wingo
func main() {
	X, err := xgbutil.NewConn()
	fatal(err)

	// Remember to always initialize the keybind package before usage.
	keybind.Initialize(X)

	// We create a benign parent window. Its only value in this example is
	// instructional. In particular, it shows how to have a sub-window get
	// focus using the ICCCM WM_TAKE_FOCUS protocol. (Since by default,
	// the window manager will assign focus to your top-level window.)
	// The real magic happens below with the WMTakeFocus method call.
	parentWin, err := xwindow.Create(X, X.RootWin())
	fatal(err)

	// NewInput creates a new input window and handles all of the text drawing
	// for you. It can be any width, but the height will be automatically
	// determined by the height extents of the font size chosen.
	input := text.NewInput(X, parentWin.Id, width, padding, font, fontSize,
		fontColor, bgColor)
	parentWin.Resize(input.Geom.Width(), input.Geom.Height())

	// Make sure X reports KeyPress events when this window is focused.
	input.Listen(xproto.EventMaskKeyPress)

	// Listen to KeyPress events. If it's a BackSpace, remove the last
	// character in the input box. If it's "Return" quit. If it's "Escape",
	// clear the input box.
	// Otherwise, try to add the key pressed to the input box.
	// (Not all key presses correspond to a single character that is added.)
	xevent.KeyPressFun(
		func(X *xgbutil.XUtil, ev xevent.KeyPressEvent) {
			mods, kc := ev.State, ev.Detail
			switch {
			case keybind.KeyMatch(X, "BackSpace", mods, kc):
				input.Remove()
			case keybind.KeyMatch(X, "Return", mods, kc):
				log.Println("Return has been pressed.")
				log.Printf("The current text is: %s", string(input.Text))
				log.Println("Quitting...")
				xevent.Quit(X)
			case keybind.KeyMatch(X, "Escape", mods, kc):
				input.Reset()
			default:
				input.Add(mods, kc)
			}
		}).Connect(X, input.Id)

	// Implement the WM_DELETE_WINDOW protocol.
	parentWin.WMGracefulClose(func(w *xwindow.Window) {
		xevent.Quit(X)
	})

	// Implement the WM_TAKE_FOCUS protocol. The callback function provided
	// is executed when a valid WM_TAKE_FOCUS ClientMessage event has been
	// received from the window manager.
	// According to ICCCM Section 4.2.7, this is one of the three valid ways
	// of setting input focus to a sub-window. (It's also easiest since it
	// doesn't require us to monitor FocusChange events. EW.)
	// If you have multiple sub-windows that can be focused, this callback
	// function is where the logic would go to pick which sub-window should
	// be focused upon receipt of a WM_TAKE_FOCUS message.
	parentWin.WMTakeFocus(func(w *xwindow.Window, tstamp xproto.Timestamp) {
		input.FocusParent(tstamp)
	})

	// Map the window and start the main X event loop.
	input.Map()
	parentWin.Map()
	xevent.Main(X)
}
예제 #11
0
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)
}