mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
exp/textinput: bug fix: issues on browsers
This change addresses on these issues on browsers: * Pressing cursor keys didn't work well. This is fixed by calling trySend with true on desktops (not mobiles). * Inputting failed just after moving a cursor. This is fixed by resetting a session correctly. * Sometimes pressing the enter key inserted a new line unexpectedly. This is fixed by calling `preventDefault`. Closes #3014
This commit is contained in:
parent
22fd1f107e
commit
546c47878d
@ -106,7 +106,7 @@ func (f *Field) HandleInput(x, y int) (handled bool, err error) {
|
|||||||
f.ch, f.end = Start(x, y)
|
f.ch, f.end = Start(x, y)
|
||||||
// Start returns nil for non-supported envrionments.
|
// Start returns nil for non-supported envrionments.
|
||||||
if f.ch == nil {
|
if f.ch == nil {
|
||||||
return true, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ package textinput
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
"github.com/hajimehoshi/ebiten/v2/internal/ui"
|
||||||
@ -79,7 +80,10 @@ func (t *textInput) init() {
|
|||||||
e.Call("preventDefault")
|
e.Call("preventDefault")
|
||||||
}
|
}
|
||||||
if e.Get("code").String() == "Enter" || e.Get("key").String() == "Enter" {
|
if e.Get("code").String() == "Enter" || e.Get("key").String() == "Enter" {
|
||||||
// Ignore Enter key to avoid ebiten.IsKeyPressed(ebiten.KeyEnter) unexpectedly becomes true, especially for iOS Safari.
|
// Ignore Enter key to avoid ebiten.IsKeyPressed(ebiten.KeyEnter) unexpectedly becomes true.
|
||||||
|
e.Call("preventDefault")
|
||||||
|
ui.Get().UpdateInputFromEvent(e)
|
||||||
|
t.trySend(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !e.Get("isComposing").Bool() {
|
if !e.Get("isComposing").Bool() {
|
||||||
@ -96,6 +100,11 @@ func (t *textInput) init() {
|
|||||||
}))
|
}))
|
||||||
t.textareaElement.Call("addEventListener", "input", js.FuncOf(func(this js.Value, args []js.Value) any {
|
t.textareaElement.Call("addEventListener", "input", js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||||
e := args[0]
|
e := args[0]
|
||||||
|
// On iOS Safari, `isComposing` can be undefined.
|
||||||
|
if e.Get("isComposing").IsUndefined() {
|
||||||
|
t.trySend(false)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if e.Get("isComposing").Bool() {
|
if e.Get("isComposing").Bool() {
|
||||||
t.trySend(false)
|
t.trySend(false)
|
||||||
return nil
|
return nil
|
||||||
@ -109,8 +118,12 @@ func (t *textInput) init() {
|
|||||||
t.trySend(true)
|
t.trySend(true)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Though `isComposing` is false, send the text as being not committed for text completion on mobile browsers.
|
// Though `isComposing` is false, send the text as being not committed for text completion with a virtual keyboard.
|
||||||
t.trySend(false)
|
if isVirtualKeyboard() {
|
||||||
|
t.trySend(false)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t.trySend(true)
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
t.textareaElement.Call("addEventListener", "change", js.FuncOf(func(this js.Value, args []js.Value) any {
|
t.textareaElement.Call("addEventListener", "change", js.FuncOf(func(this js.Value, args []js.Value) any {
|
||||||
@ -172,7 +185,13 @@ func (t *textInput) Start(x, y int) (chan State, func()) {
|
|||||||
s := newSession()
|
s := newSession()
|
||||||
t.session = s
|
t.session = s
|
||||||
}
|
}
|
||||||
return t.session.ch, t.session.end
|
return t.session.ch, func() {
|
||||||
|
if t.session != nil {
|
||||||
|
t.session.end()
|
||||||
|
// Reset the session explictly, or a new session cannot be created above.
|
||||||
|
t.session = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.session != nil {
|
if t.session != nil {
|
||||||
@ -193,6 +212,10 @@ func (t *textInput) trySend(committed bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textareaValue := t.textareaElement.Get("value").String()
|
textareaValue := t.textareaElement.Get("value").String()
|
||||||
|
if textareaValue == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
start := t.textareaElement.Get("selectionStart").Int()
|
start := t.textareaElement.Get("selectionStart").Int()
|
||||||
end := t.textareaElement.Get("selectionEnd").Int()
|
end := t.textareaElement.Get("selectionEnd").Int()
|
||||||
startInBytes := convertUTF16CountToByteCount(textareaValue, start)
|
startInBytes := convertUTF16CountToByteCount(textareaValue, start)
|
||||||
@ -213,3 +236,15 @@ func (t *textInput) trySend(committed bool) {
|
|||||||
t.textareaElement.Set("value", "")
|
t.textareaElement.Set("value", "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isVirtualKeyboard() bool {
|
||||||
|
// Detect a virtual keyboard by the user agent.
|
||||||
|
// Note that this is not a correct way to detect a virtual keyboard.
|
||||||
|
// In the future, we should use the `navigator.virtualKeyboard` API.
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/virtualKeyboard
|
||||||
|
ua := js.Global().Get("navigator").Get("userAgent").String()
|
||||||
|
if strings.Contains(ua, "Android") || strings.Contains(ua, "iPhone") || strings.Contains(ua, "iPad") || strings.Contains(ua, "iPod") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user