Fix mobile keyboard behavior (#522)

* keep only openMobileKeyboard, do not focus when touch device.

* do not test for hover when checking touch device.
This commit is contained in:
Miroslav Šedivý 2025-04-26 11:55:55 +02:00 committed by GitHub
parent 23820f6255
commit f145bd58c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -65,7 +65,7 @@
<li <li
v-if="hosting && is_touch_device" v-if="hosting && is_touch_device"
:class="extraControls || 'extra-control'" :class="extraControls || 'extra-control'"
@click.stop.prevent="toggleMobileKeyboard" @click.stop.prevent="openMobileKeyboard"
> >
<i class="fas fa-keyboard" /> <i class="fas fa-keyboard" />
</li> </li>
@ -367,12 +367,11 @@
get is_touch_device() { get is_touch_device() {
return ( return (
// check if the device has a touch screen // detect if the device has touch support
('ontouchstart' in window || navigator.maxTouchPoints > 0) && ('ontouchstart' in window || navigator.maxTouchPoints > 0) &&
// we also check if the device has a pointer // the primary input mechanism includes a pointing device of
!window.matchMedia('(pointer:fine)').matches && // limited accuracy, such as a finger on a touchscreen.
// and is capable of hover, then it probably has a mouse window.matchMedia('(pointer: coarse)').matches
!window.matchMedia('(hover:hover)').matches
) )
} }
@ -822,64 +821,20 @@
@Watch('hosting') @Watch('hosting')
@Watch('locked') @Watch('locked')
onFocus() { onFocus() {
// focus opens the keyboard on mobile
if (!this.is_touch_device) {
return
}
// in order to capture key events, overlay must be focused // in order to capture key events, overlay must be focused
if (this.focused && this.hosting && !this.locked) { if (this.focused && this.hosting && !this.locked) {
this._overlay.focus() this._overlay.focus()
} }
} }
// openMobileKeyboard() {
// mobile keyboard // focus opens the keyboard on mobile
// this._overlay.focus()
kbdShow = false
kbdOpen = false
showMobileKeyboard() {
// skip if not a touch device
if (!this.is_touch_device) return
this.kbdShow = true
this.kbdOpen = false
const overlay = this.$refs.overlay as HTMLTextAreaElement
overlay.focus()
window.visualViewport?.addEventListener('resize', this.onVisualViewportResize)
}
hideMobileKeyboard() {
// skip if not a touch device
if (!this.is_touch_device) return
this.kbdShow = false
this.kbdOpen = false
const overlay = this.$refs.overlay as HTMLTextAreaElement
window.visualViewport?.removeEventListener('resize', this.onVisualViewportResize)
overlay.blur()
}
toggleMobileKeyboard() {
// skip if not a touch device
if (!this.is_touch_device) return
if (this.kbdShow) {
this.hideMobileKeyboard()
} else {
this.showMobileKeyboard()
}
}
// visual viewport resize event is fired when keyboard is opened or closed
// android does not blur textarea when keyboard is closed, so we need to do it manually
onVisualViewportResize() {
if (!this.kbdShow) return
if (!this.kbdOpen) {
this.kbdOpen = true
} else {
this.hideMobileKeyboard()
}
} }
} }
</script> </script>