Skip to content

Commit

Permalink
feat: enhance modifier key
Browse files Browse the repository at this point in the history
  • Loading branch information
tumuyan committed Apr 21, 2022
1 parent bacd46d commit 71fce4a
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 61 deletions.
8 changes: 8 additions & 0 deletions app/src/main/java/com/osfans/trime/Rime.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,17 @@ public void toggleOption(int i) {
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
*/
public static int META_SHIFT_ON = get_modifier_by_name("Shift");
public static int META_CTRL_ON = get_modifier_by_name("Control");
public static int META_ALT_ON = get_modifier_by_name("Alt");
public static int META_SYM_ON = get_modifier_by_name("Super");
public static int META_META_ON = get_modifier_by_name("Meta");

public static int META_RELEASE_ON = get_modifier_by_name("Release");
private static boolean showSwitches = true;
private static boolean showSwitchArrow = false;
Expand Down
38 changes: 27 additions & 11 deletions app/src/main/java/com/osfans/trime/ime/core/EditorInstance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ class EditorInstance(private val ims: InputMethodService) {
fun meta(
ctrl: Boolean = false,
alt: Boolean = false,
shift: Boolean = false
shift: Boolean = false,
meta: Boolean = false,
sym: Boolean = false,
): Int {
var metaState = 0
if (ctrl) {
Expand All @@ -143,6 +145,13 @@ class EditorInstance(private val ims: InputMethodService) {
if (shift) {
metaState = metaState or KeyEvent.META_SHIFT_ON or KeyEvent.META_SHIFT_LEFT_ON
}
if (meta) {
metaState = metaState or KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON
}
if (sym) {
metaState = metaState or KeyEvent.META_SYM_ON
}

return metaState
}

Expand Down Expand Up @@ -214,16 +223,14 @@ class EditorInstance(private val ims: InputMethodService) {
if (metaState and KeyEvent.META_SHIFT_ON != 0) {
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_SHIFT_LEFT, 0)
}
/*
var sendKeyDownUp = true
if (metaState == 0 && mAsciiMode) {
// 使用ASCII键盘输入英文字符时,直接上屏,跳过复杂的调用,从表面上解决issue #301 知乎输入英语后输入法失去焦点的问题
val keyText = toCharString(keyEventCode)
if (keyText.isNotEmpty()) {
ic.commitText(keyText, 1)
sendKeyDownUp = false
}
} */
if (metaState and KeyEvent.META_META_ON != 0) {
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_META_LEFT, 0)
}

if (metaState and KeyEvent.META_SYM_ON != 0) {
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_SYM, 0)
}

for (n in 0 until count) {
sendDownKeyEvent(eventTime, keyEventCode, metaState)
sendUpKeyEvent(eventTime, keyEventCode, metaState)
Expand All @@ -237,6 +244,15 @@ class EditorInstance(private val ims: InputMethodService) {
if (metaState and KeyEvent.META_CTRL_ON != 0) {
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_CTRL_LEFT, 0)
}

if (metaState and KeyEvent.META_META_ON != 0) {
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_META_LEFT, 0)
}

if (metaState and KeyEvent.META_SYM_ON != 0) {
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_SYM, 0)
}

ic.endBatchEdit()
return true
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/osfans/trime/ime/core/Trime.java
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ private boolean composeEvent(@NonNull KeyEvent event) {
final int keyCode = event.getKeyCode();
if (keyCode == KeyEvent.KEYCODE_MENU) return false; // 不處理 Menu 鍵
if (keyCode >= Key.getSymbolStart()) return false; // 只處理安卓標準按鍵
if (event.getRepeatCount() == 0 && KeyEvent.isModifierKey(keyCode)) {
if (event.getRepeatCount() == 0 && Key.isTrimeModifierKey(keyCode)) {
boolean ret =
onRimeKey(
Event.getRimeEvent(
Expand Down
18 changes: 16 additions & 2 deletions app/src/main/java/com/osfans/trime/ime/keyboard/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private boolean parseAction(String s) {
@NonNull
private String adjustCase(String s) {
if (TextUtils.isEmpty(s)) return "";
if (s.length() == 1 && mKeyboard != null && mKeyboard.isShifted())
if (s.length() == 1 && mKeyboard != null && mKeyboard.needUpCase())
s = s.toUpperCase(Locale.getDefault());
else if (s.length() == 1
&& mKeyboard != null
Expand All @@ -200,7 +200,7 @@ public String getText() {
String s = "";
if (!TextUtils.isEmpty(text)) s = text;
else if (mKeyboard != null
&& mKeyboard.isShifted()
&& mKeyboard.needUpCase()
&& mask == 0
&& code >= KeyEvent.KEYCODE_A
&& code <= KeyEvent.KEYCODE_Z) s = label;
Expand Down Expand Up @@ -284,16 +284,30 @@ public static int[] getRimeEvent(int code, int mask) {
if (hasModifier(mask, KeyEvent.META_SHIFT_ON)) m |= Rime.META_SHIFT_ON;
if (hasModifier(mask, KeyEvent.META_CTRL_ON)) m |= Rime.META_CTRL_ON;
if (hasModifier(mask, KeyEvent.META_ALT_ON)) m |= Rime.META_ALT_ON;
if (hasModifier(mask, KeyEvent.META_SYM_ON)) m |= Rime.META_SYM_ON;
if (hasModifier(mask, KeyEvent.META_META_ON)) m |= Rime.META_META_ON;
if (mask == Rime.META_RELEASE_ON) m |= Rime.META_RELEASE_ON;
return new int[] {i, m};
}

public boolean isMeta() {
int c = getCode();
return (c == KeyEvent.KEYCODE_META_LEFT || c == KeyEvent.KEYCODE_META_RIGHT);
}

public boolean isAlt() {
int c = getCode();
return (c == KeyEvent.KEYCODE_ALT_LEFT || c == KeyEvent.KEYCODE_ALT_RIGHT);
}

private static final Map<String, Integer> masks =
new HashMap<String, Integer>() {
{
put("Shift", KeyEvent.META_SHIFT_ON);
put("Control", KeyEvent.META_CTRL_ON);
put("Alt", KeyEvent.META_ALT_ON);
put("Meta", KeyEvent.META_META_ON);
put("SYM", KeyEvent.META_SYM_ON);
}
};

Expand Down
96 changes: 82 additions & 14 deletions app/src/main/java/com/osfans/trime/ime/keyboard/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
package com.osfans.trime.ime.keyboard;

import static android.view.KeyEvent.isModifierKey;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
Expand All @@ -28,6 +30,7 @@
import com.osfans.trime.util.YamlUtils;
import java.util.List;
import java.util.Map;
import timber.log.Timber;

/** {@link Keyboard 鍵盤}中的各個按鍵,包含單擊、長按、滑動等多種{@link Event 事件} */
public class Key {
Expand All @@ -45,12 +48,12 @@ public class Key {
public static final int[] KEY_STATE_PRESSED = {android.R.attr.state_pressed};
public static final int[][] KEY_STATES =
new int[][] {
KEY_STATE_PRESSED_ON,
KEY_STATE_PRESSED_OFF,
KEY_STATE_NORMAL_ON,
KEY_STATE_NORMAL_OFF,
KEY_STATE_PRESSED,
KEY_STATE_NORMAL
KEY_STATE_PRESSED_ON, // 0
KEY_STATE_PRESSED_OFF, // 1
KEY_STATE_NORMAL_ON, // 2
KEY_STATE_NORMAL_OFF, // 3
KEY_STATE_PRESSED, // 4
KEY_STATE_NORMAL // 5
};
public static List<String> androidKeys;
public static Map<String, Map<String, ?>> presetKeys;
Expand Down Expand Up @@ -144,7 +147,7 @@ public Key(Context context, Keyboard parent, Map<String, Object> mk) {
} else if (composing == null && has_menu == null && paging == null) {
send_bindings = false;
}
if (isShift()) mKeyboard.setmShiftKey(this);
mKeyboard.setModiferKey(getCode(), this);
key_text_size = YamlUtils.INSTANCE.getPixel(mk, "key_text_size", 0);
symbol_text_size = YamlUtils.INSTANCE.getPixel(mk, "symbol_text_size", 0);
key_text_color = Config.getColor(context, mk, "key_text_color");
Expand Down Expand Up @@ -423,6 +426,30 @@ public int squaredDistanceFrom(int x, int y) {
return xDist * xDist + yDist * yDist;
}

// Trime把function键消费掉了,因此键盘只处理function键以外的修饰键
public boolean isTrimeModifierKey() {
return isTrimeModifierKey(getCode());
}

public static boolean isTrimeModifierKey(int keycode) {
if (keycode == KeyEvent.KEYCODE_FUNCTION) return false;
return isModifierKey(keycode);
}

public void printModifierKeyState(String invalidKey) {
if (isTrimeModifierKey())
Timber.d(
"\t<TrimeInput>\tkeyState() key=%s, isShifted=%s, on=%s, invalidKey=%s",
getLabel(), mKeyboard.hasModifier(getModifierKeyOnMask()), on, invalidKey);
}

public void printModifierKeyState() {
if (isTrimeModifierKey())
Timber.d(
"\t<TrimeInput>\tkeyState() key=%s, isShifted=%s, on=%s",
getLabel(), mKeyboard.hasModifier(getModifierKeyOnMask()), on);
}

/**
* Returns the drawable state for the key, based on the current state and type of the key.
*
Expand All @@ -431,7 +458,10 @@ public int squaredDistanceFrom(int x, int y) {
*/
public int[] getCurrentDrawableState() {
int[] states = KEY_STATE_NORMAL;
boolean isShifted = isShift() && mKeyboard.isShifted(); // 臨時大寫
boolean isShifted = isTrimeModifierKey() && mKeyboard.hasModifier(getModifierKeyOnMask());
// only for modiferKey debug
if (isTrimeModifierKey()) mKeyboard.printModifierKeyState("getCurrentDrawableState");

if (isShifted || on) {
if (pressed) {
states = KEY_STATE_PRESSED_ON;
Expand All @@ -454,22 +484,60 @@ public int[] getCurrentDrawableState() {
return states;
}

public int getModifierKeyOnMask() {
return getModifierKeyOnMask(getCode());
}

public int getModifierKeyOnMask(int keycode) {
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;
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;
if (keycode == KeyEvent.KEYCODE_SYM) return KeyEvent.META_SYM_ON;
return 0;
}

public boolean isShift() {
int c = getCode();
return (c == KeyEvent.KEYCODE_SHIFT_LEFT || c == KeyEvent.KEYCODE_SHIFT_RIGHT);
}

public boolean isCtrl() {
int c = getCode();
return (c == KeyEvent.KEYCODE_CTRL_LEFT || c == KeyEvent.KEYCODE_CTRL_RIGHT);
}

public boolean isMeta() {
int c = getCode();
return (c == KeyEvent.KEYCODE_META_LEFT || c == KeyEvent.KEYCODE_META_RIGHT);
}

public boolean isAlt() {
int c = getCode();
return (c == KeyEvent.KEYCODE_ALT_LEFT || c == KeyEvent.KEYCODE_ALT_RIGHT);
}

public boolean isSys() {
int c = getCode();
return (c == KeyEvent.KEYCODE_SYM);
}

// shift键在点击时是否触发锁定
public boolean isShiftLock() {
switch (getClick().getShiftLock()) {
case "long":
return false;
case "click":
return true;
}
String s = getClick().getShiftLock();
if ("long".equals(s)) return false;
if ("click".equals(s)) return true;
return !Rime.isAsciiMode();
}

/**
* @param type 同文按键模式(点击/长按/滑动)
* @return
*/
public boolean sendBindings(int type) {
Event e = null;
if (type > 0 && type <= EVENT_NUM) e = events[type];
Expand Down
Loading

0 comments on commit 71fce4a

Please sign in to comment.