From 4a63cc15d0717220317af748aa9b960cd33055ed Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Thu, 26 Dec 2024 13:28:41 +0800 Subject: [PATCH] refactor: merge RimeNotification and RimeEvent as RimeMessage --- .../main/java/com/osfans/trime/core/Rime.kt | 122 +++++++------- .../java/com/osfans/trime/core/RimeApi.kt | 2 +- .../com/osfans/trime/core/RimeCallback.kt | 8 - .../java/com/osfans/trime/core/RimeEvent.kt | 54 ------- .../java/com/osfans/trime/core/RimeMessage.kt | 153 ++++++++++++++++++ .../com/osfans/trime/core/RimeNotification.kt | 79 --------- .../com/osfans/trime/daemon/RimeSession.kt | 2 +- .../java/com/osfans/trime/ime/bar/QuickBar.kt | 4 +- .../ime/broadcast/InputBroadcastReceiver.kt | 4 +- .../trime/ime/broadcast/InputBroadcaster.kt | 4 +- .../ime/composition/ComposingPopupWindow.kt | 36 ++--- ...llbackHandler.kt => BaseMessageHandler.kt} | 24 +-- .../trime/ime/core/InputDeviceManager.kt | 4 +- .../com/osfans/trime/ime/core/InputView.kt | 35 ++-- .../trime/ime/core/TrimeInputMethodService.kt | 26 ++- .../trime/ime/keyboard/KeyboardWindow.kt | 4 +- app/src/main/jni/librime_jni/jni-utils.h | 7 +- app/src/main/jni/librime_jni/rime_jni.cc | 16 +- 18 files changed, 295 insertions(+), 289 deletions(-) delete mode 100644 app/src/main/java/com/osfans/trime/core/RimeCallback.kt delete mode 100644 app/src/main/java/com/osfans/trime/core/RimeEvent.kt create mode 100644 app/src/main/java/com/osfans/trime/core/RimeMessage.kt delete mode 100644 app/src/main/java/com/osfans/trime/core/RimeNotification.kt rename app/src/main/java/com/osfans/trime/ime/core/{BaseCallbackHandler.kt => BaseMessageHandler.kt} (58%) diff --git a/app/src/main/java/com/osfans/trime/core/Rime.kt b/app/src/main/java/com/osfans/trime/core/Rime.kt index 077c4e1f85..e83fb560d3 100644 --- a/app/src/main/java/com/osfans/trime/core/Rime.kt +++ b/app/src/main/java/com/osfans/trime/core/Rime.kt @@ -28,7 +28,7 @@ class Rime : private val lifecycleImpl = RimeLifecycleImpl() override val lifecycle get() = lifecycleImpl - override val callbackFlow = callbackFlow_.asSharedFlow() + override val messageFlow = messageFlow_.asSharedFlow() override val stateFlow get() = lifecycle.currentStateFlow @@ -54,7 +54,7 @@ class Rime : lifecycleImpl.emitState(RimeLifecycle.State.READY) - ipcResponseCallback() + requireResponse() SchemaManager.init(getCurrentRimeSchema()) } @@ -81,9 +81,9 @@ class Rime : withRimeContext { processRimeKey(value, modifiers.toInt()).also { if (it) { - ipcResponseCallback() + requireResponse() } else { - keyEventCallback(KeyValue(value), KeyModifiers(modifiers)) + requireKeyMessage(value, modifiers.toInt()) } } } @@ -95,37 +95,37 @@ class Rime : withRimeContext { processRimeKey(value.value, modifiers.toInt()).also { if (it) { - ipcResponseCallback() + requireResponse() } else { - keyEventCallback(value, modifiers) + requireKeyMessage(value.value, modifiers.toInt()) } } } override suspend fun selectCandidate(idx: Int): Boolean = withRimeContext { - selectRimeCandidate(idx).also { if (it) ipcResponseCallback() } + selectRimeCandidate(idx).also { if (it) requireResponse() } } override suspend fun forgetCandidate(idx: Int): Boolean = withRimeContext { - forgetRimeCandidate(idx).also { if (it) ipcResponseCallback() } + forgetRimeCandidate(idx).also { if (it) requireResponse() } } override suspend fun selectPagedCandidate(idx: Int): Boolean = withRimeContext { - selectRimeCandidateOnCurrentPage(idx).also { if (it) ipcResponseCallback() } + selectRimeCandidateOnCurrentPage(idx).also { if (it) requireResponse() } } override suspend fun deletedPagedCandidate(idx: Int): Boolean = withRimeContext { - deleteRimeCandidateOnCurrentPage(idx).also { if (it) ipcResponseCallback() } + deleteRimeCandidateOnCurrentPage(idx).also { if (it) requireResponse() } } override suspend fun moveCursorPos(position: Int) = withRimeContext { setRimeCaretPos(position) - ipcResponseCallback() + requireResponse() } override suspend fun availableSchemata(): Array = withRimeContext { getAvailableRimeSchemaList() } @@ -146,12 +146,12 @@ class Rime : schema ?: schemaItemCached } - override suspend fun commitComposition(): Boolean = withRimeContext { commitRimeComposition().also { if (it) ipcResponseCallback() } } + override suspend fun commitComposition(): Boolean = withRimeContext { commitRimeComposition().also { if (it) requireResponse() } } override suspend fun clearComposition() = withRimeContext { clearRimeComposition() - ipcResponseCallback() + requireResponse() } override suspend fun setRuntimeOption( @@ -175,27 +175,27 @@ class Rime : getRimeCandidates(startIndex, limit) ?: emptyArray() } - private fun handleRimeCallback(it: RimeCallback) { + private fun handleRimeMessage(it: RimeMessage<*>) { when (it) { - is RimeNotification.SchemaNotification -> { - schemaItemCached = it.value - SchemaManager.init(it.value.id) + is RimeMessage.SchemaMessage -> { + schemaItemCached = it.data + SchemaManager.init(it.data.id) } - is RimeNotification.OptionNotification -> { + is RimeMessage.OptionMessage -> { getRimeStatus()?.let { inputStatusCached = InputStatus.fromStatus(it) inputStatus = it // for compatibility } SchemaManager.updateSwitchOptions() } - is RimeNotification.DeployNotification -> { - when (it.value) { - "start" -> OpenCCDictManager.buildOpenCCDict() + is RimeMessage.DeployMessage -> { + if (it.data == RimeMessage.DeployMessage.State.Start) { + OpenCCDictManager.buildOpenCCDict() } } - is RimeEvent.IpcResponseEvent -> + is RimeMessage.ResponseMessage -> it.data.let event@{ data -> - data.status?.let { + data.status.let { val status = InputStatus.fromStatus(it) inputStatusCached = status inputStatus = it // for compatibility @@ -205,7 +205,7 @@ class Rime : schemaItemCached = item } } - data.context?.let { inputContext = it } // for compatibility + inputContext = data.context // for compatibility } else -> {} } @@ -217,7 +217,7 @@ class Rime : return } if (appContext.isStorageAvailable()) { - registerRimeCallbackHandler(::handleRimeCallback) + registerRimeMessageHandler(::handleRimeMessage) lifecycleImpl.emitState(RimeLifecycle.State.STARTING) dispatcher.start(fullCheck) } @@ -236,19 +236,19 @@ class Rime : } } lifecycleImpl.emitState(RimeLifecycle.State.STOPPED) - unregisterRimeCallbackHandler(::handleRimeCallback) + unregisterRimeMessageHandler(::handleRimeMessage) } companion object { private var inputContext: RimeProto.Context? = null private var inputStatus: RimeProto.Status? = null - private val callbackFlow_ = - MutableSharedFlow( + private val messageFlow_ = + MutableSharedFlow>( extraBufferCapacity = 15, onBufferOverflow = BufferOverflow.DROP_OLDEST, ) - private val callbackHandlers = ArrayList<(RimeCallback) -> Unit>() + private val rimeMessageHandlers = ArrayList<(RimeMessage<*>) -> Unit>() init { System.loadLibrary("rime_jni") @@ -284,7 +284,7 @@ class Rime : sequence.toString().replace("{}", "{braceleft}{braceright}"), ).also { Timber.d("simulateKeySequence ${if (it) "success" else "failed"}") - if (it) ipcResponseCallback() + if (it) requireResponse() } } @@ -304,7 +304,7 @@ class Rime : @JvmStatic fun setCaretPos(caretPos: Int) { setRimeCaretPos(caretPos) - ipcResponseCallback() + requireResponse() } // init @@ -444,50 +444,46 @@ class Rime : limit: Int, ): Array? - /** call from rime_jni */ @JvmStatic - fun handleRimeNotification( - messageType: String, - messageValue: String, + fun handleRimeMessage( + type: Int, + params: Array, ) { - val notification = RimeNotification.create(messageType, messageValue) - Timber.d("Handling Rime notification: $notification") - callbackHandlers.forEach { it.invoke(notification) } - callbackFlow_.tryEmit(notification) + val message = RimeMessage.nativeCreate(type, params) + Timber.d("Handling $message") + rimeMessageHandlers.forEach { it.invoke(message) } + messageFlow_.tryEmit(message) } - private fun ipcResponseCallback() { - handleRimeEvent( - RimeEvent.EventType.IpcResponse, - RimeEvent.IpcResponseEvent.Data(getRimeCommit(), getRimeContext(), getRimeStatus()), + private fun requireResponse() { + handleRimeMessage( + 4, // RimeMessage.MessageType.Response + arrayOf( + getRimeCommit() ?: RimeProto.Commit(null), + getRimeContext() ?: return, + getRimeStatus() ?: return, + ), ) } - private fun keyEventCallback( - value: KeyValue, - modifiers: KeyModifiers, + private fun requireKeyMessage( + value: Int, + modifiers: Int, ) { - val unicode = getRimeKeyUnicode(value.value) - handleRimeEvent(RimeEvent.EventType.Key, RimeEvent.KeyEvent.Data(value, modifiers, unicode)) - } - - private fun handleRimeEvent( - type: RimeEvent.EventType, - data: T, - ) { - val event = RimeEvent.create(type, data) - Timber.d("Handling $event") - callbackHandlers.forEach { it.invoke(event) } - callbackFlow_.tryEmit(event) + val unicode = getRimeKeyUnicode(value) + handleRimeMessage( + 5, // RimeMessage.MessageType.Key, + arrayOf(value, modifiers, unicode), + ) } - private fun registerRimeCallbackHandler(handler: (RimeCallback) -> Unit) { - if (callbackHandlers.contains(handler)) return - callbackHandlers.add(handler) + private fun registerRimeMessageHandler(handler: (RimeMessage<*>) -> Unit) { + if (rimeMessageHandlers.contains(handler)) return + rimeMessageHandlers.add(handler) } - private fun unregisterRimeCallbackHandler(handler: (RimeCallback) -> Unit) { - callbackHandlers.remove(handler) + private fun unregisterRimeMessageHandler(handler: (RimeMessage<*>) -> Unit) { + rimeMessageHandlers.remove(handler) } } } diff --git a/app/src/main/java/com/osfans/trime/core/RimeApi.kt b/app/src/main/java/com/osfans/trime/core/RimeApi.kt index c7317a9488..efab204249 100644 --- a/app/src/main/java/com/osfans/trime/core/RimeApi.kt +++ b/app/src/main/java/com/osfans/trime/core/RimeApi.kt @@ -7,7 +7,7 @@ package com.osfans.trime.core import kotlinx.coroutines.flow.SharedFlow interface RimeApi { - val callbackFlow: SharedFlow + val messageFlow: SharedFlow> val stateFlow: SharedFlow diff --git a/app/src/main/java/com/osfans/trime/core/RimeCallback.kt b/app/src/main/java/com/osfans/trime/core/RimeCallback.kt deleted file mode 100644 index 11be1d0657..0000000000 --- a/app/src/main/java/com/osfans/trime/core/RimeCallback.kt +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015 - 2024 Rime community - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package com.osfans.trime.core - -sealed interface RimeCallback diff --git a/app/src/main/java/com/osfans/trime/core/RimeEvent.kt b/app/src/main/java/com/osfans/trime/core/RimeEvent.kt deleted file mode 100644 index d46cdc0c02..0000000000 --- a/app/src/main/java/com/osfans/trime/core/RimeEvent.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015 - 2024 Rime community - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -package com.osfans.trime.core - -sealed class RimeEvent( - open val data: T, -) : RimeCallback { - abstract val eventType: EventType - - data class IpcResponseEvent( - override val data: Data, - ) : RimeEvent(data) { - override val eventType = EventType.IpcResponse - - data class Data( - val commit: RimeProto.Commit?, - val context: RimeProto.Context?, - val status: RimeProto.Status?, - ) - } - - data class KeyEvent( - override val data: Data, - ) : RimeEvent(data) { - override val eventType = EventType.Key - - data class Data( - val value: KeyValue, - val modifiers: KeyModifiers, - val unicode: Int, - ) - } - - enum class EventType { - IpcResponse, - Key, - } - - companion object { - fun create( - type: EventType, - data: T, - ) = when (type) { - EventType.IpcResponse -> { - IpcResponseEvent(data as IpcResponseEvent.Data) - } - EventType.Key -> - KeyEvent(data as KeyEvent.Data) - } - } -} diff --git a/app/src/main/java/com/osfans/trime/core/RimeMessage.kt b/app/src/main/java/com/osfans/trime/core/RimeMessage.kt new file mode 100644 index 0000000000..6779093fab --- /dev/null +++ b/app/src/main/java/com/osfans/trime/core/RimeMessage.kt @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2015 - 2024 Rime community + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.osfans.trime.core + +sealed class RimeMessage( + open val data: T, +) { + abstract val messageType: MessageType + + data class UnknownMessage( + override val data: Array, + ) : RimeMessage>(data) { + override val messageType = MessageType.Unknown + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as UnknownMessage + + if (!data.contentEquals(other.data)) return false + + return true + } + + override fun hashCode(): Int = data.contentHashCode() + } + + data class SchemaMessage( + override val data: SchemaItem, + ) : RimeMessage(data) { + override val messageType: MessageType + get() = MessageType.Schema + + override fun toString() = "SchemaMessage(id=${data.id}, name=${data.name})" + } + + data class OptionMessage( + override val data: Data, + ) : RimeMessage(data) { + override val messageType: MessageType + get() = MessageType.Option + + data class Data( + val option: String, + val value: Boolean, + ) + + override fun toString() = "OptionMessage(option=${data.option}, value=${data.value})" + } + + data class DeployMessage( + override val data: State, + ) : RimeMessage(data) { + override val messageType: MessageType + get() = MessageType.Deploy + + enum class State { + Start, + Success, + Failure, + } + + override fun toString() = "DeployMessage(state=$data)" + } + + data class ResponseMessage( + override val data: Data, + ) : RimeMessage(data) { + override val messageType = MessageType.Response + + data class Data( + val commit: RimeProto.Commit, + val context: RimeProto.Context, + val status: RimeProto.Status, + ) + + override fun toString(): String = "ResponseMessage(candidates=[${data.context.menu.candidates.joinToString(limit = 5) }], ...)" + } + + data class KeyMessage( + override val data: Data, + ) : RimeMessage(data) { + override val messageType = MessageType.Key + + data class Data( + val value: KeyValue, + val modifiers: KeyModifiers, + val unicode: Int, + ) + } + + enum class MessageType { + Unknown, + Schema, + Option, + Deploy, + Response, + Key, + } + + companion object { + private val types = MessageType.entries.toTypedArray() + + fun nativeCreate( + type: Int, + params: Array, + ) = when (types[type]) { + MessageType.Schema -> { + val (id, name) = (params[0] as String).split('/', limit = 2) + SchemaMessage(SchemaItem(id, name)) + } + MessageType.Option -> { + val value = params[0] as String + OptionMessage( + OptionMessage.Data( + value.substringAfter('!'), + !value.startsWith('!'), + ), + ) + } + MessageType.Deploy -> + DeployMessage( + DeployMessage.State.valueOf((params[0] as String).replaceFirstChar { it.titlecase() }), + ) + MessageType.Response -> + ResponseMessage( + ResponseMessage.Data( + params[0] as RimeProto.Commit, + params[1] as RimeProto.Context, + params[2] as RimeProto.Status, + ), + ) + MessageType.Key -> + KeyMessage( + KeyMessage.Data( + KeyValue(params[0] as Int), + KeyModifiers.of(params[1] as Int), + params[2] as Int, + ), + ) + else -> UnknownMessage(params) + } + + fun create( + type: MessageType, + params: Array, + ) = nativeCreate(type.ordinal, params) + } +} diff --git a/app/src/main/java/com/osfans/trime/core/RimeNotification.kt b/app/src/main/java/com/osfans/trime/core/RimeNotification.kt deleted file mode 100644 index 4fd8fae91d..0000000000 --- a/app/src/main/java/com/osfans/trime/core/RimeNotification.kt +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: 2015 - 2024 Rime community -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package com.osfans.trime.core - -sealed class RimeNotification( - open val value: T, -) : RimeCallback { - abstract val messageType: MessageType - - data class SchemaNotification( - override val value: SchemaItem, - ) : RimeNotification(value) { - override val messageType: MessageType - get() = MessageType.Schema - - override fun toString() = "SchemaEvent(schemaId=${value.id}, schemaName=${value.name})" - } - - data class OptionNotification( - override val value: Value, - ) : RimeNotification(value) { - override val messageType: MessageType - get() = MessageType.Option - - data class Value( - val option: String, - val value: Boolean, - ) - - override fun toString() = "OptionNotification(option=${value.option}, value=${value.value})" - } - - data class DeployNotification( - override val value: String, - ) : RimeNotification(value) { - override val messageType: MessageType - get() = MessageType.Deploy - - override fun toString() = "DeployNotification(state=$value)" - } - - data class UnknownNotification( - override val value: String, - ) : RimeNotification(value) { - override val messageType: MessageType - get() = MessageType.Unknown - } - - enum class MessageType { - Schema, - Option, - Deploy, - Unknown, - } - - companion object RimeNotificationHandler { - @JvmStatic - fun create( - type: String, - value: String, - ) = when (type) { - "schema" -> { - val (id, name) = value.split('/', limit = 2) - SchemaNotification(SchemaItem(id, name)) - } - "option" -> - OptionNotification( - OptionNotification.Value( - value.substringAfter('!'), - !value.startsWith('!'), - ), - ) - "deploy" -> DeployNotification(value) - else -> UnknownNotification(value) - } - } -} diff --git a/app/src/main/java/com/osfans/trime/daemon/RimeSession.kt b/app/src/main/java/com/osfans/trime/daemon/RimeSession.kt index 0d29e865c8..000b5eeece 100644 --- a/app/src/main/java/com/osfans/trime/daemon/RimeSession.kt +++ b/app/src/main/java/com/osfans/trime/daemon/RimeSession.kt @@ -15,7 +15,7 @@ interface RimeSession { * Run an operation immediately * The suspended [block] will be executed in caller's thread. * Use this function only for non-blocking operations like - * accessing [RimeApi.callbackFlow]. + * accessing [RimeApi.messageFlow]. */ fun run(block: suspend RimeApi.() -> T): T diff --git a/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt b/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt index 768e606ebc..54d05a60a6 100644 --- a/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt +++ b/app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt @@ -10,7 +10,7 @@ import android.view.inputmethod.EditorInfo import android.widget.ViewAnimator import androidx.lifecycle.lifecycleScope import com.osfans.trime.R -import com.osfans.trime.core.RimeNotification.OptionNotification +import com.osfans.trime.core.RimeMessage import com.osfans.trime.core.RimeProto import com.osfans.trime.core.SchemaItem import com.osfans.trime.daemon.RimeSession @@ -199,7 +199,7 @@ class QuickBar( } } - override fun onRimeOptionUpdated(value: OptionNotification.Value) { + override fun onRimeOptionUpdated(value: RimeMessage.OptionMessage.Data) { when (value.option) { "_hide_comment" -> { // candidateUi.candidates.shouldShowComment = !value.value diff --git a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt index 894283f80d..49b7a6859c 100644 --- a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcastReceiver.kt @@ -5,7 +5,7 @@ package com.osfans.trime.ime.broadcast import android.view.inputmethod.EditorInfo -import com.osfans.trime.core.RimeNotification.OptionNotification +import com.osfans.trime.core.RimeMessage import com.osfans.trime.core.RimeProto import com.osfans.trime.core.SchemaItem import com.osfans.trime.ime.window.BoardWindow @@ -20,7 +20,7 @@ interface InputBroadcastReceiver { fun onRimeSchemaUpdated(schema: SchemaItem) {} - fun onRimeOptionUpdated(value: OptionNotification.Value) {} + fun onRimeOptionUpdated(value: RimeMessage.OptionMessage.Data) {} fun onInputContextUpdate(ctx: RimeProto.Context) {} diff --git a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt index 69085b3cdf..d88a9ff049 100644 --- a/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt +++ b/app/src/main/java/com/osfans/trime/ime/broadcast/InputBroadcaster.kt @@ -5,7 +5,7 @@ package com.osfans.trime.ime.broadcast import android.view.inputmethod.EditorInfo -import com.osfans.trime.core.RimeNotification.OptionNotification +import com.osfans.trime.core.RimeMessage import com.osfans.trime.core.RimeProto import com.osfans.trime.core.SchemaItem import com.osfans.trime.ime.dependency.InputScope @@ -49,7 +49,7 @@ class InputBroadcaster : InputBroadcastReceiver { receivers.forEach { it.onRimeSchemaUpdated(schema) } } - override fun onRimeOptionUpdated(value: OptionNotification.Value) { + override fun onRimeOptionUpdated(value: RimeMessage.OptionMessage.Data) { receivers.forEach { it.onRimeOptionUpdated(value) } } diff --git a/app/src/main/java/com/osfans/trime/ime/composition/ComposingPopupWindow.kt b/app/src/main/java/com/osfans/trime/ime/composition/ComposingPopupWindow.kt index 472672f35a..ec856ebf56 100644 --- a/app/src/main/java/com/osfans/trime/ime/composition/ComposingPopupWindow.kt +++ b/app/src/main/java/com/osfans/trime/ime/composition/ComposingPopupWindow.kt @@ -16,13 +16,12 @@ import androidx.core.graphics.component1 import androidx.core.graphics.component2 import androidx.core.graphics.component3 import androidx.core.graphics.component4 -import com.osfans.trime.core.RimeCallback -import com.osfans.trime.core.RimeEvent +import com.osfans.trime.core.RimeMessage import com.osfans.trime.daemon.RimeSession import com.osfans.trime.data.prefs.AppPrefs import com.osfans.trime.data.theme.ColorManager import com.osfans.trime.data.theme.Theme -import com.osfans.trime.ime.core.BaseCallbackHandler +import com.osfans.trime.ime.core.BaseMessageHandler import com.osfans.trime.ime.core.TrimeInputMethodService import splitties.dimensions.dp import timber.log.Timber @@ -125,32 +124,31 @@ class ComposingPopupWindow( window.update(x, y, -1, -1) } - private val baseCallbackHandler = - object : BaseCallbackHandler(service, rime) { - override fun handleRimeCallback(it: RimeCallback) { - if (it is RimeEvent.IpcResponseEvent) { - it.data.context?.let ctx@{ - if (it.composition.length > 0) { - root.update(it) - Timber.d("Update! Ready to showup") - updatePosition() - } else { - dismiss() - } + private val baseMessageHandler = + object : BaseMessageHandler(service, rime) { + override fun handleRimeMessage(it: RimeMessage<*>) { + if (it is RimeMessage.ResponseMessage) { + val ctx = it.data.context + if (ctx.composition.length > 0) { + root.update(ctx) + Timber.d("Update! Ready to showup") + updatePosition() + } else { + dismiss() } } } } - var handleCallback: Boolean - get() = baseCallbackHandler.handleCallback + var handleMessage: Boolean + get() = baseMessageHandler.handleMessage set(value) { - baseCallbackHandler.handleCallback = value + baseMessageHandler.handleMessage = value } fun cancelJob() { dismiss() - baseCallbackHandler.cancelJob() + baseMessageHandler.cancelJob() } fun dismiss() { diff --git a/app/src/main/java/com/osfans/trime/ime/core/BaseCallbackHandler.kt b/app/src/main/java/com/osfans/trime/ime/core/BaseMessageHandler.kt similarity index 58% rename from app/src/main/java/com/osfans/trime/ime/core/BaseCallbackHandler.kt rename to app/src/main/java/com/osfans/trime/ime/core/BaseMessageHandler.kt index aa781b5283..9e473fc55e 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/BaseCallbackHandler.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/BaseMessageHandler.kt @@ -6,42 +6,42 @@ package com.osfans.trime.ime.core import androidx.lifecycle.lifecycleScope -import com.osfans.trime.core.RimeCallback +import com.osfans.trime.core.RimeMessage import com.osfans.trime.daemon.RimeSession import kotlinx.coroutines.Job import kotlinx.coroutines.launch -open class BaseCallbackHandler( +open class BaseMessageHandler( val service: TrimeInputMethodService, val rime: RimeSession, ) { - open fun handleRimeCallback(it: RimeCallback) {} + open fun handleRimeMessage(it: RimeMessage<*>) {} - private var callbackHandlerJob: Job? = null + private var messageHandlerJob: Job? = null private fun setupFcitxEventHandler() { - callbackHandlerJob = + messageHandlerJob = service.lifecycleScope.launch { - rime.run { callbackFlow }.collect { - handleRimeCallback(it) + rime.run { messageFlow }.collect { + handleRimeMessage(it) } } } - var handleCallback = false + var handleMessage = false set(value) { field = value if (field) { - if (callbackHandlerJob == null) { + if (messageHandlerJob == null) { setupFcitxEventHandler() } } else { - callbackHandlerJob?.cancel() - callbackHandlerJob = null + messageHandlerJob?.cancel() + messageHandlerJob = null } } fun cancelJob() { - handleCallback = false + handleMessage = false } } diff --git a/app/src/main/java/com/osfans/trime/ime/core/InputDeviceManager.kt b/app/src/main/java/com/osfans/trime/ime/core/InputDeviceManager.kt index eac8c12001..7ffefba44f 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/InputDeviceManager.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/InputDeviceManager.kt @@ -23,13 +23,13 @@ class InputDeviceManager { private fun setupInputViewCallback(isVirtual: Boolean) { val shouldSetupInputView = isVirtual && candidatesMode != PopupCandidatesMode.FORCE_SHOW - inputView?.handleCallback = shouldSetupInputView + inputView?.handleMessage = shouldSetupInputView inputView?.visibility = if (isVirtual) View.VISIBLE else View.GONE } private fun setupComposingPopupWindowCallback(isVirtual: Boolean) { val shouldSetupWindow = !isVirtual || candidatesMode == PopupCandidatesMode.FORCE_SHOW - composingPopupWindow?.handleCallback = shouldSetupWindow + composingPopupWindow?.handleMessage = shouldSetupWindow composingPopupWindow?.useVirtualKeyboard = isVirtual // dismiss ComposingPopupWindow when entering virtual keyboard mode, // but preserve the visibility when entering physical keyboard mode (in case it's empty) diff --git a/app/src/main/java/com/osfans/trime/ime/core/InputView.kt b/app/src/main/java/com/osfans/trime/ime/core/InputView.kt index 150d30b10e..cb44831647 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/InputView.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/InputView.kt @@ -18,9 +18,7 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updateLayoutParams import androidx.lifecycle.lifecycleScope -import com.osfans.trime.core.RimeCallback -import com.osfans.trime.core.RimeEvent -import com.osfans.trime.core.RimeNotification +import com.osfans.trime.core.RimeMessage import com.osfans.trime.daemon.RimeSession import com.osfans.trime.data.prefs.AppPrefs import com.osfans.trime.data.theme.ColorManager @@ -322,20 +320,20 @@ class InputView( } } - private val baseCallbackHandler = - object : BaseCallbackHandler(service, rime) { - override fun handleRimeCallback(it: RimeCallback) { + private val baseMessageHandler = + object : BaseMessageHandler(service, rime) { + override fun handleRimeMessage(it: RimeMessage<*>) { when (it) { - is RimeNotification.SchemaNotification -> { - broadcaster.onRimeSchemaUpdated(it.value) + is RimeMessage.SchemaMessage -> { + broadcaster.onRimeSchemaUpdated(it.data) windowManager.attachWindow(KeyboardWindow) } - is RimeNotification.OptionNotification -> { - broadcaster.onRimeOptionUpdated(it.value) + is RimeMessage.OptionMessage -> { + broadcaster.onRimeOptionUpdated(it.data) - if (it.value.option == "_liquid_keyboard") { + if (it.data.option == "_liquid_keyboard") { ContextCompat.getMainExecutor(service).execute { windowManager.attachWindow(LiquidKeyboard) liquidKeyboard.select(0) @@ -343,12 +341,9 @@ class InputView( } } - is RimeEvent.IpcResponseEvent -> + is RimeMessage.ResponseMessage -> it.data.let event@{ - val ctx = it.context - if (ctx != null) { - broadcaster.onInputContextUpdate(ctx) - } + broadcaster.onInputContextUpdate(it.context) } else -> {} @@ -356,10 +351,10 @@ class InputView( } } - var handleCallback: Boolean - get() = baseCallbackHandler.handleCallback + var handleMessage: Boolean + get() = baseMessageHandler.handleMessage set(value) { - baseCallbackHandler.handleCallback = value + baseMessageHandler.handleMessage = value } fun updateSelection( @@ -373,7 +368,7 @@ class InputView( ViewCompat.setOnApplyWindowInsetsListener(this, null) // cancel the notification job and clear all broadcast receivers, // implies that InputView should not be attached again after detached. - baseCallbackHandler.cancelJob() + baseMessageHandler.cancelJob() updateWindowViewHeightJob.cancel() preedit.onDetached() preview.root.removeAllViews() diff --git a/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt b/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt index feeeacd6dc..4297a1033a 100644 --- a/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt +++ b/app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt @@ -37,10 +37,8 @@ import com.osfans.trime.core.KeyModifiers 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.RimeMessage import com.osfans.trime.core.RimeProto import com.osfans.trime.daemon.RimeDaemon import com.osfans.trime.daemon.RimeSession @@ -166,8 +164,8 @@ open class TrimeInputMethodService : LifecycleInputMethodService() { jobs.consumeEach { it.join() } } lifecycleScope.launch { - rime.run { callbackFlow }.collect { - handleRimeCallback(it) + rime.run { messageFlow }.collect { + handleRimeMessage(it) } } ThemeManager.addOnChangedListener(onThemeChangeListener) @@ -214,28 +212,26 @@ open class TrimeInputMethodService : LifecycleInputMethodService() { } } - private fun handleRimeCallback(it: RimeCallback) { + private fun handleRimeMessage(it: RimeMessage<*>) { when (it) { - is RimeNotification.OptionNotification -> { - val value = it.value.value - when (it.value.option) { + is RimeMessage.OptionMessage -> { + val (option, value) = it.data + when (option) { "ascii_mode" -> { InputFeedbackManager.ttsLanguage = locales[if (value) 1 else 0] } } } - is RimeEvent.IpcResponseEvent -> + is RimeMessage.ResponseMessage -> it.data.let event@{ val (commit, ctx) = it - if (commit?.text?.isNotEmpty() == true) { + if (commit.text?.isNotEmpty() == true) { commitText(commit.text) } - if (ctx != null) { - updateComposingText(ctx) - } + updateComposingText(ctx) } - is RimeEvent.KeyEvent -> + is RimeMessage.KeyMessage -> it.data.let event@{ val keyCode = it.value.keyCode if (keyCode != KeyEvent.KEYCODE_UNKNOWN) { diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt index f4a0ec755e..80bfa4c204 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardWindow.kt @@ -14,7 +14,7 @@ import android.widget.FrameLayout import androidx.core.content.ContextCompat import com.osfans.trime.R import com.osfans.trime.core.Rime -import com.osfans.trime.core.RimeNotification.OptionNotification +import com.osfans.trime.core.RimeMessage import com.osfans.trime.core.SchemaItem import com.osfans.trime.daemon.RimeSession import com.osfans.trime.data.prefs.AppPrefs @@ -264,7 +264,7 @@ class KeyboardWindow( switchKeyboard(schema.id) } - override fun onRimeOptionUpdated(value: OptionNotification.Value) { + override fun onRimeOptionUpdated(value: RimeMessage.OptionMessage.Data) { when (val opt = value.option) { "ascii_mode" -> currentKeyboard?.currentAsciiMode = value.value "_hide_key_hint" -> currentKeyboardView?.showKeyHint = !value.value diff --git a/app/src/main/jni/librime_jni/jni-utils.h b/app/src/main/jni/librime_jni/jni-utils.h index 2fdb0f5c6d..8cb4519f09 100644 --- a/app/src/main/jni/librime_jni/jni-utils.h +++ b/app/src/main/jni/librime_jni/jni-utils.h @@ -149,7 +149,7 @@ class GlobalRefSingleton { jmethodID PairSecond; jclass Rime; - jmethodID HandleRimeNotification; + jmethodID HandleRimeMessage; jclass CandidateItem; jmethodID CandidateItemInit; @@ -217,9 +217,8 @@ class GlobalRefSingleton { Rime = reinterpret_cast( env->NewGlobalRef(env->FindClass("com/osfans/trime/core/Rime"))); - HandleRimeNotification = - env->GetStaticMethodID(Rime, "handleRimeNotification", - "(Ljava/lang/String;Ljava/lang/String;)V"); + HandleRimeMessage = env->GetStaticMethodID(Rime, "handleRimeMessage", + "(I[Ljava/lang/Object;)V"); CandidateItem = reinterpret_cast(env->NewGlobalRef( env->FindClass("com/osfans/trime/core/CandidateItem"))); diff --git a/app/src/main/jni/librime_jni/rime_jni.cc b/app/src/main/jni/librime_jni/rime_jni.cc index 581dc50908..a0656d241d 100644 --- a/app/src/main/jni/librime_jni/rime_jni.cc +++ b/app/src/main/jni/librime_jni/rime_jni.cc @@ -193,9 +193,19 @@ extern "C" JNIEXPORT void JNICALL Java_com_osfans_trime_core_Rime_startupRime( const char *message_type, const char *message_value) { auto env = GlobalRef->AttachEnv(); - env->CallStaticVoidMethod( - GlobalRef->Rime, GlobalRef->HandleRimeNotification, - *JString(env, message_type), *JString(env, message_value)); + int type = 0; // unknown + if (strcmp(message_type, "schema") == 0) { + type = 1; + } else if (strcmp(message_type, "option") == 0) { + type = 2; + } else if (strcmp(message_type, "deploy") == 0) { + type = 3; + } + auto vararg = JRef( + env, env->NewObjectArray(1, GlobalRef->Object, nullptr)); + env->SetObjectArrayElement(vararg, 0, JString(env, message_value)); + env->CallStaticVoidMethod(GlobalRef->Rime, GlobalRef->HandleRimeMessage, + type, *vararg); }; Rime::Instance().startup(full_check, notificationHandler);