Add proper and reliable (i hope) support for modifier keys

This commit is contained in:
Sasha Koshka 2022-11-22 00:21:35 -05:00
parent 8c28c57925
commit ae514f5ae2
8 changed files with 38 additions and 15 deletions

View File

@ -45,7 +45,7 @@ func (application *Application) OnQuit (
// OnPress registers an event handler to be called when a key or mouse button // OnPress registers an event handler to be called when a key or mouse button
// is pressed. // is pressed.
func (application *Application) OnPress ( func (application *Application) OnPress (
onPress func (button Button), onPress func (button Button, modifiers Modifiers),
) { ) {
application.callbackManager.onPress = onPress application.callbackManager.onPress = onPress
} }

View File

@ -91,7 +91,9 @@ func (backend *Backend) handleButtonPress (
backend.compressScrollSum(&sum) backend.compressScrollSum(&sum)
backend.callbackManager.RunScroll(sum.x, sum.y) backend.callbackManager.RunScroll(sum.x, sum.y)
} else { } else {
backend.callbackManager.RunPress(stone.Button(buttonEvent.Detail + 127)) backend.callbackManager.RunPress (
stone.Button(buttonEvent.Detail + 127),
stone.Modifiers { })
} }
} }
@ -110,7 +112,15 @@ func (backend *Backend) handleKeyPress (
) { ) {
keyEvent := *event.KeyPressEvent keyEvent := *event.KeyPressEvent
button := backend.keycodeToButton(keyEvent.Detail, keyEvent.State) button := backend.keycodeToButton(keyEvent.Detail, keyEvent.State)
backend.callbackManager.RunPress(button) backend.callbackManager.RunPress (button, stone.Modifiers {
// FIXME these may not be correct in all cases
Shift: (keyEvent.State & xproto.ModMaskShift) > 0,
Control: (keyEvent.State & xproto.ModMaskControl) > 0,
Alt: (keyEvent.State & xproto.ModMask1) > 0,
// Meta: (keyEvent.State & xproto.??) > 0,
Super: (keyEvent.State & xproto.ModMask4) > 0,
// Hyper: (keyEvent.State & xproto.??) > 0,
})
} }
func (backend *Backend) handleKeyRelease ( func (backend *Backend) handleKeyRelease (

View File

@ -1,6 +1,6 @@
package x package x
import "fmt" // import "fmt"
import "unicode" import "unicode"
import "github.com/jezek/xgb/xproto" import "github.com/jezek/xgb/xproto"
import "github.com/jezek/xgbutil/keybind" import "github.com/jezek/xgbutil/keybind"
@ -138,7 +138,7 @@ func (backend *Backend) keycodeToButton (
var selectedKeysym xproto.Keysym var selectedKeysym xproto.Keysym
var selectedRune rune var selectedRune rune
fmt.Printf("AAA\t%X\t%X\t%X\t%X\n", symbol1, symbol2, symbol3, symbol4) // fmt.Printf("AAA\t%X\t%X\t%X\t%X\n", symbol1, symbol2, symbol3, symbol4)
// big ol list in the middle // big ol list in the middle
switch { switch {

View File

@ -2,7 +2,7 @@ package stone
type CallbackManager struct { type CallbackManager struct {
onQuit func () onQuit func ()
onPress func (button Button) onPress func (button Button, modifiers Modifiers)
onRelease func (button Button) onRelease func (button Button)
onResize func () onResize func ()
onMouseMove func (x, y int) onMouseMove func (x, y int)
@ -15,9 +15,9 @@ func (manager *CallbackManager) RunQuit () {
manager.onQuit() manager.onQuit()
} }
func (manager *CallbackManager) RunPress (button Button) { func (manager *CallbackManager) RunPress (button Button, modifiers Modifiers) {
if manager.onPress == nil { return } if manager.onPress == nil { return }
manager.onPress(button) manager.onPress(button, modifiers)
} }
func (manager *CallbackManager) RunRelease (button Button) { func (manager *CallbackManager) RunRelease (button Button) {

View File

@ -34,7 +34,7 @@ func main () {
if err != nil { panic(err) } if err != nil { panic(err) }
} }
func onPress (button stone.Button) { func onPress (button stone.Button, modifiers stone.Modifiers) {
if button == stone.MouseButtonLeft { if button == stone.MouseButtonLeft {
mousePressed = true mousePressed = true
application.SetRune(0, 0, '+') application.SetRune(0, 0, '+')

View File

@ -32,7 +32,7 @@ func main () {
if err != nil { panic(err) } if err != nil { panic(err) }
} }
func onPress (button stone.Button) { func onPress (button stone.Button, modifiers stone.Modifiers) {
println("press", button) println("press", button)
} }

View File

@ -55,7 +55,7 @@ func drawCaret () {
application.SetColor(caretX, caretY, stone.ColorDim) application.SetColor(caretX, caretY, stone.ColorDim)
} }
func onPress (button stone.Button) { func onPress (button stone.Button, modifiers stone.Modifiers) {
width, height := application.Size() width, height := application.Size()
if button == stone.KeyEnter { if button == stone.KeyEnter {

View File

@ -33,10 +33,10 @@ const (
KeyRightShift Button = 21 KeyRightShift Button = 21
KeyLeftControl Button = 22 KeyLeftControl Button = 22
KeyRightControl Button = 23 KeyRightControl Button = 23
KeyLeftMeta Button = 24 KeyLeftAlt Button = 24
KeyRightMeta Button = 25 KeyRightAlt Button = 25
KeyLeftAlt Button = 26 KeyLeftMeta Button = 26
KeyRightAlt Button = 27 KeyRightMeta Button = 27
KeyLeftSuper Button = 28 KeyLeftSuper Button = 28
KeyRightSuper Button = 29 KeyRightSuper Button = 29
KeyLeftHyper Button = 30 KeyLeftHyper Button = 30
@ -82,3 +82,16 @@ func (button Button) Printable () (printable bool) {
printable = unicode.IsPrint(rune(button)) printable = unicode.IsPrint(rune(button))
return return
} }
// Modifiers lists what modifier keys are being pressed. This is used in
// conjunction with a button code in a button press event. These should be used
// instead of attempting to track the state of the modifier keys, because there
// is no guarantee that one press event will be coupled with one release event.
type Modifiers struct {
Shift bool
Control bool
Alt bool
Meta bool
Super bool
Hyper bool
}