skelterjohn / go.wde

Windows, drawing and events for Go
217 stars 46 forks source link

xgb: listen to KeymapNotify events #37

Closed sqweek closed 10 years ago

sqweek commented 11 years ago

To keep downKeys in sync in the face of focus changes, we must act on KeymapNotify events.

sqweek commented 11 years ago

I could be swung either way on the events thing actually, it seems a little odd to generate key press events for stuff that happened before we gained focus. But it presents nice semantics for clients that want to track the keyboard state themselves via wde.KeyEvent and wde.KeyUpEvent.

I don't generate KeyTypedEvents, that would be REALLY weird :)

sqweek commented 11 years ago

Got a panic with this patch. Dumping the stack here for my reference:

panic: runtime error: index out of range

goroutine 10 [running]: github.com/BurntSushi/xgbutil/keybind.KeysymGetWithMap(0xc2000e3280, 0xc2000002e0, 0x5, 0x4158f6) /usr/lib/go/site/src/github.com/BurntSushi/xgbutil/keybind/keybind.go:262 +0x86 github.com/BurntSushi/xgbutil/keybind.KeysymGet(0xc2000e3280, 0x410005, 0xc200b87050) /usr/lib/go/site/src/github.com/BurntSushi/xgbutil/keybind/keybind.go:251 +0x45 github.com/BurntSushi/xgbutil/keybind.interpretSymList(0xc2000e3280, 0x5, 0x0, 0x0, 0x0, ...) /usr/lib/go/site/src/github.com/BurntSushi/xgbutil/keybind/encoding.go:87 +0xa2 github.com/BurntSushi/xgbutil/keybind.LookupString(0xc2000e3280, 0x50000, 0xc200cda740, 0xc2000b7880) /usr/lib/go/site/src/github.com/BurntSushi/xgbutil/keybind/encoding.go:34 +0x32 github.com/skelterjohn/go.wde/xgb.(*Window).handleEvents(0xc2000ab730) /usr/lib/go/site/src/github.com/skelterjohn/go.wde/xgb/events.go:160 +0xb45 created by github.com/skelterjohn/go.wde/xgb.NewWindow /usr/lib/go/site/src/github.com/skelterjohn/go.wde/xgb/xgb.go:115 +0x583

sqweek commented 10 years ago

The panic is because my keycode math is incorrect. The KeymapNotify event gives us a slice of bytes, where each byte is a bitmask indicating the state of 8 keycodes.

To calculate the keycode represented by a given bit I was doing i*8 + j. This makes sense according to the Xlib man page, which provides 32 bytes = 256 keycodes. However, the first 8 keycodes are not really keys. I suspect they are reserved for modifiers, but whatever the case they are NOT included in the wire protocol.

BurntSushi's xgb sticks closer to the wire protocol and only gives us the 31 bytes that were actually sent instead of sticking an extra 0 byte at the front, resulting in me mapping the bytes to keycodes 0-247 instead of 8-255. Then, when passing a keycode below 8 back into keybind.LookupString it panics.

Will rebase and open new pull request.