Skip to content

Commit

Permalink
refactor: update key processing api usage
Browse files Browse the repository at this point in the history
fix: enter/return key cannot perform available editor action
  • Loading branch information
WhiredPlanck committed Nov 7, 2024
1 parent 89504bb commit a760919
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 151 deletions.
10 changes: 10 additions & 0 deletions app/src/main/java/com/osfans/trime/core/KeyModifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ value class KeyModifiers(
return KeyModifiers(states)
}

fun fromMetaState(metaState: Int): KeyModifiers {
var states = KeyModifier.None.modifier
if (metaState.hasFlag(KeyEvent.META_ALT_ON)) states += KeyModifier.Alt
if (metaState.hasFlag(KeyEvent.META_CTRL_ON)) states += KeyModifier.Control
if (metaState.hasFlag(KeyEvent.META_SHIFT_ON)) states += KeyModifier.Shift
if (metaState.hasFlag(KeyEvent.META_CAPS_LOCK_ON)) states += KeyModifier.Lock
if (metaState.hasFlag(KeyEvent.META_META_ON)) states + KeyModifier.Meta
return KeyModifiers(states)
}

fun mergeModifiers(arr: Array<out KeyModifier>): UInt = arr.fold(KeyModifier.None.modifier) { acc, it -> acc or it.modifier }
}
}
47 changes: 0 additions & 47 deletions app/src/main/java/com/osfans/trime/core/Rime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -238,29 +238,6 @@ class Rime :
System.loadLibrary("rime_jni")
}

/*
Android SDK包含了如下6个修饰键的状态,其中function键会被trime消费掉,因此只处理5个键
Android和librime对按键命名并不一致。读取可能有误。librime按键命名见如下链接,
/~https://github.com/rime/librime/blob/master/src/rime/key_table.cc
*/
@JvmField
val META_SHIFT_ON = getRimeModifierByName("Shift")

@JvmField
val META_CTRL_ON = getRimeModifierByName("Control")

@JvmField
val META_ALT_ON = getRimeModifierByName("Alt")

@JvmField
val META_SYM_ON = getRimeModifierByName("Super")

@JvmField
val META_META_ON = getRimeModifierByName("Meta")

@JvmField
val META_RELEASE_ON = getRimeModifierByName("Release")

@JvmStatic
val isComposing get() = inputStatus?.isComposing ?: false

Expand All @@ -283,30 +260,6 @@ class Rime :
val composingText: String
get() = inputContext?.composition?.commitTextPreview ?: ""

@JvmStatic
fun isVoidKeycode(keycode: Int): Boolean {
val voidSymbol = 0xffffff
return keycode <= 0 || keycode == voidSymbol
}

// KeyProcess 调用JNI方法发送keycode和mask
@JvmStatic
fun processKey(
keycode: Int,
mask: Int,
): Boolean {
if (isVoidKeycode(keycode)) return false
Timber.d("processKey: keyCode=$keycode, mask=$mask")
return processRimeKey(keycode, mask).also {
Timber.d("processKey ${if (it) "success" else "failed"}")
if (it) {
ipcResponseCallback()
} else {
keyEventCallback(KeyValue(keycode), KeyModifiers.of(mask))
}
}
}

@JvmStatic
fun simulateKeySequence(sequence: CharSequence): Boolean {
if (!sequence.first().isAsciiPrintable()) return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ import com.osfans.trime.data.theme.ThemeManager
import com.osfans.trime.ime.broadcast.IntentReceiver
import com.osfans.trime.ime.enums.FullscreenMode
import com.osfans.trime.ime.enums.InlinePreeditMode
import com.osfans.trime.ime.enums.Keycode
import com.osfans.trime.ime.keyboard.CommonKeyboardActionListener
import com.osfans.trime.ime.keyboard.Event
import com.osfans.trime.ime.keyboard.InitializationUi
import com.osfans.trime.ime.keyboard.InputFeedbackManager
import com.osfans.trime.util.ShortcutUtils
Expand Down Expand Up @@ -339,7 +339,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
instance = null
}

private fun handleReturnKey() {
fun handleReturnKey() {
currentInputEditorInfo.run {
if (inputType and InputType.TYPE_MASK_CLASS == InputType.TYPE_NULL) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER)
Expand Down Expand Up @@ -762,26 +762,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
return s
}

/**
* 如果爲Back鍵[KeyEvent.KEYCODE_BACK],則隱藏鍵盤
*
* @param keyCode 鍵碼[KeyEvent.getKeyCode]
* @return 是否處理了Back鍵事件
*/
private fun handleBack(keyCode: Int): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
requestHideSelf(0)
return true
}
return false
}

private fun onRimeKey(event: IntArray): Boolean {
updateRimeOption()
// todo 改为异步处理按键事件、刷新UI
return Rime.processKey(event[0], event[1])
}

private fun forwardKeyEvent(event: KeyEvent): Boolean {
val modifiers = KeyModifiers.fromKeyEvent(event)
val charCode = event.unicodeChar
Expand Down Expand Up @@ -845,33 +825,32 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
keyEventCode: Int,
metaState: Int,
): Boolean { // 軟鍵盤
commonKeyboardActionListener?.needSendUpRimeKey = false
if (onRimeKey(Event.getRimeEvent(keyEventCode, metaState))) {
// 如果输入法消费了按键事件,则需要释放按键
commonKeyboardActionListener?.needSendUpRimeKey = true
Timber.d(
"\t<TrimeInput>\thandleKey()\trimeProcess, keycode=%d, metaState=%d",
keyEventCode,
metaState,
)
} else if (hookKeyboard(keyEventCode, metaState)) {
Timber.d("\t<TrimeInput>\thandleKey()\thookKeyboard, keycode=%d", keyEventCode)
} else if (handleBack(keyEventCode)) {
// 处理返回键(隐藏软键盘)
Timber.d("handleKey(): Back, keycode=$keyEventCode")
} else if (openCategory(keyEventCode)) {
// 打开系统默认应用
Timber.d("\t<TrimeInput>\thandleKey()\topenCategory keycode=%d", keyEventCode)
} else {
commonKeyboardActionListener?.needSendUpRimeKey = true
Timber.d(
"\t<TrimeInput>\thandleKey()\treturn FALSE, keycode=%d, metaState=%d",
keyEventCode,
metaState,
)
return false
commonKeyboardActionListener?.shouldReleaseKey = false
val value =
RimeKeyMapping
.keyCodeToVal(keyEventCode)
.takeIf { it != RimeKeyMapping.RimeKey_VoidSymbol }
?: Rime.getRimeKeycodeByName(Keycode.keyNameOf(keyEventCode))
val modifiers = KeyModifiers.fromMetaState(metaState).modifiers
var result = false
postRimeJob {
if (!processKey(value, modifiers)) {
if (!hookKeyboard(keyEventCode, metaState)) {
if (!openCategory(keyEventCode)) {
result = false
} else {
Timber.d("handleKey: openCategory")
}
} else {
Timber.d("handleKey: hook")
}
} else {
commonKeyboardActionListener?.shouldReleaseKey = true
Timber.d("handleKey: processKey")
}
}
return true
if (!result) commonKeyboardActionListener?.shouldReleaseKey = true
return result
}

fun shareText(): Boolean {
Expand Down Expand Up @@ -1005,21 +984,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
if (!onEvaluateInputViewShown()) setCandidatesViewShown(isComposable) // 實體鍵盤打字時顯示候選欄
}

/**
* 如果爲回車鍵[KeyEvent.KEYCODE_ENTER],則換行
*
* @param keyCode 鍵碼[KeyEvent.getKeyCode]
* @return 是否處理了回車事件
*/
private fun performEnter(keyCode: Int): Boolean { // 回車
if (keyCode == KeyEvent.KEYCODE_ENTER) {
DraftHelper.onInputEventChanged()
handleReturnKey()
return true
}
return false
}

override fun onEvaluateFullscreenMode(): Boolean {
val config = resources.configuration
if (config == null || !resources.configuration.isLandscape()) return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import android.content.Context
import android.view.KeyEvent
import androidx.lifecycle.lifecycleScope
import com.osfans.trime.R
import com.osfans.trime.core.KeyModifier
import com.osfans.trime.core.Rime
import com.osfans.trime.core.RimeApi
import com.osfans.trime.core.RimeKeyMapping
import com.osfans.trime.daemon.RimeSession
import com.osfans.trime.daemon.launchOnReady
import com.osfans.trime.data.prefs.AppPrefs
Expand Down Expand Up @@ -57,7 +59,7 @@ class CommonKeyboardActionListener(

private val prefs = AppPrefs.defaultInstance()

var needSendUpRimeKey: Boolean = false
var shouldReleaseKey: Boolean = false

private fun showDialog(dialog: suspend (RimeApi) -> Dialog) {
rime.launchOnReady { api ->
Expand Down Expand Up @@ -115,15 +117,19 @@ class CommonKeyboardActionListener(
}

override fun onRelease(keyEventCode: Int) {
if (needSendUpRimeKey) {
if (shouldReleaseKey) {
if (service.shouldUpdateRimeOption) {
Rime.setOption("soft_cursors", prefs.keyboard.softCursorEnabled)
Rime.setOption("_horizontal", ThemeManager.activeTheme.generalStyle.horizontal)
service.shouldUpdateRimeOption = false
}
// FIXME: 释放按键可能不对
val (value, modifiers) = Event.getRimeEvent(keyEventCode, Rime.META_RELEASE_ON)
Rime.processKey(value, modifiers)
val value = RimeKeyMapping.keyCodeToVal(keyEventCode)
if (value != RimeKeyMapping.RimeKey_VoidSymbol) {
service.postRimeJob {
processKey(value, KeyModifier.Release.modifier)
}
}
}
}

Expand Down Expand Up @@ -214,6 +220,10 @@ class CommonKeyboardActionListener(
}
KeyEvent.KEYCODE_PROG_RED -> showColorPicker()
KeyEvent.KEYCODE_MENU -> showEnabledSchemaPicker()
KeyEvent.KEYCODE_BACK,
KeyEvent.KEYCODE_ESCAPE,
-> service.requestHideSelf(0)
KeyEvent.KEYCODE_ENTER -> service.handleReturnKey()
else -> {
if (event.mask == 0 && KeyboardSwitcher.currentKeyboard.isOnlyShiftOn) {
if (event.code == KeyEvent.KEYCODE_SPACE && prefs.keyboard.hookShiftSpace) {
Expand Down Expand Up @@ -252,7 +262,7 @@ class CommonKeyboardActionListener(
// 优先由librime处理按键事件
if (service.handleKey(keyEventCode, metaState)) return

needSendUpRimeKey = false
shouldReleaseKey = false

// 小键盘自动增加锁定
if (keyEventCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyEventCode <= KeyEvent.KEYCODE_NUMPAD_EQUALS) {
Expand Down Expand Up @@ -295,7 +305,7 @@ class CommonKeyboardActionListener(
}
sequence = sequence.substring(slice.length)
}
needSendUpRimeKey = false
shouldReleaseKey = false
}
}
}
Expand Down
35 changes: 0 additions & 35 deletions app/src/main/java/com/osfans/trime/ime/keyboard/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package com.osfans.trime.ime.keyboard

import android.view.KeyEvent
import com.osfans.trime.core.Rime
import com.osfans.trime.core.RimeKeyMapping
import com.osfans.trime.data.prefs.AppPrefs
import com.osfans.trime.data.theme.ThemeManager
import com.osfans.trime.ime.enums.Keycode
Expand Down Expand Up @@ -220,39 +219,5 @@ class Event(
}
return keyCode
}

private fun hasModifier(
mask: Int,
modifier: Int,
): Boolean = mask and modifier > 0

// KeyboardEvent 从软键盘的按键keycode(可能含有mask)和mask,分离出rimekeycode和mask构成的数组
@JvmStatic
fun getRimeEvent(
code: Int,
mask: Int,
): IntArray {
var i = RimeKeyMapping.keyCodeToVal(code)
if (i == 0xffffff) { // 如果不是Android keycode, 则直接使用获取rimekeycode
val s = Keycode.keyNameOf(code)
i = Rime.getRimeKeycodeByName(s)
}
var m = 0
if (hasModifier(mask, KeyEvent.META_SHIFT_ON)) m = m or Rime.META_SHIFT_ON
if (hasModifier(mask, KeyEvent.META_CTRL_ON)) m = m or Rime.META_CTRL_ON
if (hasModifier(mask, KeyEvent.META_ALT_ON)) m = m or Rime.META_ALT_ON
if (hasModifier(mask, KeyEvent.META_SYM_ON)) m = m or Rime.META_SYM_ON
if (hasModifier(mask, KeyEvent.META_META_ON)) m = m or Rime.META_META_ON
if (mask == Rime.META_RELEASE_ON) m = m or Rime.META_RELEASE_ON
Timber.d(
"<Event> getRimeEvent()\tcode=%d, mask=%d, name=%s\toutput key=%d, meta=%d",
code,
mask,
Keycode.keyNameOf(code),
i,
m,
)
return intArrayOf(i, m)
}
}
}

0 comments on commit a760919

Please sign in to comment.