Repeated keys are detected properly
The repeated bool was removed and instead key release events are *only* sent when the key is actually let go. If an element wants to listen to repeat presses, it can just listen to press events.
This commit is contained in:
parent
2f53c942ac
commit
72f604e819
@ -67,6 +67,23 @@ func (window *Window) handleConfigureNotify (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (window *Window) modifiersFromState (
|
||||||
|
state uint16,
|
||||||
|
) (
|
||||||
|
modifiers tomo.Modifiers,
|
||||||
|
) {
|
||||||
|
return tomo.Modifiers {
|
||||||
|
Shift:
|
||||||
|
(state & xproto.ModMaskShift) > 0 ||
|
||||||
|
(state & window.backend.modifierMasks.shiftLock) > 0,
|
||||||
|
Control: (state & xproto.ModMaskControl) > 0,
|
||||||
|
Alt: (state & window.backend.modifierMasks.alt) > 0,
|
||||||
|
Meta: (state & window.backend.modifierMasks.meta) > 0,
|
||||||
|
Super: (state & window.backend.modifierMasks.super) > 0,
|
||||||
|
Hyper: (state & window.backend.modifierMasks.hyper) > 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (window *Window) handleKeyPress (
|
func (window *Window) handleKeyPress (
|
||||||
connection *xgbutil.XUtil,
|
connection *xgbutil.XUtil,
|
||||||
event xevent.KeyPressEvent,
|
event xevent.KeyPressEvent,
|
||||||
@ -75,17 +92,8 @@ func (window *Window) handleKeyPress (
|
|||||||
|
|
||||||
keyEvent := *event.KeyPressEvent
|
keyEvent := *event.KeyPressEvent
|
||||||
key, numberPad := window.backend.keycodeToKey(keyEvent.Detail, keyEvent.State)
|
key, numberPad := window.backend.keycodeToKey(keyEvent.Detail, keyEvent.State)
|
||||||
modifiers := tomo.Modifiers {
|
modifiers := window.modifiersFromState(keyEvent.State)
|
||||||
Shift:
|
modifiers.NumberPad = numberPad
|
||||||
(keyEvent.State & xproto.ModMaskShift) > 0 ||
|
|
||||||
(keyEvent.State & window.backend.modifierMasks.shiftLock) > 0,
|
|
||||||
Control: (keyEvent.State & xproto.ModMaskControl) > 0,
|
|
||||||
Alt: (keyEvent.State & window.backend.modifierMasks.alt) > 0,
|
|
||||||
Meta: (keyEvent.State & window.backend.modifierMasks.meta) > 0,
|
|
||||||
Super: (keyEvent.State & window.backend.modifierMasks.super) > 0,
|
|
||||||
Hyper: (keyEvent.State & window.backend.modifierMasks.hyper) > 0,
|
|
||||||
NumberPad: numberPad,
|
|
||||||
}
|
|
||||||
|
|
||||||
if key == tomo.KeyTab && modifiers.Alt {
|
if key == tomo.KeyTab && modifiers.Alt {
|
||||||
if child, ok := window.child.(tomo.Selectable); ok {
|
if child, ok := window.child.(tomo.Selectable); ok {
|
||||||
@ -99,8 +107,7 @@ func (window *Window) handleKeyPress (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
} else if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||||
// FIXME: pass correct value for repeated
|
child.HandleKeyDown(key, modifiers)
|
||||||
child.HandleKeyDown(key, modifiers, false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,18 +118,27 @@ func (window *Window) handleKeyRelease (
|
|||||||
if window.child == nil { return }
|
if window.child == nil { return }
|
||||||
|
|
||||||
keyEvent := *event.KeyReleaseEvent
|
keyEvent := *event.KeyReleaseEvent
|
||||||
key, numberPad := window.backend.keycodeToKey(keyEvent.Detail, keyEvent.State)
|
|
||||||
modifiers := tomo.Modifiers {
|
// do not process this event if it was generated from a key repeat
|
||||||
Shift:
|
nextEvents := xevent.Peek(window.backend.connection)
|
||||||
(keyEvent.State & xproto.ModMaskShift) > 0 ||
|
if len(nextEvents) > 0 {
|
||||||
(keyEvent.State & window.backend.modifierMasks.shiftLock) > 0,
|
untypedEvent := nextEvents[0]
|
||||||
Control: (keyEvent.State & xproto.ModMaskControl) > 0,
|
if untypedEvent.Err == nil {
|
||||||
Alt: (keyEvent.State & window.backend.modifierMasks.alt) > 0,
|
typedEvent, ok :=
|
||||||
Meta: (keyEvent.State & window.backend.modifierMasks.meta) > 0,
|
untypedEvent.Event.(xproto.KeyReleaseEvent)
|
||||||
Super: (keyEvent.State & window.backend.modifierMasks.super) > 0,
|
|
||||||
Hyper: (keyEvent.State & window.backend.modifierMasks.hyper) > 0,
|
if ok && typedEvent.Detail == keyEvent.Detail &&
|
||||||
NumberPad: numberPad,
|
typedEvent.Event == keyEvent.Event &&
|
||||||
|
typedEvent.State == keyEvent.State {
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key, numberPad := window.backend.keycodeToKey(keyEvent.Detail, keyEvent.State)
|
||||||
|
modifiers := window.modifiersFromState(keyEvent.State)
|
||||||
|
modifiers.NumberPad = numberPad
|
||||||
|
|
||||||
if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
if child, ok := window.child.(tomo.KeyboardTarget); ok {
|
||||||
child.HandleKeyUp(key, modifiers)
|
child.HandleKeyUp(key, modifiers)
|
||||||
|
12
element.go
12
element.go
@ -86,12 +86,12 @@ type Selectable interface {
|
|||||||
type KeyboardTarget interface {
|
type KeyboardTarget interface {
|
||||||
Element
|
Element
|
||||||
|
|
||||||
// HandleKeyDown is called when a key is pressed down while this element
|
// HandleKeyDown is called when a key is pressed down or repeated while
|
||||||
// has keyboard focus. It is important to note that not every key down
|
// this element has keyboard focus. It is important to note that not
|
||||||
// event is guaranteed to be paired with exactly one key up event. This
|
// every key down event is guaranteed to be paired with exactly one key
|
||||||
// is the reason a list of modifier keys held down at the time of the
|
// up event. This is the reason a list of modifier keys held down at the
|
||||||
// key press is given.
|
// time of the key press is given.
|
||||||
HandleKeyDown (key Key, modifiers Modifiers, repeated bool)
|
HandleKeyDown (key Key, modifiers Modifiers)
|
||||||
|
|
||||||
// HandleKeyUp is called when a key is released while this element has
|
// HandleKeyUp is called when a key is released while this element has
|
||||||
// keyboard focus.
|
// keyboard focus.
|
||||||
|
@ -68,11 +68,7 @@ func (element *Button) HandleMouseUp (x, y int, button tomo.Button) {
|
|||||||
func (element *Button) HandleMouseMove (x, y int) { }
|
func (element *Button) HandleMouseMove (x, y int) { }
|
||||||
func (element *Button) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
func (element *Button) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
||||||
|
|
||||||
func (element *Button) HandleKeyDown (
|
func (element *Button) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) {
|
||||||
key tomo.Key,
|
|
||||||
modifiers tomo.Modifiers,
|
|
||||||
repeated bool,
|
|
||||||
) {
|
|
||||||
if !element.enabled { return }
|
if !element.enabled { return }
|
||||||
if key == tomo.KeyEnter {
|
if key == tomo.KeyEnter {
|
||||||
element.pressed = true
|
element.pressed = true
|
||||||
|
@ -70,11 +70,7 @@ func (element *Checkbox) HandleMouseUp (x, y int, button tomo.Button) {
|
|||||||
func (element *Checkbox) HandleMouseMove (x, y int) { }
|
func (element *Checkbox) HandleMouseMove (x, y int) { }
|
||||||
func (element *Checkbox) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
func (element *Checkbox) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
||||||
|
|
||||||
func (element *Checkbox) HandleKeyDown (
|
func (element *Checkbox) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) {
|
||||||
key tomo.Key,
|
|
||||||
modifiers tomo.Modifiers,
|
|
||||||
repeated bool,
|
|
||||||
) {
|
|
||||||
if key == tomo.KeyEnter {
|
if key == tomo.KeyEnter {
|
||||||
element.pressed = true
|
element.pressed = true
|
||||||
if element.core.HasImage() {
|
if element.core.HasImage() {
|
||||||
|
@ -235,15 +235,11 @@ func (element *Container) HandleMouseScroll (x, y int, deltaX, deltaY float64) {
|
|||||||
child.HandleMouseScroll(x - childPosition.X, y - childPosition.Y, deltaX, deltaY)
|
child.HandleMouseScroll(x - childPosition.X, y - childPosition.Y, deltaX, deltaY)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *Container) HandleKeyDown (
|
func (element *Container) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) {
|
||||||
key tomo.Key,
|
|
||||||
modifiers tomo.Modifiers,
|
|
||||||
repeated bool,
|
|
||||||
) {
|
|
||||||
element.forSelected (func (child tomo.Selectable) bool {
|
element.forSelected (func (child tomo.Selectable) bool {
|
||||||
child0, handlesKeyboard := child.(tomo.KeyboardTarget)
|
child0, handlesKeyboard := child.(tomo.KeyboardTarget)
|
||||||
if handlesKeyboard {
|
if handlesKeyboard {
|
||||||
child0.HandleKeyDown(key, modifiers, repeated)
|
child0.HandleKeyDown(key, modifiers)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -93,13 +93,9 @@ func (element *ScrollContainer) Adopt (child tomo.Scrollable) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (element *ScrollContainer) HandleKeyDown (
|
func (element *ScrollContainer) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) {
|
||||||
key tomo.Key,
|
|
||||||
modifiers tomo.Modifiers,
|
|
||||||
repeated bool,
|
|
||||||
) {
|
|
||||||
if child, ok := element.child.(tomo.KeyboardTarget); ok {
|
if child, ok := element.child.(tomo.KeyboardTarget); ok {
|
||||||
child.HandleKeyDown(key, modifiers, repeated)
|
child.HandleKeyDown(key, modifiers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ type TextBox struct {
|
|||||||
placeholderDrawer artist.TextDrawer
|
placeholderDrawer artist.TextDrawer
|
||||||
valueDrawer artist.TextDrawer
|
valueDrawer artist.TextDrawer
|
||||||
|
|
||||||
onKeyDown func (tomo.Key, tomo.Modifiers, bool) (bool)
|
onKeyDown func (key tomo.Key, modifiers tomo.Modifiers) (handled bool)
|
||||||
onChange func ()
|
onChange func ()
|
||||||
onSelectionRequest func () (granted bool)
|
onSelectionRequest func () (granted bool)
|
||||||
onSelectionMotionRequest func (tomo.SelectionDirection) (granted bool)
|
onSelectionMotionRequest func (tomo.SelectionDirection) (granted bool)
|
||||||
@ -63,12 +63,8 @@ func (element *TextBox) HandleMouseUp (x, y int, button tomo.Button) { }
|
|||||||
func (element *TextBox) HandleMouseMove (x, y int) { }
|
func (element *TextBox) HandleMouseMove (x, y int) { }
|
||||||
func (element *TextBox) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
func (element *TextBox) HandleMouseScroll (x, y int, deltaX, deltaY float64) { }
|
||||||
|
|
||||||
func (element *TextBox) HandleKeyDown (
|
func (element *TextBox) HandleKeyDown(key tomo.Key, modifiers tomo.Modifiers) {
|
||||||
key tomo.Key,
|
if element.onKeyDown != nil && element.onKeyDown(key, modifiers) {
|
||||||
modifiers tomo.Modifiers,
|
|
||||||
repeated bool,
|
|
||||||
) {
|
|
||||||
if element.onKeyDown != nil && element.onKeyDown(key, modifiers, repeated) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +228,7 @@ func (element *TextBox) Filled () (filled bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (element *TextBox) OnKeyDown (
|
func (element *TextBox) OnKeyDown (
|
||||||
callback func (
|
callback func (key tomo.Key, modifiers tomo.Modifiers) (handled bool),
|
||||||
key tomo.Key, modifiers tomo.Modifiers, repeated bool,
|
|
||||||
) (
|
|
||||||
handled bool,
|
|
||||||
),
|
|
||||||
) {
|
) {
|
||||||
element.onKeyDown = callback
|
element.onKeyDown = callback
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user