-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve support for keyboard input on mobile browsers #21960
Comments
Do you know if SDL2 has the same issues? I general I would expect SDL2 support to be more advanced than the SDL1/js code. |
I was referring to SDL2, I've never tried SDL1. |
Adding @Daft-Freak. |
Well I've got my personal solution working, which can be seen here: https://curiousdannii.github.io/infocom-frotz/zorkzero.html <textarea id="textinput" autocapitalize="off" rows="1"></textarea> #textinput {
position: absolute;
left: -10000px;
} const textinput_elem = document.getElementById('textinput')
Module.canvas = document.getElementById('canvas')
// Mobile input event handlers
Module.canvas.addEventListener('touchstart', ev => {
textinput_elem.focus()
})
textinput_elem.addEventListener('input', ev => {
const char = ev.data
if (char) {
const char_keycode = char.codePointAt(0)
const upper_key = char.toUpperCase()
const upper_keycode = upper_key.codePointAt(0)
const down_up_options = {
code: 'Key' + upper_key,
key: char,
keyCode: upper_keycode,
which: upper_keycode,
}
window.dispatchEvent(new KeyboardEvent('keydown', down_up_options))
window.dispatchEvent(new KeyboardEvent('keypress', {
charCode: char_keycode,
code: 'Key' + upper_key,
key: char,
keyCode: char_keycode,
which: char_keycode,
}))
window.dispatchEvent(new KeyboardEvent('keyup', down_up_options))
}
// To fully reset we have to clear the value then blur and refocus, otherwise Android will keep trying to do its IME magic, which we don't want.
textinput_elem.value = ''
textinput_elem.blur()
textinput_elem.focus()
ev.preventDefault()
ev.stopPropagation()
})
textinput_elem.addEventListener('keydown', ev => {
if (ev.which === 8) {
const options = {
code: 'Backspace',
key: 'Backspace',
keyCode: 8,
which: 8,
}
window.dispatchEvent(new KeyboardEvent('keydown', options))
window.dispatchEvent(new KeyboardEvent('keyup', options))
ev.preventDefault()
ev.stopPropagation()
}
if (ev.which === 13) {
const options = {
charCode: 13,
code: 'Enter',
key: 'Enter',
keyCode: 13,
which: 13,
}
window.dispatchEvent(new KeyboardEvent('keydown', options))
window.dispatchEvent(new KeyboardEvent('keypress', options))
window.dispatchEvent(new KeyboardEvent('keyup', options))
ev.preventDefault()
ev.stopPropagation()
}
if (ev.which === 229) {
ev.preventDefault()
ev.stopPropagation()
}
})
textinput_elem.addEventListener('keyup', ev => {
if (ev.which === 8 || ev.which === 13 || ev.which === 229) {
ev.preventDefault()
ev.stopPropagation()
}
}) Basically when an |
Mobile browsers (with virtual keyboards) don't support
keypress
events, and forkeydown
events set the code to 229 for most keys. But, there is pretty good support through theinput
event - at least it supports all actual textual input keys plus the backspace key (one of the few keys actually returned inkeydown
events). It would be good if Emscripten (and then SDL) supported theinput
event with little/no manual work by the user.(I just discovered something new: the
input
event doesn't seem to fire if Chrome dev tools have breakpoints in the event handler. Makes it very hard to test and debug these events! This did not used to be the case.)What this might involve:
input
event won't fire on document or window. This should be a<textarea>
not an<input>
because of this other unfixed Chrome bug.input
event needs to be handled differently, as it has different properties, or you can access what was typed via the textarea's.value
. When I've used it (not in an Emscripten project) I also had to empty it each time. And if the character was space, blur then refocus, as otherwise it thinks there are still spaces and backspace doesn't work.emscripten_set_keydown_callback_on_thread
and then using it in SDL. I don't know if it could be directly used or if it would need to be mapped into something more like akeydown
event.keydown
events which have a code of 229 and don't send them to the wasm? That's what I've previously done, but it may not be necessary.The text was updated successfully, but these errors were encountered: