Avoid interrupting keyboard input while handling a keypress. How? #7
Replies: 2 comments
-
I don't know the answer, but I asked ChatGPT for you. Here's the reply: The basic issue is that “grabbing” the keyboard – whether explicitly (via XGrabKeyboard) or indirectly (by using an event‐hook that “steals” events) – causes the X server not to deliver those key events to other clients. To log keys without “eating” them, you have two general options:
In short, the “solution” is to either use a passive (noninvasive) approach like XRecord or, if you must grab, then explicitly allow events to continue by calling the appropriate function (e.g. XAllowEvents) after you log each key. This way, your program both logs the event and then “passes it along” to the rest of the system. For more details on how to use XAllowEvents with xgbutil, see the discussion in the xgbutil documentation and examples (for instance, note how the CallbackMouse’s synchronous grab requires you to call xproto.AllowEvents to avoid locking up the event loop https://pkg.go.dev/github.com/alex11br/xgbutil). I hope this helps clarify the options available for logging key events without disrupting normal input! Was this helpfull? |
Beta Was this translation helpful? Give feedback.
-
Thank you. ChatGPT is the first thing I've tried. Here is the code: package main
import (
"log"
"time"
"github.com/jezek/xgb/xproto"
"github.com/jezek/xgbutil"
"github.com/jezek/xgbutil/keybind"
"github.com/jezek/xgbutil/xevent"
)
func main() {
X, err := xgbutil.NewConn()
if err != nil {
log.Fatal(err)
}
keybind.Initialize(X)
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)
}
}
// xevent.SendRootEvent(X, e, xproto.EventMaskKeyPress)
xproto.AllowEvents(X.Conn(), xproto.AllowAsyncKeyboard, e.Time)
}).Connect(X, X.RootWin())
if err := keybind.GrabKeyboard(X, X.RootWin()); err != nil {
log.Fatalf("Could not grab keyboard: %s", err)
}
xevent.Main(X)
} Can anyone who has better |
Beta Was this translation helpful? Give feedback.
-
Hey!
I'm playing around with a keylogger-like example keypress-english and noticed that in root mode it intercepts all keyboard input so all applications don't receive any key events until the program exits.
I want to rewrite my old layout-switcher from Python to Go. So I need to log keyboard events without interrupting keyboard input.
How do you pass events further but keep logging them?
Beta Was this translation helpful? Give feedback.
All reactions