@@ -212,42 +212,55 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
212212 KeyboardSwitcher .currentKeyboardView?.invalidateAllKeys()
213213 }
214214 is RimeMessage .KeyMessage ->
215- it.data.let event@{
216- val keyCode = it.value.keyCode
217- if (keyCode == KeyEvent .KEYCODE_UNKNOWN ) {
218- when {
219- ! it.modifiers.release && it.value.value > 0 -> {
220- runCatching {
221- commitText(" ${Char (it.value.value)} " )
215+ it.data.let msg@{
216+ if (it.isVirtual) {
217+ when (it.value.value) {
218+ RimeKeyMapping .RimeKey_Return -> handleReturnKey()
219+ else -> {
220+ val keyCode = it.value.keyCode
221+ if (keyCode != KeyEvent .KEYCODE_UNKNOWN ) {
222+ // recognized keyCode
223+ sendDownUpKeyEvent(
224+ keyCode,
225+ it.modifiers.metaState or meta(
226+ alt = it.modifiers.alt,
227+ shift = it.modifiers.shift,
228+ ctrl = it.modifiers.ctrl,
229+ meta = it.modifiers.meta,
230+ ),
231+ )
232+ if (it.modifiers.ctrl && keyCode == KeyEvent .KEYCODE_C ) clearTextSelection()
233+ } else {
234+ if (it.value.value > 0 ) {
235+ runCatching {
236+ commitText(Character .toString(it.value.value))
237+ }.getOrElse { t -> Timber .w(t, " Unhandled Virtual KeyEvent: $it " ) }
238+ } else {
239+ Timber .w(" Unhandled Virtual KeyEvent: $it " )
240+ }
222241 }
223242 }
224- else -> Timber .w(" Unhandled Rime KeyEvent: $it " )
225243 }
226- return
227- }
228-
229- val eventTime = SystemClock .uptimeMillis()
230- if (it.modifiers.release) {
231- sendUpKeyEvent(eventTime, keyCode, it.modifiers.metaState)
232- return
233- }
234-
235- // TODO: look for better workaround for this
236- if (keyCode == KeyEvent . KEYCODE_ENTER ) {
237- handleReturnKey()
238- return
239- }
240-
241- if (keyCode in KeyEvent . KEYCODE_NUMPAD_0 .. KeyEvent . KEYCODE_NUMPAD_EQUALS ) {
242- // ignore KP_X keys, which is handled in `CommonKeyboardActionListener`.
243- // Requires this empty body becoz Kotlin request it
244- return
244+ } else {
245+ val keyCode = it.value.keyCode
246+ if (keyCode != KeyEvent . KEYCODE_UNKNOWN ) {
247+ // recognized keyCode
248+ val eventTime = SystemClock .uptimeMillis()
249+ if ( it.modifiers.release) {
250+ sendUpKeyEvent(eventTime, keyCode, it.modifiers.metaState)
251+ } else {
252+ sendDownKeyEvent(eventTime, keyCode, it.modifiers.metaState)
253+ }
254+ } else {
255+ if ( ! it.modifiers.release && it.value.value > 0 ) {
256+ runCatching {
257+ commitText( Character .toString(it.value.value))
258+ }.getOrElse { t -> Timber .w(t, " Unhandled Rime KeyEvent: $it " ) }
259+ } else {
260+ Timber .w( " Unhandled Rime KeyEvent: $it " )
261+ }
262+ }
245263 }
246-
247- if (it.modifiers.shift) sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_SHIFT_LEFT )
248- sendDownKeyEvent(eventTime, keyCode, it.modifiers.metaState)
249- if (it.modifiers.shift) sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_SHIFT_LEFT )
250- if (it.modifiers.ctrl && keyCode == KeyEvent .KEYCODE_C ) clearTextSelection()
251264 }
252265 else -> {}
253266 }
@@ -635,29 +648,18 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
635648 * @return An integer containing all meta flags passed and formatted for use in a [KeyEvent].
636649 */
637650 fun meta (
638- ctrl : Boolean = false,
639651 alt : Boolean = false,
652+ ctrl : Boolean = false,
640653 shift : Boolean = false,
641654 meta : Boolean = false,
642655 sym : Boolean = false,
643656 ): Int {
644657 var metaState = 0
645- if (ctrl) {
646- metaState = metaState or KeyEvent .META_CTRL_ON or KeyEvent .META_CTRL_LEFT_ON
647- }
648- if (alt) {
649- metaState = metaState or KeyEvent .META_ALT_ON or KeyEvent .META_ALT_LEFT_ON
650- }
651- if (shift) {
652- metaState = metaState or KeyEvent .META_SHIFT_ON or KeyEvent .META_SHIFT_LEFT_ON
653- }
654- if (meta) {
655- metaState = metaState or KeyEvent .META_META_ON or KeyEvent .META_META_LEFT_ON
656- }
657- if (sym) {
658- metaState = metaState or KeyEvent .META_SYM_ON
659- }
660-
658+ if (alt) metaState = KeyEvent .META_ALT_ON or KeyEvent .META_ALT_LEFT_ON
659+ if (ctrl) metaState = metaState or KeyEvent .META_CTRL_ON or KeyEvent .META_CTRL_LEFT_ON
660+ if (shift) metaState = metaState or KeyEvent .META_SHIFT_ON or KeyEvent .META_SHIFT_LEFT_ON
661+ if (meta) metaState = metaState or KeyEvent .META_META_ON or KeyEvent .META_META_LEFT_ON
662+ if (sym) metaState = metaState or KeyEvent .META_SYM_ON
661663 return metaState
662664 }
663665
@@ -710,84 +712,66 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
710712 *
711713 * @param keyEventCode The key code to send, use a key code defined in Android's [KeyEvent].
712714 * @param metaState Flags indicating which meta keys are currently pressed.
713- * @param count How often the key is pressed while the meta keys passed are down. Must be greater than or equal to
714- * `1`, else this method will immediately return false.
715715 *
716716 * @return True on success, false if an error occurred or the input connection is invalid.
717717 */
718718 fun sendDownUpKeyEvent (
719719 keyEventCode : Int ,
720720 metaState : Int = meta(),
721- count : Int = 1,
722721 ): Boolean {
723- if (count < 1 ) return false
724- val ic = currentInputConnection ? : return false
725- ic.clearMetaKeyStates(
726- KeyEvent .META_FUNCTION_ON
727- or KeyEvent .META_SHIFT_MASK
728- or KeyEvent .META_ALT_MASK
729- or KeyEvent .META_CTRL_MASK
730- or KeyEvent .META_META_MASK
731- or KeyEvent .META_SYM_ON ,
732- )
733- ic.beginBatchEdit()
734722 val eventTime = SystemClock .uptimeMillis()
735- if (metaState and KeyEvent .META_CTRL_ON != 0 ) {
736- sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_CTRL_LEFT )
737- }
738723 if (metaState and KeyEvent .META_ALT_ON != 0 ) {
739724 sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_ALT_LEFT )
740725 }
726+ if (metaState and KeyEvent .META_CTRL_ON != 0 ) {
727+ sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_CTRL_LEFT )
728+ }
741729 if (metaState and KeyEvent .META_SHIFT_ON != 0 ) {
742730 sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_SHIFT_LEFT )
743731 }
744732 if (metaState and KeyEvent .META_META_ON != 0 ) {
745733 sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_META_LEFT )
746734 }
747-
748735 if (metaState and KeyEvent .META_SYM_ON != 0 ) {
749736 sendDownKeyEvent(eventTime, KeyEvent .KEYCODE_SYM )
750737 }
751-
752- for (n in 0 until count) {
753- sendDownKeyEvent(eventTime, keyEventCode, metaState)
754- sendUpKeyEvent(eventTime, keyEventCode, metaState)
738+ sendDownKeyEvent(eventTime, keyEventCode, metaState)
739+ sendUpKeyEvent(eventTime, keyEventCode, metaState)
740+ if (metaState and KeyEvent .META_SYM_ON != 0 ) {
741+ sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_SYM )
742+ }
743+ if (metaState and KeyEvent .META_META_ON != 0 ) {
744+ sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_META_LEFT )
755745 }
756746 if (metaState and KeyEvent .META_SHIFT_ON != 0 ) {
757747 sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_SHIFT_LEFT )
758748 }
759- if (metaState and KeyEvent .META_ALT_ON != 0 ) {
760- sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_ALT_LEFT )
761- }
762749 if (metaState and KeyEvent .META_CTRL_ON != 0 ) {
763750 sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_CTRL_LEFT )
764751 }
765-
766- if (metaState and KeyEvent .META_META_ON != 0 ) {
767- sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_META_LEFT )
768- }
769-
770- if (metaState and KeyEvent .META_SYM_ON != 0 ) {
771- sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_SYM )
752+ if (metaState and KeyEvent .META_ALT_ON != 0 ) {
753+ sendUpKeyEvent(eventTime, KeyEvent .KEYCODE_ALT_LEFT )
772754 }
773-
774- ic.endBatchEdit()
775755 return true
776756 }
777757
778758 private fun forwardKeyEvent (event : KeyEvent ): Boolean {
779759 val modifiers = KeyModifiers .fromKeyEvent(event)
780760 val charCode = event.unicodeChar
781- if (charCode > 0 && charCode != ' \t ' .code && charCode != ' \n ' .code) {
761+ if (charCode > 0 && charCode != ' \t ' .code && charCode != ' \n ' .code && charCode != ' ' .code) {
762+ // drop modifier state when using combination keys to input number/symbol on some phones
763+ // because rime doesn't recognize selection key with modifiers (eg. Alt+Q for 1)
764+ // in which case event.getNumber().toInt() == event.getUnicodeChar()
765+ val m = if (event.number.code == charCode) KeyModifiers .Empty else modifiers
782766 postRimeJob {
783- processKey(charCode, modifiers .modifiers)
767+ processKey(charCode, m .modifiers, isVirtual = false )
784768 }
785769 return true
786770 }
787771 val keyVal = KeyValue .fromKeyEvent(event)
788772 if (keyVal.value != RimeKeyMapping .RimeKey_VoidSymbol ) {
789773 postRimeJob {
790- processKey(keyVal, modifiers)
774+ processKey(keyVal, modifiers, isVirtual = false )
791775 }
792776 return true
793777 }
0 commit comments