From 53b248a771f0b271131269f6958a5a520c098c05 Mon Sep 17 00:00:00 2001 From: Trevor Slocum Date: Tue, 19 Nov 2024 00:04:09 -0800 Subject: [PATCH] Improve on-screen keyboard responsiveness --- game.go | 10 ++- kibodo/key.go | 4 + kibodo/keyboard.go | 172 ++++++++++++++++--------------------------- messeji/textfield.go | 2 +- 4 files changed, 74 insertions(+), 114 deletions(-) diff --git a/game.go b/game.go index b1d14a8..ba65ca3 100644 --- a/game.go +++ b/game.go @@ -219,7 +219,7 @@ func Update() error { } } - if activeTouchID == -1 { + if true || activeTouchID == -1 { touchIDs = inpututil.AppendJustPressedTouchIDs(touchIDs[:0]) for _, id := range touchIDs { x, y := ebiten.TouchPosition(id) @@ -260,12 +260,14 @@ func Update() error { } } - if !pressed && !clicked && pressedWidget != nil { - _, err := pressedWidget.HandleMouse(cursor, false, false) + if pressedWidget != nil { + _, err := pressedWidget.HandleMouse(cursor, pressed, clicked) if err != nil { return err } - pressedWidget = nil + if !pressed && !clicked { + pressedWidget = nil + } } mouseHandled, err := update(root, cursor, pressed, clicked, false) diff --git a/kibodo/key.go b/kibodo/key.go index 7382798..69e45b5 100644 --- a/kibodo/key.go +++ b/kibodo/key.go @@ -1,6 +1,8 @@ package kibodo import ( + "time" + "github.com/hajimehoshi/ebiten/v2" ) @@ -16,7 +18,9 @@ type Key struct { w, h int pressed bool + pressedTime time.Time pressedTouchID ebiten.TouchID + repeatTime time.Time } // Input represents the input event from a key press. diff --git a/kibodo/keyboard.go b/kibodo/keyboard.go index 4a0c917..c348a3d 100644 --- a/kibodo/keyboard.go +++ b/kibodo/keyboard.go @@ -273,6 +273,13 @@ func (k *Keyboard) handleHideKey(inputKey ebiten.Key) bool { // Hit handles a key press. func (k *Keyboard) Hit(key *Key) { + now := time.Now() + if !key.pressedTime.IsZero() && now.Sub(key.pressedTime) < 50*time.Millisecond { + return + } + key.pressedTime = now + key.repeatTime = now.Add(k.backspaceDelay) + input := key.LowerInput if k.shift { input = key.UpperInput @@ -298,21 +305,11 @@ func (k *Keyboard) HandleMouse(cursor image.Point, pressed bool, clicked bool) ( k.backgroundDirty = false } - pressDuration := 50 * time.Millisecond - if k.wasPressed && !pressed && !clicked { + //pressDuration := 50 * time.Millisecond + if clicked { var key *Key if cursor.X != 0 || cursor.Y != 0 { key = k.at(cursor.X, cursor.Y) - } else { - PRESSKEY: - for _, rowKeys := range k.keys { - for _, rowKey := range rowKeys { - if rowKey.pressed { - key = rowKey - break PRESSKEY - } - } - } } for _, rowKeys := range k.keys { for _, rowKey := range rowKeys { @@ -326,48 +323,23 @@ func (k *Keyboard) HandleMouse(cursor image.Point, pressed bool, clicked bool) ( key.pressed = true k.Hit(key) - - go func() { - time.Sleep(pressDuration) - - key.pressed = false - if k.scheduleFrameFunc != nil { - k.scheduleFrameFunc() - } - }() } - k.wasPressed = false + k.wasPressed = true } else if pressed { key := k.at(cursor.X, cursor.Y) if key != nil { - if !key.pressed { - input := key.LowerInput - if k.shift { - input = key.UpperInput - } - - // Repeat backspace and delete operations. - if input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete { - k.backspaceLast = time.Now().Add(k.backspaceDelay) - } - go func() { - t := time.NewTicker(k.backspaceRepeat) - for { - <-t.C - - if !key.pressed { - t.Stop() - return - } - - if (input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete) && time.Since(k.backspaceLast) >= k.backspaceRepeat { - k.backspaceLast = time.Now() - k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) - } - } - - }() + // Repeat backspace and delete operations. + input := key.LowerInput + if k.shift { + input = key.UpperInput } + if input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete { + for time.Since(key.repeatTime) >= k.backspaceRepeat { + k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) + key.repeatTime = key.repeatTime.Add(k.backspaceRepeat) + } + } + key.pressed = true k.wasPressed = true @@ -380,6 +352,15 @@ func (k *Keyboard) HandleMouse(cursor image.Point, pressed bool, clicked bool) ( } } } + } else if k.wasPressed { + for _, rowKeys := range k.keys { + for _, rowKey := range rowKeys { + if !rowKey.pressed { + continue + } + rowKey.pressed = false + } + } } return true, nil } @@ -416,12 +397,14 @@ func (k *Keyboard) Update() error { } } } + // Handle mouse input + var key *Key pressDuration := 50 * time.Millisecond - if inpututil.IsMouseButtonJustReleased(ebiten.MouseButtonLeft) { + if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) { x, y := ebiten.CursorPosition() - key := k.at(x, y) + key = k.at(x, y) if key != nil { for _, rowKeys := range k.keys { for _, rowKey := range rowKeys { @@ -441,10 +424,12 @@ func (k *Keyboard) Update() error { } }() } + + k.wasPressed = true } else if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) { x, y := ebiten.CursorPosition() - key := k.at(x, y) + key = k.at(x, y) if key != nil { if !key.pressed { input := key.LowerInput @@ -454,25 +439,11 @@ func (k *Keyboard) Update() error { // Repeat backspace and delete operations. if input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete { - k.backspaceLast = time.Now().Add(k.backspaceDelay) - } - go func() { - t := time.NewTicker(k.backspaceRepeat) - for { - <-t.C - - if !key.pressed { - t.Stop() - return - } - - if (input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete) && time.Since(k.backspaceLast) >= k.backspaceRepeat { - k.backspaceLast = time.Now() - k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) - } + for time.Since(key.repeatTime) >= k.backspaceRepeat { + k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) + key.repeatTime = key.repeatTime.Add(k.backspaceRepeat) } - - }() + } } key.pressed = true @@ -485,20 +456,24 @@ func (k *Keyboard) Update() error { } } } + + k.wasPressed = true } + // Handle touch input if k.holdTouchID != -1 { x, y := ebiten.TouchPosition(k.holdTouchID) if x == 0 && y == 0 { k.holdTouchID = -1 } else { - key := k.at(x, y) + key = k.at(x, y) if key != k.holdKey { k.holdTouchID = -1 return nil } //k.Hold(key) k.holdKey = key + k.wasPressed = true } } if k.holdTouchID == -1 { @@ -506,7 +481,7 @@ func (k *Keyboard) Update() error { for _, id := range k.touchIDs { x, y := ebiten.TouchPosition(id) - key := k.at(x, y) + key = k.at(x, y) if key != nil { input := key.LowerInput if k.shift { @@ -533,48 +508,27 @@ func (k *Keyboard) Update() error { if input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete { k.backspaceLast = time.Now().Add(k.backspaceDelay) } - - go func() { - var touchIDs []ebiten.TouchID - t := time.NewTicker(pressDuration) - for range t.C { - touchIDs = ebiten.AppendTouchIDs(touchIDs[:0]) - - var found bool - for _, touchID := range touchIDs { - if id == touchID { - found = true - break - } - } - - if found { - tx, ty := ebiten.TouchPosition(id) - if tx != 0 || ty != 0 { - x, y = tx, ty - } - } - - if !found { - key.pressed = false - if k.scheduleFrameFunc != nil { - k.scheduleFrameFunc() - } - t.Stop() - return - } - - // Repeat backspace and delete operations. - if (input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete) && time.Since(k.backspaceLast) >= k.backspaceRepeat { - k.backspaceLast = time.Now() - k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) - } + } else { + // Repeat backspace and delete operations. + if input.Key == ebiten.KeyBackspace || input.Key == ebiten.KeyDelete { + for time.Since(k.backspaceLast) >= k.backspaceRepeat { + k.inputEvents = append(k.inputEvents, &Input{Key: input.Key}) + k.backspaceLast = k.backspaceLast.Add(k.backspaceRepeat) } - }() + } } + k.wasPressed = true } } } + for _, rowKeys := range k.keys { + for _, rowKey := range rowKeys { + if rowKey == key || !rowKey.pressed { + continue + } + rowKey.pressed = false + } + } return nil } diff --git a/messeji/textfield.go b/messeji/textfield.go index ae0fbff..dc251c1 100644 --- a/messeji/textfield.go +++ b/messeji/textfield.go @@ -751,7 +751,7 @@ func (f *TextField) HandleMouseEvent(cursor image.Point, pressed bool, clicked b } func (f *TextField) _handleMouseEvent(cursor image.Point, pressed bool, clicked bool) (handled bool, err error) { - if !cursor.In(f.r) { + if !f.scrollDrag && !cursor.In(f.r) { return false, nil }