Skip to content

Commit

Permalink
add basic ime support for web browsers on mobile devices
Browse files Browse the repository at this point in the history
  • Loading branch information
jershell committed Feb 8, 2024
1 parent 2458969 commit 691b10e
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@

package androidx.compose.foundation.text

internal actual val isInTouchMode = false
internal actual val isInTouchMode = true
3 changes: 1 addition & 2 deletions compose/mpp/demo/src/jsMain/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
<title>compose multiplatform web demo</title>
<script src="skiko.js"> </script>
<link type="text/css" rel="stylesheet" href="styles.css">
</head>

<body>
<h1>compose multiplatform web demo</h1>
<div>
<canvas id="canvas1"></canvas>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.ui.platform

internal actual fun getVisualViewport(): VisualViewport? {
return js("window.visualViewport") as? VisualViewport
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.asComposeCanvas
import androidx.compose.ui.input.InputMode
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.pointer.PointerButton
import androidx.compose.ui.input.pointer.PointerId
import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.input.pointer.toCompose
Expand Down Expand Up @@ -73,6 +74,9 @@ internal class ComposeLayer(
onPointerEventWithMultitouch(event)
} else {
// macos and desktop`s web don't work properly when using onPointerEventWithMultitouch
if (scene.platformContext.inputModeManager.inputMode != InputMode.Keyboard) {
scene.platformContext.inputModeManager.requestInputMode(InputMode.Keyboard)
}
onPointerEventNoMultitouch(event)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
*/
package androidx.compose.ui.native

internal actual val supportsMultitouch: Boolean get() = false
internal actual val supportsMultitouch: Boolean get() = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.ui.platform

import kotlinx.browser.window
import org.w3c.dom.events.*

internal interface ImeMobileKeyboardListener {
fun onShow(callback: ()->Unit)
fun onHide(callback: ()->Unit)
}

internal class ImeKeyboardListenerImpl: ImeMobileKeyboardListener {
private var callbackOnShow = {}
private var callbackOnHide = {}

init {
val visualViewport = getVisualViewport()

if (visualViewport != null) {
val viewportVsClientHeightRatio = 0.75

visualViewport.addEventListener("resize", { event ->
val target = event.target as? VisualViewport ?: return@addEventListener
if (
(target.height * target.scale) / window.screen.height <
viewportVsClientHeightRatio
) {
callbackOnShow()
} else {
callbackOnHide()
}
}, false)
}
}

override fun onShow(callback: () -> Unit) {
callbackOnShow = callback
}

override fun onHide(callback: () -> Unit) {
callbackOnHide = callback
}
}

abstract external class VisualViewport : EventTarget {
val offsetLeft: Double
val offsetTop: Double

val pageLeft: Double
val pageTop: Double

val width: Double
val height: Double

val scale: Double

val onresize: (Event) -> Unit
val onscroll: (Event) -> Unit
val onscrollend: (Event) -> Unit
}
Loading

0 comments on commit 691b10e

Please sign in to comment.