From bb4ec4fb117d05e2e6f529f9a3e6056c4ca3c001 Mon Sep 17 00:00:00 2001 From: Mule <193615967+MULE-FEHU-EOLIA-ARTONELICO@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:43:49 +0800 Subject: [PATCH 1/5] fix: key preview displays incorrect label --- app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt index 1c616e7947..db48553206 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt @@ -952,7 +952,7 @@ class KeyboardView( if (mCurrentKey != NOT_A_KEY) { handleLongPressJob() } - showPreview(keyIndex, KeyBehavior.COMPOSING) + showPreview(keyIndex, KeyBehavior.CLICK) } /** From 6025d81842b47fe578a131bc5efb4718c6d33e11 Mon Sep 17 00:00:00 2001 From: Mule <193615967+MULE-FEHU-EOLIA-ARTONELICO@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:46:19 +0800 Subject: [PATCH 2/5] reforce(key): reduce redundant code, 'ascii' support 'send_bindings' --- .../java/com/osfans/trime/ime/keyboard/Key.kt | 233 +++++++----------- 1 file changed, 85 insertions(+), 148 deletions(-) diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/Key.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/Key.kt index e62dfe908d..fbd4ce2f0d 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/Key.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/Key.kt @@ -27,30 +27,31 @@ class Key( private val mKeyboard: Keyboard, ) { var keyActions = arrayOfNulls(EVENT_NUM) - var edgeFlags = 0 private var sendBindings = true + private lateinit var keyMap: Map - var width = 0 + var isPressed = false + private set + var isOn = false + private set - var height = 0 + @JvmField + var x = 0 - var gap = 0 + @JvmField + var y = 0 + var width = 0 + var height = 0 + var gap = 0 var row = 0 - var column = 0 + private var label = "" + private var labelSymbol = "" var hint: String = "" private set - private lateinit var keyMap: Map - private val keyBackColor get() = ColorManager.getDrawable(keyMap, "key_back_color") - private val hilitedKeyBackColor get() = ColorManager.getDrawable(keyMap, "hilited_key_back_color") - - private val keyTextColor get() = ColorManager.getColor(keyMap, "key_text_color") - private val keySymbolColor get() = ColorManager.getColor(keyMap, "key_symbol_color") - private val hilitedKeyTextColor get() = ColorManager.getColor(keyMap, "hilited_key_text_color") - private val hilitedKeySymbolColor get() = ColorManager.getColor(keyMap, "hilited_key_symbol_color") var keyTextSize: Float = 0f private set @@ -73,17 +74,12 @@ class Key( var keyPressOffsetX = 0 var keyPressOffsetY = 0 - @JvmField - var x = 0 - - @JvmField - var y = 0 - var isPressed = false - private set - var isOn = false - private set - - private var labelSymbol = "" + private val keyBackColor get() = ColorManager.getDrawable(keyMap, "key_back_color") + private val keyTextColor get() = ColorManager.getColor(keyMap, "key_text_color") + private val keySymbolColor get() = ColorManager.getColor(keyMap, "key_symbol_color") + private val hilitedKeyBackColor get() = ColorManager.getDrawable(keyMap, "hilited_key_back_color") + private val hilitedKeyTextColor get() = ColorManager.getColor(keyMap, "hilited_key_text_color") + private val hilitedKeySymbolColor get() = ColorManager.getColor(keyMap, "hilited_key_symbol_color") /** * Create an empty key with no attributes. @@ -94,29 +90,32 @@ class Key( constructor(parent: Keyboard, externalKeyMap: Map) : this(parent) { keyMap = externalKeyMap var hasComposingKey = false - for (behavior in KeyBehavior.entries) { + KeyBehavior.entries.forEach { behavior -> val behaviorName = behavior.name.lowercase() val what = obtainString(externalKeyMap, behaviorName) - if (what.isNotEmpty()) { - keyActions[behavior.ordinal] = KeyActionManager.getAction(what) - if (behavior.ordinal < KeyBehavior.COMBO.ordinal) hasComposingKey = true - } else if (behavior == KeyBehavior.CLICK) { - keyActions[behavior.ordinal] = KeyActionManager.getAction("") + when { + what.isNotEmpty() -> { + keyActions[behavior.ordinal] = KeyActionManager.getAction(what) + if (behavior.ordinal < KeyBehavior.COMBO.ordinal) { + hasComposingKey = true + } + } + behavior == KeyBehavior.CLICK -> { + keyActions[behavior.ordinal] = KeyActionManager.getAction("") + } } } if (hasComposingKey) mKeyboard.composingKeys.add(this) label = obtainString(externalKeyMap, "label") labelSymbol = obtainString(externalKeyMap, "label_symbol") hint = obtainString(externalKeyMap, "hint") - if (externalKeyMap.containsKey("send_bindings")) { - sendBindings = obtainBoolean(externalKeyMap, "send_bindings", true) - } else if (!hasComposingKey) { - sendBindings = false - } - mKeyboard.setModiferKey(this.code, this) keyTextSize = obtainFloat(externalKeyMap, "key_text_size") symbolTextSize = obtainFloat(externalKeyMap, "symbol_text_size") roundCorner = obtainFloat(externalKeyMap, "round_corner") + sendBindings = externalKeyMap["send_bindings"]?.let { + obtainBoolean(externalKeyMap, "send_bindings", true) + } ?: hasComposingKey + mKeyboard.setModiferKey(this.code, this) } fun setOn(on: Boolean): Boolean { @@ -225,12 +224,10 @@ class Key( get() { val isShifted = isTrimeModifierKey && mKeyboard.hasModifier(modifierKeyOnMask) val states = - if (isShifted || isOn) { - if (isPressed) KEY_STATE_ON_PRESSED else KEY_STATE_ON_NORMAL - } else if (click!!.isSticky || click!!.isFunctional) { - if (isPressed) KEY_STATE_OFF_PRESSED else KEY_STATE_OFF_NORMAL - } else { - if (isPressed) KEY_STATE_PRESSED else KEY_STATE_NORMAL + when { + isShifted || isOn -> if (isPressed) KEY_STATE_ON_PRESSED else KEY_STATE_ON_NORMAL + click!!.isSticky || click!!.isFunctional -> if (isPressed) KEY_STATE_OFF_PRESSED else KEY_STATE_OFF_NORMAL + else -> if (isPressed) KEY_STATE_PRESSED else KEY_STATE_NORMAL } // only for modiferKey debug @@ -249,82 +246,43 @@ class Key( } return states } + val modifierKeyOnMask: Int get() = getModifierKeyOnMask(this.code) - private fun getModifierKeyOnMask(keycode: Int): Int { - if (keycode == KeyEvent.KEYCODE_SHIFT_LEFT || - keycode == KeyEvent.KEYCODE_SHIFT_RIGHT - ) { - return KeyEvent.META_SHIFT_ON - } - if (keycode == KeyEvent.KEYCODE_CTRL_LEFT || - keycode == KeyEvent.KEYCODE_CTRL_RIGHT - ) { - return KeyEvent.META_CTRL_ON + private fun getModifierKeyOnMask(keycode: Int): Int = + when (keycode) { + KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT -> KeyEvent.META_SHIFT_ON + KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON + KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON + KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON + KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON + else -> 0 } - if (keycode == KeyEvent.KEYCODE_META_LEFT || - keycode == KeyEvent.KEYCODE_META_RIGHT - ) { - return KeyEvent.META_META_ON - } - if (keycode == KeyEvent.KEYCODE_ALT_LEFT || - keycode == KeyEvent.KEYCODE_ALT_RIGHT - ) { - return KeyEvent.META_ALT_ON - } - return if (keycode == KeyEvent.KEYCODE_SYM) KeyEvent.META_SYM_ON else 0 - } val isShift: Boolean - get() { - val c = this.code - return c == KeyEvent.KEYCODE_SHIFT_LEFT || c == KeyEvent.KEYCODE_SHIFT_RIGHT - } + get() = this.code == KeyEvent.KEYCODE_SHIFT_LEFT || this.code == KeyEvent.KEYCODE_SHIFT_RIGHT + val isShiftLock: Boolean - // Shift、Ctrl、Alt、Meta等修饰键在点击时是否触发锁定 - get() { - val s = click!!.shiftLock - // shift_lock #ascii_long: 英文長按中文單按鎖定, long: 長按鎖定, click: 單按鎖定 - if ("long" == s) return false - if ("click" == s) return true - return if ("ascii_long" == s) !isAsciiMode else false - } + // Shift、Ctrl、Alt、Meta 等修饰键在点击时是否触发锁定 + get() = + when (click?.shiftLock) { + "long" -> false // 长按锁定 + "click" -> true // 点击锁定 + "ascii_long" -> !isAsciiMode // 英文长按锁定,中文点击锁定 + else -> false + } /** * @param behavior 同文按键模式(点击/长按/滑动) * @return */ - fun sendBindings(behavior: KeyBehavior): Boolean { - var e: KeyAction? = null - if (behavior != KeyBehavior.CLICK) e = keyActions[behavior.ordinal] - if (e != null) return true - if (keyActions[KeyBehavior.ASCII.ordinal] != null && isAsciiMode) return false - if (sendBindings) { - if (keyActions[KeyBehavior.PAGING.ordinal] != null && hasLeft()) return true - if (keyActions[KeyBehavior.HAS_MENU.ordinal] != null && hasMenu()) return true - if (keyActions[KeyBehavior.COMPOSING.ordinal] != null && isComposing) return true - } - return false - } + fun sendBindings(behavior: KeyBehavior): Boolean = + keyActions[behavior.ordinal]?.takeIf { behavior != KeyBehavior.CLICK } != null || checkKeyAction(sendBindings) != null private val keyAction: KeyAction? - get() { - if (keyActions[KeyBehavior.ASCII.ordinal] != null && isAsciiMode) { - return keyActions[KeyBehavior.ASCII.ordinal] - } - if (keyActions[KeyBehavior.PAGING.ordinal] != null && hasLeft()) { - return keyActions[KeyBehavior.PAGING.ordinal] - } - if (keyActions[KeyBehavior.HAS_MENU.ordinal] != null && hasMenu()) { - return keyActions[KeyBehavior.HAS_MENU.ordinal] - } - return if (keyActions[KeyBehavior.COMPOSING.ordinal] != null && isComposing) { - keyActions[KeyBehavior.COMPOSING.ordinal] - } else { - click - } - } + get() = checkKeyAction() ?: click + val click: KeyAction? get() = keyActions[KeyBehavior.CLICK.ordinal] val longClick: KeyAction? @@ -332,60 +290,39 @@ class Key( fun hasAction(behavior: KeyBehavior): Boolean = keyActions[behavior.ordinal] != null - fun getAction(behavior: KeyBehavior): KeyAction? { - var e: KeyAction? = null - if (behavior != KeyBehavior.CLICK) e = keyActions[behavior.ordinal] - if (e != null) return e - if (keyActions[KeyBehavior.ASCII.ordinal] != null && isAsciiMode) { - return keyActions[KeyBehavior.ASCII.ordinal] - } - if (sendBindings) { - if (keyActions[KeyBehavior.PAGING.ordinal] != null && hasLeft()) { - return keyActions[KeyBehavior.PAGING.ordinal] - } - if (keyActions[KeyBehavior.HAS_MENU.ordinal] != null && hasMenu()) { - return keyActions[KeyBehavior.HAS_MENU.ordinal] - } - if (keyActions[KeyBehavior.COMPOSING.ordinal] != null && isComposing) { - return keyActions[KeyBehavior.COMPOSING.ordinal] - } - } - return click - } + fun getAction(behavior: KeyBehavior): KeyAction? = + keyActions[behavior.ordinal]?.takeIf { behavior != KeyBehavior.CLICK } ?: checkKeyAction(sendBindings) ?: click + + private fun checkKeyAction(): KeyAction? = + keyActions[KeyBehavior.ASCII.ordinal].takeIf { isAsciiMode } + ?: keyActions[KeyBehavior.PAGING.ordinal]?.takeIf { hasLeft() } + ?: keyActions[KeyBehavior.HAS_MENU.ordinal]?.takeIf { hasMenu() } + ?: keyActions[KeyBehavior.COMPOSING.ordinal]?.takeIf { isComposing } + + private fun checkKeyAction(sendBindings: Boolean): KeyAction? = checkKeyAction().takeIf { sendBindings } val code: Int get() = click!!.code fun getCode(behavior: KeyBehavior): Int = getAction(behavior)!!.code - fun getLabel(): String { - keyAction - return if (label.isNotEmpty() && - keyAction === click && - keyActions[KeyBehavior.ASCII.ordinal] == null && - !showAsciiPunch() - ) { - label - } else { - keyAction!!.getLabel(mKeyboard) // 中文狀態顯示標籤 + fun getLabel(): String = + when { + label.isNotEmpty() && + keyAction == click && + keyActions[KeyBehavior.ASCII.ordinal] == null && + !showAsciiPunch() -> label + else -> keyAction!!.getLabel(mKeyboard) // 中文狀態顯示標籤 } - } fun getPreviewText(behavior: KeyBehavior): String = - if (behavior == KeyBehavior.CLICK) { - keyAction!!.getPreview(mKeyboard) - } else { - getAction(behavior)!!.getPreview(mKeyboard) + when (behavior) { + KeyBehavior.CLICK -> keyAction!!.getPreview(mKeyboard) + else -> getAction(behavior)!!.getPreview(mKeyboard) } val symbolLabel: String - get() { - if (labelSymbol.isEmpty()) { - val longClick = longClick - if (longClick != null) return longClick.getLabel(mKeyboard) - } - return labelSymbol - } + get() = labelSymbol.takeIf { it.isNotEmpty() } ?: longClick?.getLabel(mKeyboard) ?: "" companion object { val KEY_STATE_ON_NORMAL = @@ -420,12 +357,12 @@ class Key( KEY_STATE_OFF_PRESSED, // 2 "hilited_off_key_back_color" 功能键按下的背景 KEY_STATE_OFF_NORMAL, // 3 "off_key_back_color" 功能键背景 KEY_STATE_PRESSED, // 4 "hilited_key_back_color" 按键按下的背景 - KEY_STATE_NORMAL, // 5 "key_back_color" 按键背景 + KEY_STATE_NORMAL, // 5 "key_back_color" 按键背景 ) private val EVENT_NUM = KeyBehavior.entries.size @JvmStatic - fun isTrimeModifierKey(keycode: Int): Boolean = if (keycode == KeyEvent.KEYCODE_FUNCTION) false else KeyEvent.isModifierKey(keycode) + fun isTrimeModifierKey(keycode: Int): Boolean = keycode != KeyEvent.KEYCODE_FUNCTION && KeyEvent.isModifierKey(keycode) } } From e2ce438d6832d9f060d69949e67dca0a68b7ad24 Mon Sep 17 00:00:00 2001 From: Mule <193615967+MULE-FEHU-EOLIA-ARTONELICO@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:46:28 +0800 Subject: [PATCH 3/5] feat: all trime modifier keys, support long-press lock --- .../com/osfans/trime/ime/keyboard/Keyboard.kt | 59 ++++++++----------- .../osfans/trime/ime/keyboard/KeyboardView.kt | 43 ++++---------- .../trime/ime/keyboard/KeyboardWindow.kt | 5 +- 3 files changed, 39 insertions(+), 68 deletions(-) diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/Keyboard.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/Keyboard.kt index b05bb8fb18..abc5428837 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/Keyboard.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/Keyboard.kt @@ -42,9 +42,6 @@ class Keyboard( var roundCorner: Float private set - // 鍵盤的Shift鍵是否按住 - // private boolean mShifted; - /** 鍵盤的Shift鍵 */ var mShiftKey: Key? = null var mCtrlKey: Key? = null @@ -457,59 +454,54 @@ class Keyboard( ) } - val isAlted: Boolean - get() = hasModifier(KeyEvent.META_ALT_ON) val isShifted: Boolean + get() = modifier.hasFlag(KeyEvent.META_SHIFT_ON) || mShiftKey?.isOn == true + + val isOnlyShiftOn: Boolean get() = - modifier.hasFlag(KeyEvent.META_SHIFT_ON) || - mShiftKey?.isOn == true + isShifted && + !modifier.hasFlag(KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON or KeyEvent.META_SYM_ON or KeyEvent.META_META_ON) /** - * 設定鍵盤的Shift鍵狀態 + * 设置Shift键状态(用于自动大写) * - * @param on 是否保持Shift按下狀態(锁定) - * @param shifted 是否按下Shift - * @return Shift鍵狀態是否改變 + * @param on 是否锁定Shift键 + * @param shifted 是否按下Shift键 + * @return Shift键状态是否改变 */ fun setShifted( on: Boolean, shifted: Boolean, ): Boolean { - var on = on - on = on and shifted - if (mShiftKey != null) mShiftKey!!.setOn(on) - return setModifier(KeyEvent.META_SHIFT_ON, on || shifted) + mShiftKey?.setOn(on) + return setModifier(KeyEvent.META_SHIFT_ON, shifted) } /** - * 设定修饰键的状态 + * 设置修饰键的状态 * * @param on 是否锁定修饰键 - * @param keycode 修饰键on的keyevent mask code - * @return + * @param keycode 修饰键的 KeyEvent 掩码 + * @return 修饰键状态是否改变 */ fun clikModifierKey( on: Boolean, keycode: Int, ): Boolean { val keyDown = !hasModifier(keycode) - var keepOn = on - if (keycode == KeyEvent.META_SHIFT_ON && mShiftKey != null) { - keepOn = mShiftKey!!.setOn(on) - } else if (keycode == KeyEvent.META_ALT_ON && mAltKey != null) { - keepOn = mAltKey!!.setOn(on) - } else if (keycode == KeyEvent.META_CTRL_ON && mCtrlKey != null) { - keepOn = mCtrlKey!!.setOn(on) - } else if (keycode == KeyEvent.META_META_ON && mMetaKey != null) { - keepOn = mMetaKey!!.setOn(on) - } else if (keycode == KeyEvent.KEYCODE_SYM && mSymKey != null) { - keepOn = mSymKey!!.setOn(on) - } + val modifierKey = + when (keycode) { + KeyEvent.META_SHIFT_ON -> mShiftKey + KeyEvent.META_ALT_ON -> mAltKey + KeyEvent.META_CTRL_ON -> mCtrlKey + KeyEvent.META_META_ON -> mMetaKey + KeyEvent.KEYCODE_SYM -> mSymKey + else -> null + } + val keepOn = modifierKey?.setOn(on) ?: on return if (on) setModifier(keycode, keepOn) else setModifier(keycode, keyDown) } - private val MASK_META_WITHOUT_SHIFT = KeyEvent.META_CTRL_ON or KeyEvent.META_ALT_ON or KeyEvent.META_SYM_ON or KeyEvent.META_META_ON - /** Creates a keyboard from the given xml key layout file. */ init { @@ -538,9 +530,6 @@ class Keyboard( composingKeys = ArrayList() } - val isOnlyShiftOn: Boolean - get() = mShiftKey != null && mShiftKey!!.isOn && modifier and MASK_META_WITHOUT_SHIFT == 0 - fun refreshModifier(): Boolean { // 这里改为了一次性重置全部修饰键状态并返回TRUE刷新UI,可能有bug var result = false diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt index db48553206..8644b10b47 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyboardView.kt @@ -373,37 +373,18 @@ class KeyboardView( * 设置键盘修饰键的状态 * * @param key 按下的修饰键(非组合键) + * @param behavior 按键行为(单击、长按等) * @return */ - private fun setModifier(key: Key): Boolean = - if (keyboard.clikModifierKey(key.isShiftLock, key.modifierKeyOnMask)) { - invalidateAllKeys() - true - } else { - false - } + private fun setModifier( + key: Key, + behavior: KeyBehavior, + ): Boolean = setModifier(key.isShiftLock xor (behavior == KeyBehavior.LONG_CLICK), key.modifierKeyOnMask) - /** - * 設定鍵盤的Shift鍵狀態 - * - * @param on 是否保持Shift按下狀態 - * @param shifted 是否按下Shift - * @return Shift鍵狀態是否改變 - * @see Keyboard.setShifted - */ - fun setShifted( + private fun setModifier( on: Boolean, - shifted: Boolean, - ): Boolean { - // todo 扩展为设置全部修饰键的状态 - return if (keyboard.setShifted(on, shifted)) { - // The whole keyboard probably needs to be redrawn - invalidateAllKeys() - true - } else { - false - } - } + code: Int, + ): Boolean = keyboard.clikModifierKey(on, code).also { if (it) invalidateAllKeys() } // 重置全部修饰键的状态(如果有锁定则不重置) private fun refreshModifier() { @@ -705,7 +686,7 @@ class KeyboardView( val key = mKeys[index] if (Key.isTrimeModifierKey(key.code) && !key.sendBindings(behavior)) { Timber.d("detectAndSendKey: ModifierKey, key.getEvent, keyLabel=${key.getLabel()}") - setModifier(key) + setModifier(key, behavior) } else { if (key.click!!.isRepeatable) { if (behavior > KeyBehavior.CLICK) mAbortKey = true @@ -812,10 +793,8 @@ class KeyboardView( } return true } - Timber.w("only set isShifted, no others modifierkey") - if (popupKey.isShift && !popupKey.sendBindings(KeyBehavior.LONG_CLICK)) { - // todo 其他修饰键 - setShifted(!popupKey.isOn, !popupKey.isOn) + if (Key.isTrimeModifierKey(popupKey.code) && !popupKey.sendBindings(KeyBehavior.LONG_CLICK)) { + setModifier(popupKey, KeyBehavior.LONG_CLICK) return true } return false 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 4ed9e7e6f9..b7e863c91f 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 @@ -256,6 +256,7 @@ class KeyboardWindow( } private fun dispatchCapsState(setShift: (Boolean, Boolean) -> Unit) { + // TODO: 启用自动首句大写后,点击方向键时,保持Shift锁定状态功能将无法生效 if (theme.generalStyle.autoCaps.toBoolean() && Rime.isAsciiMode && currentKeyboardView?.isCapsOn == false) { setShift(false, cursorCapsMode != 0) } @@ -265,7 +266,9 @@ class KeyboardWindow( start: Int, end: Int, ) { - dispatchCapsState { on, shifted -> currentKeyboardView?.setShifted(on, shifted) } + dispatchCapsState { on, shifted -> + currentKeyboard?.setShifted(on, shifted)?.let { if (it) currentKeyboardView?.invalidateAllKeys() } + } } override fun onRimeSchemaUpdated(schema: SchemaItem) { From e7381583a23ae69fdf80f8e842348a026bf558a6 Mon Sep 17 00:00:00 2001 From: Mule <193615967+MULE-FEHU-EOLIA-ARTONELICO@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:46:34 +0800 Subject: [PATCH 4/5] fix: space, number, symbol keys hook shift not working --- .../keyboard/CommonKeyboardActionListener.kt | 32 ++++++++----------- .../osfans/trime/ime/keyboard/KeyAction.kt | 20 ++++++------ app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values-zh-rTW/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 5 files changed, 26 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/CommonKeyboardActionListener.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/CommonKeyboardActionListener.kt index 9f86c2323f..c3e8664baf 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/CommonKeyboardActionListener.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/CommonKeyboardActionListener.kt @@ -248,24 +248,20 @@ class CommonKeyboardActionListener( KeyEvent.KEYCODE_MENU -> showEnabledSchemaPicker() else -> { if (action.modifier == 0 && KeyboardSwitcher.currentKeyboard.isOnlyShiftOn) { - if (action.code == KeyEvent.KEYCODE_SPACE && prefs.keyboard.hookShiftSpace) { + val shouldHookSpace = + prefs.keyboard.hookShiftSpace && action.code == KeyEvent.KEYCODE_SPACE + val shouldHookNumber = + prefs.keyboard.hookShiftNum && action.code in KeyEvent.KEYCODE_0..KeyEvent.KEYCODE_9 + val shouldHookSymbol = + (prefs.keyboard.hookShiftSymbol || !Rime.isAsciiMode) && + ( + action.code in KeyEvent.KEYCODE_GRAVE..KeyEvent.KEYCODE_SLASH || + action.code == KeyEvent.KEYCODE_COMMA || + action.code == KeyEvent.KEYCODE_PERIOD + ) + if (shouldHookSpace || shouldHookNumber || shouldHookSymbol) { onKey(action.code, 0) return - } else if (action.code >= KeyEvent.KEYCODE_0 && - action.code <= KeyEvent.KEYCODE_9 && - prefs.keyboard.hookShiftNum - ) { - onKey(action.code, 0) - return - } else if (prefs.keyboard.hookShiftSymbol) { - if (action.code >= KeyEvent.KEYCODE_GRAVE && - action.code <= KeyEvent.KEYCODE_SLASH || - action.code == KeyEvent.KEYCODE_COMMA || - action.code == KeyEvent.KEYCODE_PERIOD - ) { - onKey(action.code, 0) - return - } } } val modifier = @@ -274,10 +270,8 @@ class CommonKeyboardActionListener( (action.modifier and KeyEvent.META_CTRL_ON) != 0 -> { when (action.code) { in KeyEvent.KEYCODE_DPAD_UP..KeyEvent.KEYCODE_DPAD_RIGHT, - KeyEvent.KEYCODE_MOVE_HOME, - KeyEvent.KEYCODE_MOVE_END, + KeyEvent.KEYCODE_MOVE_HOME, KeyEvent.KEYCODE_MOVE_END, -> action.modifier or KeyboardSwitcher.currentKeyboard.modifier - else -> action.modifier } } diff --git a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyAction.kt b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyAction.kt index d852915dcc..d9d3452bbc 100644 --- a/app/src/main/java/com/osfans/trime/ime/keyboard/KeyAction.kt +++ b/app/src/main/java/com/osfans/trime/ime/keyboard/KeyAction.kt @@ -12,7 +12,6 @@ import com.osfans.trime.ime.enums.Keycode import com.osfans.trime.util.virtualKeyCharacterMap import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.serializer -import splitties.bitflags.hasFlag /** [按鍵][Key]的各種事件(單擊、長按、滑動等) */ class KeyAction( @@ -61,20 +60,21 @@ class KeyAction( } fun getLabel(keyboard: Keyboard): String { - val state = states?.get(if (Rime.getOption(toggle)) 1 else 0) - if (state != null) return state + states?.get(if (Rime.getOption(toggle)) 1 else 0)?.let { return it } if (keyboard.isOnlyShiftOn) { - if (code in KeyEvent.KEYCODE_0..KeyEvent.KEYCODE_9 && !hookShiftNum) { + if (!hookShiftNum && !Rime.isComposing && code in KeyEvent.KEYCODE_0..KeyEvent.KEYCODE_9) { return adjustCase(shiftLabel, keyboard) } - if (code in KeyEvent.KEYCODE_GRAVE..KeyEvent.KEYCODE_SLASH || - code == KeyEvent.KEYCODE_COMMA || - code == KeyEvent.KEYCODE_PERIOD + if (!hookShiftSymbol && + Rime.isAsciiMode && + ( + code in KeyEvent.KEYCODE_GRAVE..KeyEvent.KEYCODE_SLASH || + code == KeyEvent.KEYCODE_COMMA || + code == KeyEvent.KEYCODE_PERIOD + ) ) { - if (!hookShiftSymbol) return adjustCase(shiftLabel, keyboard) + return adjustCase(shiftLabel, keyboard) } - } else if ((modifier or keyboard.modifier).hasFlag(KeyEvent.META_SHIFT_ON)) { - return adjustCase(shiftLabel, keyboard) } return adjustCase(label, keyboard) } diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d8af5c7417..ebc7509352 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -133,7 +133,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 点击空格时,忽略Shift的锁定状态 点击0-9时,忽略Shift的锁定状态 点击符号键时,忽略Shift的锁定状态 - 点击方向键时,不重置Shift的锁定状态 + 点击方向键时,保持Shift的锁定状态 工具箱 导出 跳到最后 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e9b53f4f2a..ad04c8a4e5 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -135,7 +135,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 點擊空格時,忽略Shift的鎖定狀態 點擊0-9時,忽略Shift的鎖定狀態 點擊符號鍵時,忽略Shift的鎖定狀態 - 點選方向鍵時,不重置Shift的鎖定狀態 + 點選方向鍵時,保持Shift的鎖定狀態 匯出 跳到最後 抱歉,但我們為您帶來了一些紀錄檔以供調查。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d0fe3661cc..4f49b475f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -137,7 +137,7 @@ SPDX-License-Identifier: GPL-3.0-or-later Ignore Shift locked for Space Ignore Shift locked for 0-9 Ignore Shift locked for Symbol keys - Not reset Shift state for arrow keys + Keep Shift locked for Arrow keys Logcat process is already created Application crashed Sorry, but we bring you some logs to investigate. From 5f9947a617d96e1d21c1130e2787f97460b73710 Mon Sep 17 00:00:00 2001 From: Mule <193615967+MULE-FEHU-EOLIA-ARTONELICO@users.noreply.github.com> Date: Sat, 15 Feb 2025 01:43:08 +0800 Subject: [PATCH 5/5] fix: no vibrate effect for candidates --- app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt | 7 +++++-- .../osfans/trime/ime/bar/ui/always/switches/SwitchesUi.kt | 4 +++- .../ime/candidates/compact/CompactCandidateModule.kt | 7 +++++-- .../unrolled/window/BaseUnrolledCandidateWindow.kt | 8 ++++++-- 4 files changed, 19 insertions(+), 7 deletions(-) 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 63b3670857..c52e679270 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 @@ -29,6 +29,7 @@ import com.osfans.trime.ime.candidates.popup.PopupCandidatesMode import com.osfans.trime.ime.candidates.unrolled.window.FlexboxUnrolledCandidateWindow import com.osfans.trime.ime.core.TrimeInputMethodService import com.osfans.trime.ime.dependency.InputScope +import com.osfans.trime.ime.keyboard.InputFeedbackManager import com.osfans.trime.ime.keyboard.KeyboardWindow import com.osfans.trime.ime.window.BoardWindow import com.osfans.trime.ime.window.BoardWindowManager @@ -139,7 +140,8 @@ class QuickBar( } private fun setUnrollButtonToAttach() { - candidateUi.unrollButton.setOnClickListener { + candidateUi.unrollButton.setOnClickListener { view -> + InputFeedbackManager.keyPressVibrate(view) windowManager.attachWindow( FlexboxUnrolledCandidateWindow(context, service, rime, theme, this, windowManager, candidate.compactCandidateModule), ) @@ -148,7 +150,8 @@ class QuickBar( } private fun setUnrollButtonToDetach() { - candidateUi.unrollButton.setOnClickListener { + candidateUi.unrollButton.setOnClickListener { view -> + InputFeedbackManager.keyPressVibrate(view) windowManager.attachWindow(KeyboardWindow) } candidateUi.unrollButton.setIcon(R.drawable.ic_baseline_expand_less_24) diff --git a/app/src/main/java/com/osfans/trime/ime/bar/ui/always/switches/SwitchesUi.kt b/app/src/main/java/com/osfans/trime/ime/bar/ui/always/switches/SwitchesUi.kt index 817ccc48f3..a6161b56a6 100644 --- a/app/src/main/java/com/osfans/trime/ime/bar/ui/always/switches/SwitchesUi.kt +++ b/app/src/main/java/com/osfans/trime/ime/bar/ui/always/switches/SwitchesUi.kt @@ -9,6 +9,7 @@ import android.view.ViewGroup import com.chad.library.adapter4.util.setOnDebouncedItemClick import com.osfans.trime.data.schema.Schema import com.osfans.trime.data.theme.Theme +import com.osfans.trime.ime.keyboard.InputFeedbackManager import com.osfans.trime.ime.symbol.SpacesItemDecoration import splitties.dimensions.dp import splitties.views.dsl.core.Ui @@ -42,7 +43,8 @@ class SwitchesUi( listener: (Schema.Switch) -> Unit, debounceTime: Long = 300L, ) { - switchesAdapter.setOnDebouncedItemClick(debounceTime) { adapter, _, position -> + switchesAdapter.setOnDebouncedItemClick(debounceTime) { adapter, view, position -> + InputFeedbackManager.keyPressVibrate(view) (adapter as? SwitchesAdapter)?.items?.getOrNull(position)?.let(listener) } } diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateModule.kt b/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateModule.kt index 75ce9983a3..d2fd356722 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateModule.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/compact/CompactCandidateModule.kt @@ -67,8 +67,11 @@ class CompactCandidateModule( val adapter by lazy { CompactCandidateViewAdapter(theme).apply { - setOnItemClickListener { _, _, position -> - rime.launchOnReady { it.selectCandidate(previous + position) } + setOnItemClickListener { _, view, position -> + rime.launchOnReady { + InputFeedbackManager.keyPressVibrate(view) + it.selectCandidate(previous + position) + } } setOnItemLongClickListener { _, view, position -> showCandidateAction(previous + position, items[position].text, view) diff --git a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/window/BaseUnrolledCandidateWindow.kt b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/window/BaseUnrolledCandidateWindow.kt index 8decea8bf3..f256bbde25 100644 --- a/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/window/BaseUnrolledCandidateWindow.kt +++ b/app/src/main/java/com/osfans/trime/ime/candidates/unrolled/window/BaseUnrolledCandidateWindow.kt @@ -27,6 +27,7 @@ import com.osfans.trime.ime.candidates.unrolled.CandidatesPagingSource import com.osfans.trime.ime.candidates.unrolled.PagingCandidateViewAdapter import com.osfans.trime.ime.candidates.unrolled.UnrolledCandidateLayout import com.osfans.trime.ime.core.TrimeInputMethodService +import com.osfans.trime.ime.keyboard.InputFeedbackManager import com.osfans.trime.ime.keyboard.KeyboardWindow import com.osfans.trime.ime.window.BoardWindow import com.osfans.trime.ime.window.BoardWindowManager @@ -107,8 +108,11 @@ abstract class BaseUnrolledCandidateWindow( fun bindCandidateUiViewHolder(holder: CandidateViewHolder) { holder.itemView.run { - setOnClickListener { - rime.launchOnReady { it.selectCandidate(holder.idx) } + setOnClickListener { view -> + rime.launchOnReady { + InputFeedbackManager.keyPressVibrate(view) + it.selectCandidate(holder.idx) + } } setOnLongClickListener { view -> compactCandidate.showCandidateAction(holder.idx, holder.text, view)