Skip to content

Commit

Permalink
feat: implement RimeEvent to hold events created by this frontend
Browse files Browse the repository at this point in the history
feat: forward rejected key event via callback flow to handle globally
  • Loading branch information
WhiredPlanck committed Oct 17, 2024
1 parent bde2c47 commit 19005e6
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 36 deletions.
51 changes: 42 additions & 9 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,27 @@ class Rime :
modifiers: UInt,
): Boolean =
withRimeContext {
processRimeKey(value, modifiers.toInt()).also { if (it) requestRimeResponse() }
processRimeKey(value, modifiers.toInt()).also {
if (it) {
requestRimeResponse()
} else {
keyEventCallback(KeyValue(value), KeyModifiers(modifiers))
}
}
}

override suspend fun processKey(
value: KeyValue,
modifiers: KeyModifiers,
): Boolean =
withRimeContext {
processRimeKey(value.value, modifiers.toInt()).also { if (it) requestRimeResponse() }
processRimeKey(value.value, modifiers.toInt()).also {
if (it) {
requestRimeResponse()
} else {
keyEventCallback(value, modifiers)
}
}
}

override suspend fun selectCandidate(idx: Int): Boolean =
Expand Down Expand Up @@ -286,7 +298,11 @@ class Rime :
Timber.d("processKey: keyCode=$keycode, mask=$mask")
return processRimeKey(keycode, mask).also {
Timber.d("processKey ${if (it) "success" else "failed"}")
if (it) requestRimeResponse()
if (it) {
requestRimeResponse()
} else {
keyEventCallback(KeyValue(keycode), KeyModifiers.of(mask))
}
}
}

Expand Down Expand Up @@ -482,6 +498,29 @@ class Rime :
callbackFlow_.tryEmit(notification)
}

fun requestRimeResponse() {
val response = RimeResponse(getRimeCommit(), getRimeContext(), getRimeStatus())
Timber.d("Got Rime response: $response")
callbackFlow_.tryEmit(response)
}

private fun keyEventCallback(
value: KeyValue,
modifiers: KeyModifiers,
) {
handleRimeEvent(RimeEvent.EventType.Key, RimeEvent.KeyEvent.Data(value, modifiers))
}

private fun <T> handleRimeEvent(
type: RimeEvent.EventType,
data: T,
) {
val event = RimeEvent.create(type, data)
Timber.d("Handling $event")
callbackHandlers.forEach { it.invoke(event) }
callbackFlow_.tryEmit(event)
}

private fun registerRimeCallbackHandler(handler: (RimeCallback) -> Unit) {
if (callbackHandlers.contains(handler)) return
callbackHandlers.add(handler)
Expand All @@ -490,11 +529,5 @@ class Rime :
private fun unregisterRimeCallbackHandler(handler: (RimeCallback) -> Unit) {
callbackHandlers.remove(handler)
}

fun requestRimeResponse() {
val response = RimeResponse(getRimeCommit(), getRimeContext(), getRimeStatus())
Timber.d("Got Rime response: $response")
callbackFlow_.tryEmit(response)
}
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/com/osfans/trime/core/RimeEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* SPDX-FileCopyrightText: 2015 - 2024 Rime community
* SPDX-License-Identifier: GPL-3.0-or-later
*/

package com.osfans.trime.core

sealed class RimeEvent<T>(
open val data: T,
) : RimeCallback {
abstract val eventType: EventType

data class KeyEvent(
override val data: Data,
) : RimeEvent<KeyEvent.Data>(data) {
override val eventType = EventType.Key

data class Data(
val value: KeyValue,
val modifiers: KeyModifiers,
)
}

enum class EventType {
Key,
}

companion object {
fun <T> create(
type: EventType,
data: T,
) = when (type) {
EventType.Key ->
KeyEvent(data as KeyEvent.Data)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.osfans.trime.core.KeyValue
import com.osfans.trime.core.Rime
import com.osfans.trime.core.RimeApi
import com.osfans.trime.core.RimeCallback
import com.osfans.trime.core.RimeEvent
import com.osfans.trime.core.RimeKeyMapping
import com.osfans.trime.core.RimeNotification
import com.osfans.trime.core.RimeProto
Expand Down Expand Up @@ -294,6 +295,24 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
}
updateComposing()
}
is RimeEvent.KeyEvent ->
it.data.let event@{
val keyCode = it.value.keyCode
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
val eventTime = SystemClock.uptimeMillis()
if (it.modifiers.modifiers == KeyModifier.Release.modifier) {
sendUpKeyEvent(eventTime, keyCode, it.modifiers.metaState)
} else {
sendDownKeyEvent(eventTime, keyCode, it.modifiers.metaState)
}
} else {
if (it.modifiers.modifiers != KeyModifier.Release.modifier && it.value.value > 0) {
commitText(Char(it.value.value).toString())
} else {
Timber.w("Unhandled Rime KeyEvent: $it")
}
}
}
else -> {}
}
}
Expand Down Expand Up @@ -772,46 +791,21 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
val charCode = event.unicodeChar
if (charCode > 0 && charCode != '\t'.code) {
postRimeJob {
if (!processKey(charCode, modifiers.modifiers)) {
onKeyEventCallback(KeyValue(charCode), modifiers)
}
processKey(charCode, modifiers.modifiers)
}
return true
}
val keyVal = KeyValue.fromKeyEvent(event)
if (keyVal.value != RimeKeyMapping.RimeKey_VoidSymbol) {
postRimeJob {
if (!processKey(keyVal, modifiers)) {
onKeyEventCallback(keyVal, modifiers)
}
processKey(keyVal, modifiers)
}
return true
}
Timber.d("Skipped KeyEvent: $event")
return false
}

private fun onKeyEventCallback(
keyVal: KeyValue,
modifiers: KeyModifiers,
) {
val keyCode = keyVal.keyCode
if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
val eventTime = SystemClock.uptimeMillis()
if (modifiers.modifiers == KeyModifier.Release.modifier) {
sendUpKeyEvent(eventTime, keyCode, modifiers.metaState)
} else {
sendDownKeyEvent(eventTime, keyCode, modifiers.metaState)
}
} else {
if (modifiers.modifiers != KeyModifier.Release.modifier && keyVal.value > 0) {
commitText(Char(keyVal.value).toString())
} else {
Timber.w("Unhandled Rime KeyEvent: ($keyVal, $modifiers)")
}
}
}

override fun onKeyDown(
keyCode: Int,
event: KeyEvent,
Expand Down

0 comments on commit 19005e6

Please sign in to comment.