Skip to content

Commit a760919

Browse files
committed
refactor: update key processing api usage
fix: enter/return key cannot perform available editor action
1 parent 89504bb commit a760919

File tree

5 files changed

+53
-151
lines changed

5 files changed

+53
-151
lines changed

app/src/main/java/com/osfans/trime/core/KeyModifier.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ value class KeyModifiers(
9898
return KeyModifiers(states)
9999
}
100100

101+
fun fromMetaState(metaState: Int): KeyModifiers {
102+
var states = KeyModifier.None.modifier
103+
if (metaState.hasFlag(KeyEvent.META_ALT_ON)) states += KeyModifier.Alt
104+
if (metaState.hasFlag(KeyEvent.META_CTRL_ON)) states += KeyModifier.Control
105+
if (metaState.hasFlag(KeyEvent.META_SHIFT_ON)) states += KeyModifier.Shift
106+
if (metaState.hasFlag(KeyEvent.META_CAPS_LOCK_ON)) states += KeyModifier.Lock
107+
if (metaState.hasFlag(KeyEvent.META_META_ON)) states + KeyModifier.Meta
108+
return KeyModifiers(states)
109+
}
110+
101111
fun mergeModifiers(arr: Array<out KeyModifier>): UInt = arr.fold(KeyModifier.None.modifier) { acc, it -> acc or it.modifier }
102112
}
103113
}

app/src/main/java/com/osfans/trime/core/Rime.kt

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -238,29 +238,6 @@ class Rime :
238238
System.loadLibrary("rime_jni")
239239
}
240240

241-
/*
242-
Android SDK包含了如下6个修饰键的状态,其中function键会被trime消费掉,因此只处理5个键
243-
Android和librime对按键命名并不一致。读取可能有误。librime按键命名见如下链接,
244-
https://github.com/rime/librime/blob/master/src/rime/key_table.cc
245-
*/
246-
@JvmField
247-
val META_SHIFT_ON = getRimeModifierByName("Shift")
248-
249-
@JvmField
250-
val META_CTRL_ON = getRimeModifierByName("Control")
251-
252-
@JvmField
253-
val META_ALT_ON = getRimeModifierByName("Alt")
254-
255-
@JvmField
256-
val META_SYM_ON = getRimeModifierByName("Super")
257-
258-
@JvmField
259-
val META_META_ON = getRimeModifierByName("Meta")
260-
261-
@JvmField
262-
val META_RELEASE_ON = getRimeModifierByName("Release")
263-
264241
@JvmStatic
265242
val isComposing get() = inputStatus?.isComposing ?: false
266243

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

286-
@JvmStatic
287-
fun isVoidKeycode(keycode: Int): Boolean {
288-
val voidSymbol = 0xffffff
289-
return keycode <= 0 || keycode == voidSymbol
290-
}
291-
292-
// KeyProcess 调用JNI方法发送keycode和mask
293-
@JvmStatic
294-
fun processKey(
295-
keycode: Int,
296-
mask: Int,
297-
): Boolean {
298-
if (isVoidKeycode(keycode)) return false
299-
Timber.d("processKey: keyCode=$keycode, mask=$mask")
300-
return processRimeKey(keycode, mask).also {
301-
Timber.d("processKey ${if (it) "success" else "failed"}")
302-
if (it) {
303-
ipcResponseCallback()
304-
} else {
305-
keyEventCallback(KeyValue(keycode), KeyModifiers.of(mask))
306-
}
307-
}
308-
}
309-
310263
@JvmStatic
311264
fun simulateKeySequence(sequence: CharSequence): Boolean {
312265
if (!sequence.first().isAsciiPrintable()) return false

app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ import com.osfans.trime.data.theme.ThemeManager
5353
import com.osfans.trime.ime.broadcast.IntentReceiver
5454
import com.osfans.trime.ime.enums.FullscreenMode
5555
import com.osfans.trime.ime.enums.InlinePreeditMode
56+
import com.osfans.trime.ime.enums.Keycode
5657
import com.osfans.trime.ime.keyboard.CommonKeyboardActionListener
57-
import com.osfans.trime.ime.keyboard.Event
5858
import com.osfans.trime.ime.keyboard.InitializationUi
5959
import com.osfans.trime.ime.keyboard.InputFeedbackManager
6060
import com.osfans.trime.util.ShortcutUtils
@@ -339,7 +339,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
339339
instance = null
340340
}
341341

342-
private fun handleReturnKey() {
342+
fun handleReturnKey() {
343343
currentInputEditorInfo.run {
344344
if (inputType and InputType.TYPE_MASK_CLASS == InputType.TYPE_NULL) {
345345
sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER)
@@ -762,26 +762,6 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
762762
return s
763763
}
764764

765-
/**
766-
* 如果爲Back鍵[KeyEvent.KEYCODE_BACK],則隱藏鍵盤
767-
*
768-
* @param keyCode 鍵碼[KeyEvent.getKeyCode]
769-
* @return 是否處理了Back鍵事件
770-
*/
771-
private fun handleBack(keyCode: Int): Boolean {
772-
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
773-
requestHideSelf(0)
774-
return true
775-
}
776-
return false
777-
}
778-
779-
private fun onRimeKey(event: IntArray): Boolean {
780-
updateRimeOption()
781-
// todo 改为异步处理按键事件、刷新UI
782-
return Rime.processKey(event[0], event[1])
783-
}
784-
785765
private fun forwardKeyEvent(event: KeyEvent): Boolean {
786766
val modifiers = KeyModifiers.fromKeyEvent(event)
787767
val charCode = event.unicodeChar
@@ -845,33 +825,32 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
845825
keyEventCode: Int,
846826
metaState: Int,
847827
): Boolean { // 軟鍵盤
848-
commonKeyboardActionListener?.needSendUpRimeKey = false
849-
if (onRimeKey(Event.getRimeEvent(keyEventCode, metaState))) {
850-
// 如果输入法消费了按键事件,则需要释放按键
851-
commonKeyboardActionListener?.needSendUpRimeKey = true
852-
Timber.d(
853-
"\t<TrimeInput>\thandleKey()\trimeProcess, keycode=%d, metaState=%d",
854-
keyEventCode,
855-
metaState,
856-
)
857-
} else if (hookKeyboard(keyEventCode, metaState)) {
858-
Timber.d("\t<TrimeInput>\thandleKey()\thookKeyboard, keycode=%d", keyEventCode)
859-
} else if (handleBack(keyEventCode)) {
860-
// 处理返回键(隐藏软键盘)
861-
Timber.d("handleKey(): Back, keycode=$keyEventCode")
862-
} else if (openCategory(keyEventCode)) {
863-
// 打开系统默认应用
864-
Timber.d("\t<TrimeInput>\thandleKey()\topenCategory keycode=%d", keyEventCode)
865-
} else {
866-
commonKeyboardActionListener?.needSendUpRimeKey = true
867-
Timber.d(
868-
"\t<TrimeInput>\thandleKey()\treturn FALSE, keycode=%d, metaState=%d",
869-
keyEventCode,
870-
metaState,
871-
)
872-
return false
828+
commonKeyboardActionListener?.shouldReleaseKey = false
829+
val value =
830+
RimeKeyMapping
831+
.keyCodeToVal(keyEventCode)
832+
.takeIf { it != RimeKeyMapping.RimeKey_VoidSymbol }
833+
?: Rime.getRimeKeycodeByName(Keycode.keyNameOf(keyEventCode))
834+
val modifiers = KeyModifiers.fromMetaState(metaState).modifiers
835+
var result = false
836+
postRimeJob {
837+
if (!processKey(value, modifiers)) {
838+
if (!hookKeyboard(keyEventCode, metaState)) {
839+
if (!openCategory(keyEventCode)) {
840+
result = false
841+
} else {
842+
Timber.d("handleKey: openCategory")
843+
}
844+
} else {
845+
Timber.d("handleKey: hook")
846+
}
847+
} else {
848+
commonKeyboardActionListener?.shouldReleaseKey = true
849+
Timber.d("handleKey: processKey")
850+
}
873851
}
874-
return true
852+
if (!result) commonKeyboardActionListener?.shouldReleaseKey = true
853+
return result
875854
}
876855

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

1008-
/**
1009-
* 如果爲回車鍵[KeyEvent.KEYCODE_ENTER],則換行
1010-
*
1011-
* @param keyCode 鍵碼[KeyEvent.getKeyCode]
1012-
* @return 是否處理了回車事件
1013-
*/
1014-
private fun performEnter(keyCode: Int): Boolean { // 回車
1015-
if (keyCode == KeyEvent.KEYCODE_ENTER) {
1016-
DraftHelper.onInputEventChanged()
1017-
handleReturnKey()
1018-
return true
1019-
}
1020-
return false
1021-
}
1022-
1023987
override fun onEvaluateFullscreenMode(): Boolean {
1024988
val config = resources.configuration
1025989
if (config == null || !resources.configuration.isLandscape()) return false

app/src/main/java/com/osfans/trime/ime/keyboard/CommonKeyboardActionListener.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import android.content.Context
1010
import android.view.KeyEvent
1111
import androidx.lifecycle.lifecycleScope
1212
import com.osfans.trime.R
13+
import com.osfans.trime.core.KeyModifier
1314
import com.osfans.trime.core.Rime
1415
import com.osfans.trime.core.RimeApi
16+
import com.osfans.trime.core.RimeKeyMapping
1517
import com.osfans.trime.daemon.RimeSession
1618
import com.osfans.trime.daemon.launchOnReady
1719
import com.osfans.trime.data.prefs.AppPrefs
@@ -57,7 +59,7 @@ class CommonKeyboardActionListener(
5759

5860
private val prefs = AppPrefs.defaultInstance()
5961

60-
var needSendUpRimeKey: Boolean = false
62+
var shouldReleaseKey: Boolean = false
6163

6264
private fun showDialog(dialog: suspend (RimeApi) -> Dialog) {
6365
rime.launchOnReady { api ->
@@ -115,15 +117,19 @@ class CommonKeyboardActionListener(
115117
}
116118

117119
override fun onRelease(keyEventCode: Int) {
118-
if (needSendUpRimeKey) {
120+
if (shouldReleaseKey) {
119121
if (service.shouldUpdateRimeOption) {
120122
Rime.setOption("soft_cursors", prefs.keyboard.softCursorEnabled)
121123
Rime.setOption("_horizontal", ThemeManager.activeTheme.generalStyle.horizontal)
122124
service.shouldUpdateRimeOption = false
123125
}
124126
// FIXME: 释放按键可能不对
125-
val (value, modifiers) = Event.getRimeEvent(keyEventCode, Rime.META_RELEASE_ON)
126-
Rime.processKey(value, modifiers)
127+
val value = RimeKeyMapping.keyCodeToVal(keyEventCode)
128+
if (value != RimeKeyMapping.RimeKey_VoidSymbol) {
129+
service.postRimeJob {
130+
processKey(value, KeyModifier.Release.modifier)
131+
}
132+
}
127133
}
128134
}
129135

@@ -214,6 +220,10 @@ class CommonKeyboardActionListener(
214220
}
215221
KeyEvent.KEYCODE_PROG_RED -> showColorPicker()
216222
KeyEvent.KEYCODE_MENU -> showEnabledSchemaPicker()
223+
KeyEvent.KEYCODE_BACK,
224+
KeyEvent.KEYCODE_ESCAPE,
225+
-> service.requestHideSelf(0)
226+
KeyEvent.KEYCODE_ENTER -> service.handleReturnKey()
217227
else -> {
218228
if (event.mask == 0 && KeyboardSwitcher.currentKeyboard.isOnlyShiftOn) {
219229
if (event.code == KeyEvent.KEYCODE_SPACE && prefs.keyboard.hookShiftSpace) {
@@ -252,7 +262,7 @@ class CommonKeyboardActionListener(
252262
// 优先由librime处理按键事件
253263
if (service.handleKey(keyEventCode, metaState)) return
254264

255-
needSendUpRimeKey = false
265+
shouldReleaseKey = false
256266

257267
// 小键盘自动增加锁定
258268
if (keyEventCode >= KeyEvent.KEYCODE_NUMPAD_0 && keyEventCode <= KeyEvent.KEYCODE_NUMPAD_EQUALS) {
@@ -295,7 +305,7 @@ class CommonKeyboardActionListener(
295305
}
296306
sequence = sequence.substring(slice.length)
297307
}
298-
needSendUpRimeKey = false
308+
shouldReleaseKey = false
299309
}
300310
}
301311
}

app/src/main/java/com/osfans/trime/ime/keyboard/Event.kt

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package com.osfans.trime.ime.keyboard
66

77
import android.view.KeyEvent
88
import com.osfans.trime.core.Rime
9-
import com.osfans.trime.core.RimeKeyMapping
109
import com.osfans.trime.data.prefs.AppPrefs
1110
import com.osfans.trime.data.theme.ThemeManager
1211
import com.osfans.trime.ime.enums.Keycode
@@ -220,39 +219,5 @@ class Event(
220219
}
221220
return keyCode
222221
}
223-
224-
private fun hasModifier(
225-
mask: Int,
226-
modifier: Int,
227-
): Boolean = mask and modifier > 0
228-
229-
// KeyboardEvent 从软键盘的按键keycode(可能含有mask)和mask,分离出rimekeycode和mask构成的数组
230-
@JvmStatic
231-
fun getRimeEvent(
232-
code: Int,
233-
mask: Int,
234-
): IntArray {
235-
var i = RimeKeyMapping.keyCodeToVal(code)
236-
if (i == 0xffffff) { // 如果不是Android keycode, 则直接使用获取rimekeycode
237-
val s = Keycode.keyNameOf(code)
238-
i = Rime.getRimeKeycodeByName(s)
239-
}
240-
var m = 0
241-
if (hasModifier(mask, KeyEvent.META_SHIFT_ON)) m = m or Rime.META_SHIFT_ON
242-
if (hasModifier(mask, KeyEvent.META_CTRL_ON)) m = m or Rime.META_CTRL_ON
243-
if (hasModifier(mask, KeyEvent.META_ALT_ON)) m = m or Rime.META_ALT_ON
244-
if (hasModifier(mask, KeyEvent.META_SYM_ON)) m = m or Rime.META_SYM_ON
245-
if (hasModifier(mask, KeyEvent.META_META_ON)) m = m or Rime.META_META_ON
246-
if (mask == Rime.META_RELEASE_ON) m = m or Rime.META_RELEASE_ON
247-
Timber.d(
248-
"<Event> getRimeEvent()\tcode=%d, mask=%d, name=%s\toutput key=%d, meta=%d",
249-
code,
250-
mask,
251-
Keycode.keyNameOf(code),
252-
i,
253-
m,
254-
)
255-
return intArrayOf(i, m)
256-
}
257222
}
258223
}

0 commit comments

Comments
 (0)