@@ -39,7 +39,6 @@ import com.osfans.trime.core.KeyValue
3939import com.osfans.trime.core.RimeApi
4040import com.osfans.trime.core.RimeKeyMapping
4141import com.osfans.trime.core.RimeMessage
42- import com.osfans.trime.core.RimeProto
4342import com.osfans.trime.daemon.RimeDaemon
4443import com.osfans.trime.daemon.RimeSession
4544import com.osfans.trime.data.prefs.AppPrefs
@@ -87,8 +86,11 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
8786 }
8887 private val rimeIntentReceiver = RimeIntentReceiver ()
8988
90- var lastCommittedText: CharSequence = " "
91- private set
89+ private var lastCommittedText: String = " "
90+
91+ private var composingText: String = " "
92+
93+ private var cursorUpdateIndex = 0
9294
9395 private val recreateInputViewPrefs: Array <PreferenceDelegate <* >> =
9496 arrayOf(prefs.keyboard.hideInputBar)
@@ -191,7 +193,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
191193 commitText(it.data.text)
192194 }
193195 }
194- is RimeMessage .CompositionMessage -> {
196+ is RimeMessage .InlinePreeditMessage -> {
195197 updateComposingText(it.data)
196198 }
197199 is RimeMessage .KeyMessage ->
@@ -405,18 +407,45 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
405407 candidatesStart,
406408 candidatesEnd,
407409 )
408- if (candidatesEnd != - 1 && (newSelStart != candidatesEnd || newSelEnd != candidatesEnd)) {
409- // 移動光標時,更新候選區
410- if (newSelEnd in candidatesStart.. < candidatesEnd) {
411- val newPosition = newSelEnd - candidatesStart
412- postRimeJob { moveCursorPos(newPosition) }
410+ cursorUpdateIndex + = 1
411+ handleCursorUpdate(newSelStart, newSelEnd, candidatesStart, candidatesEnd, cursorUpdateIndex)
412+ inputView?.updateSelection(newSelStart, newSelEnd)
413+ }
414+
415+ private fun handleCursorUpdate (
416+ newSelStart : Int ,
417+ newSelEnd : Int ,
418+ candidatesStart : Int ,
419+ candidatesEnd : Int ,
420+ updateIndex : Int ,
421+ ) {
422+ if (newSelStart != newSelEnd) return
423+ if (candidatesStart == candidatesEnd) {
424+ postRimeJob {
425+ if (isComposing) {
426+ Timber .d(" handleCursorUpdate: commit composition" )
427+ commitComposition()
428+ }
413429 }
430+ return
414431 }
415- if (candidatesStart == - 1 && candidatesEnd == - 1 && newSelStart == 0 && newSelEnd == 0 ) {
416- // 上屏後,清除候選區
417- postRimeJob { clearComposition() }
432+ if (newSelStart in candidatesStart.. candidatesEnd) {
433+ val position = newSelStart - candidatesStart
434+ if (position != composingText.length) {
435+ postRimeJob {
436+ if (updateIndex != cursorUpdateIndex) return @postRimeJob
437+ Timber .d(" handleCursorUpdate: move rime cursor to $position " )
438+ moveCursorPos(position)
439+ }
440+ }
441+ } else {
442+ Timber .d(" handleCursorUpdate: clear composition" )
443+ composingText = " "
444+ currentInputConnection?.finishComposingText()
445+ postRimeJob {
446+ clearComposition()
447+ }
418448 }
419- inputView?.updateSelection(newSelStart, newSelEnd)
420449 }
421450
422451 private val inputViewLocation = intArrayOf(0 , 0 )
@@ -476,12 +505,15 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
476505 attribute : EditorInfo ,
477506 restarting : Boolean ,
478507 ) {
508+ composingText = " "
479509 Timber .d(" onStartInput: restarting=$restarting " )
510+ val isNullType = attribute.inputType and InputType .TYPE_MASK_CLASS == InputType .TYPE_NULL
480511 postRimeJob {
481512 if (restarting) {
482513 // when input restarts in the same editor, clear previous composition
483514 clearComposition()
484515 }
516+ setRuntimeOption(" no_inline_preedit" , isNullType)
485517 }
486518 }
487519
@@ -531,25 +563,25 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
531563 finishComposingText()
532564 monitorCursorAnchor(false )
533565 }
566+ composingText = " "
534567 postRimeJob {
535568 clearComposition()
536569 }
537570 InputFeedbackManager .finishInput()
538571 }
539572
540- // 直接commit不做任何处理
541- fun commitText (
542- text : CharSequence ,
543- clearMeatKeyState : Boolean = false,
544- ) {
573+ fun commitText (text : String ) {
545574 val ic = currentInputConnection ? : return
546- if (ic.commitText(text, 1 )) {
547- lastCommittedText = text
548- }
549- InputFeedbackManager .textCommitSpeak(text.toString())
550- if (clearMeatKeyState) {
551- ic.clearMetaKeyStates(KeyEvent .getModifierMetaStateMask())
575+ // when composing text equals commit content, finish composing text as-is
576+ if (composingText == text) {
577+ composingText = " "
578+ ic.finishComposingText()
579+ return
552580 }
581+ ic.commitText(text, 1 )
582+ lastCommittedText = text
583+ composingText = " "
584+ InputFeedbackManager .textCommitSpeak(text)
553585 }
554586
555587 /* *
@@ -877,19 +909,20 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
877909 }
878910 }
879911
880- private val inlinePreeditMode by prefs.general.inlinePreeditMode
881-
882- private fun updateComposingText (composition : RimeProto .Context .Composition ) {
912+ private fun updateComposingText (text : String ) {
883913 val ic = currentInputConnection ? : return
884- val text =
885- when (inlinePreeditMode) {
886- InlinePreeditMode .DISABLE -> " "
887- InlinePreeditMode .COMPOSING_TEXT -> composition.preedit ? : " "
888- InlinePreeditMode .COMMIT_TEXT_PREVIEW -> composition.commitTextPreview ? : " "
914+ ic.beginBatchEdit()
915+ if (composingText.isNotEmpty() || text.isNotEmpty()) {
916+ if (! ic.getSelectedText(0 ).isNullOrEmpty()) {
917+ ic.deleteSurroundingText(1 , 0 )
889918 }
890- if (ic.getSelectedText(0 ).isNullOrEmpty() || text.isNotEmpty()) {
891919 ic.setComposingText(text, 1 )
920+ if (text.isEmpty()) {
921+ ic.finishComposingText()
922+ }
892923 }
924+ composingText = text
925+ ic.endBatchEdit()
893926 }
894927
895928 fun getActiveText (type : Int ): String {
@@ -899,7 +932,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
899932 val preedit = rimeComposition.preedit ? : " "
900933 val beforeCursor = getTextAroundCursor(1024 , before = true ) ? : " "
901934 val afterCursor = getTextAroundCursor(before = false ) ? : " "
902- val lastCommitted = lastCommittedText.toString()
935+ val lastCommitted = lastCommittedText
903936
904937 return sequenceOf(
905938 when (type) {
0 commit comments