Skip to content

Commit 71fce4a

Browse files
committed
feat: enhance modifier key
1 parent bacd46d commit 71fce4a

File tree

8 files changed

+403
-61
lines changed

8 files changed

+403
-61
lines changed

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

+8
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,17 @@ public void toggleOption(int i) {
224224
System.loadLibrary("rime_jni");
225225
}
226226

227+
/*
228+
Android SDK包含了如下6个修饰键的状态,其中function键会被trime消费掉,因此只处理5个键
229+
Android和librime对按键命名并不一致。读取可能有误。librime按键命名见如下链接,
230+
https://github.com/rime/librime/blob/master/src/rime/key_table.cc
231+
*/
227232
public static int META_SHIFT_ON = get_modifier_by_name("Shift");
228233
public static int META_CTRL_ON = get_modifier_by_name("Control");
229234
public static int META_ALT_ON = get_modifier_by_name("Alt");
235+
public static int META_SYM_ON = get_modifier_by_name("Super");
236+
public static int META_META_ON = get_modifier_by_name("Meta");
237+
230238
public static int META_RELEASE_ON = get_modifier_by_name("Release");
231239
private static boolean showSwitches = true;
232240
private static boolean showSwitchArrow = false;

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

+27-11
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ class EditorInstance(private val ims: InputMethodService) {
131131
fun meta(
132132
ctrl: Boolean = false,
133133
alt: Boolean = false,
134-
shift: Boolean = false
134+
shift: Boolean = false,
135+
meta: Boolean = false,
136+
sym: Boolean = false,
135137
): Int {
136138
var metaState = 0
137139
if (ctrl) {
@@ -143,6 +145,13 @@ class EditorInstance(private val ims: InputMethodService) {
143145
if (shift) {
144146
metaState = metaState or KeyEvent.META_SHIFT_ON or KeyEvent.META_SHIFT_LEFT_ON
145147
}
148+
if (meta) {
149+
metaState = metaState or KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON
150+
}
151+
if (sym) {
152+
metaState = metaState or KeyEvent.META_SYM_ON
153+
}
154+
146155
return metaState
147156
}
148157

@@ -214,16 +223,14 @@ class EditorInstance(private val ims: InputMethodService) {
214223
if (metaState and KeyEvent.META_SHIFT_ON != 0) {
215224
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_SHIFT_LEFT, 0)
216225
}
217-
/*
218-
var sendKeyDownUp = true
219-
if (metaState == 0 && mAsciiMode) {
220-
// 使用ASCII键盘输入英文字符时,直接上屏,跳过复杂的调用,从表面上解决issue #301 知乎输入英语后输入法失去焦点的问题
221-
val keyText = toCharString(keyEventCode)
222-
if (keyText.isNotEmpty()) {
223-
ic.commitText(keyText, 1)
224-
sendKeyDownUp = false
225-
}
226-
} */
226+
if (metaState and KeyEvent.META_META_ON != 0) {
227+
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_META_LEFT, 0)
228+
}
229+
230+
if (metaState and KeyEvent.META_SYM_ON != 0) {
231+
sendDownKeyEvent(eventTime, KeyEvent.KEYCODE_SYM, 0)
232+
}
233+
227234
for (n in 0 until count) {
228235
sendDownKeyEvent(eventTime, keyEventCode, metaState)
229236
sendUpKeyEvent(eventTime, keyEventCode, metaState)
@@ -237,6 +244,15 @@ class EditorInstance(private val ims: InputMethodService) {
237244
if (metaState and KeyEvent.META_CTRL_ON != 0) {
238245
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_CTRL_LEFT, 0)
239246
}
247+
248+
if (metaState and KeyEvent.META_META_ON != 0) {
249+
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_META_LEFT, 0)
250+
}
251+
252+
if (metaState and KeyEvent.META_SYM_ON != 0) {
253+
sendUpKeyEvent(eventTime, KeyEvent.KEYCODE_SYM, 0)
254+
}
255+
240256
ic.endBatchEdit()
241257
return true
242258
}

app/src/main/java/com/osfans/trime/ime/core/Trime.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ private boolean composeEvent(@NonNull KeyEvent event) {
845845
final int keyCode = event.getKeyCode();
846846
if (keyCode == KeyEvent.KEYCODE_MENU) return false; // 不處理 Menu 鍵
847847
if (keyCode >= Key.getSymbolStart()) return false; // 只處理安卓標準按鍵
848-
if (event.getRepeatCount() == 0 && KeyEvent.isModifierKey(keyCode)) {
848+
if (event.getRepeatCount() == 0 && Key.isTrimeModifierKey(keyCode)) {
849849
boolean ret =
850850
onRimeKey(
851851
Event.getRimeEvent(

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

+16-2
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ private boolean parseAction(String s) {
182182
@NonNull
183183
private String adjustCase(String s) {
184184
if (TextUtils.isEmpty(s)) return "";
185-
if (s.length() == 1 && mKeyboard != null && mKeyboard.isShifted())
185+
if (s.length() == 1 && mKeyboard != null && mKeyboard.needUpCase())
186186
s = s.toUpperCase(Locale.getDefault());
187187
else if (s.length() == 1
188188
&& mKeyboard != null
@@ -200,7 +200,7 @@ public String getText() {
200200
String s = "";
201201
if (!TextUtils.isEmpty(text)) s = text;
202202
else if (mKeyboard != null
203-
&& mKeyboard.isShifted()
203+
&& mKeyboard.needUpCase()
204204
&& mask == 0
205205
&& code >= KeyEvent.KEYCODE_A
206206
&& code <= KeyEvent.KEYCODE_Z) s = label;
@@ -284,16 +284,30 @@ public static int[] getRimeEvent(int code, int mask) {
284284
if (hasModifier(mask, KeyEvent.META_SHIFT_ON)) m |= Rime.META_SHIFT_ON;
285285
if (hasModifier(mask, KeyEvent.META_CTRL_ON)) m |= Rime.META_CTRL_ON;
286286
if (hasModifier(mask, KeyEvent.META_ALT_ON)) m |= Rime.META_ALT_ON;
287+
if (hasModifier(mask, KeyEvent.META_SYM_ON)) m |= Rime.META_SYM_ON;
288+
if (hasModifier(mask, KeyEvent.META_META_ON)) m |= Rime.META_META_ON;
287289
if (mask == Rime.META_RELEASE_ON) m |= Rime.META_RELEASE_ON;
288290
return new int[] {i, m};
289291
}
290292

293+
public boolean isMeta() {
294+
int c = getCode();
295+
return (c == KeyEvent.KEYCODE_META_LEFT || c == KeyEvent.KEYCODE_META_RIGHT);
296+
}
297+
298+
public boolean isAlt() {
299+
int c = getCode();
300+
return (c == KeyEvent.KEYCODE_ALT_LEFT || c == KeyEvent.KEYCODE_ALT_RIGHT);
301+
}
302+
291303
private static final Map<String, Integer> masks =
292304
new HashMap<String, Integer>() {
293305
{
294306
put("Shift", KeyEvent.META_SHIFT_ON);
295307
put("Control", KeyEvent.META_CTRL_ON);
296308
put("Alt", KeyEvent.META_ALT_ON);
309+
put("Meta", KeyEvent.META_META_ON);
310+
put("SYM", KeyEvent.META_SYM_ON);
297311
}
298312
};
299313

app/src/main/java/com/osfans/trime/ime/keyboard/Key.java

+82-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818
package com.osfans.trime.ime.keyboard;
1919

20+
import static android.view.KeyEvent.isModifierKey;
21+
2022
import android.content.Context;
2123
import android.graphics.drawable.Drawable;
2224
import android.text.TextUtils;
@@ -28,6 +30,7 @@
2830
import com.osfans.trime.util.YamlUtils;
2931
import java.util.List;
3032
import java.util.Map;
33+
import timber.log.Timber;
3134

3235
/** {@link Keyboard 鍵盤}中的各個按鍵,包含單擊、長按、滑動等多種{@link Event 事件} */
3336
public class Key {
@@ -45,12 +48,12 @@ public class Key {
4548
public static final int[] KEY_STATE_PRESSED = {android.R.attr.state_pressed};
4649
public static final int[][] KEY_STATES =
4750
new int[][] {
48-
KEY_STATE_PRESSED_ON,
49-
KEY_STATE_PRESSED_OFF,
50-
KEY_STATE_NORMAL_ON,
51-
KEY_STATE_NORMAL_OFF,
52-
KEY_STATE_PRESSED,
53-
KEY_STATE_NORMAL
51+
KEY_STATE_PRESSED_ON, // 0
52+
KEY_STATE_PRESSED_OFF, // 1
53+
KEY_STATE_NORMAL_ON, // 2
54+
KEY_STATE_NORMAL_OFF, // 3
55+
KEY_STATE_PRESSED, // 4
56+
KEY_STATE_NORMAL // 5
5457
};
5558
public static List<String> androidKeys;
5659
public static Map<String, Map<String, ?>> presetKeys;
@@ -144,7 +147,7 @@ public Key(Context context, Keyboard parent, Map<String, Object> mk) {
144147
} else if (composing == null && has_menu == null && paging == null) {
145148
send_bindings = false;
146149
}
147-
if (isShift()) mKeyboard.setmShiftKey(this);
150+
mKeyboard.setModiferKey(getCode(), this);
148151
key_text_size = YamlUtils.INSTANCE.getPixel(mk, "key_text_size", 0);
149152
symbol_text_size = YamlUtils.INSTANCE.getPixel(mk, "symbol_text_size", 0);
150153
key_text_color = Config.getColor(context, mk, "key_text_color");
@@ -423,6 +426,30 @@ public int squaredDistanceFrom(int x, int y) {
423426
return xDist * xDist + yDist * yDist;
424427
}
425428

429+
// Trime把function键消费掉了,因此键盘只处理function键以外的修饰键
430+
public boolean isTrimeModifierKey() {
431+
return isTrimeModifierKey(getCode());
432+
}
433+
434+
public static boolean isTrimeModifierKey(int keycode) {
435+
if (keycode == KeyEvent.KEYCODE_FUNCTION) return false;
436+
return isModifierKey(keycode);
437+
}
438+
439+
public void printModifierKeyState(String invalidKey) {
440+
if (isTrimeModifierKey())
441+
Timber.d(
442+
"\t<TrimeInput>\tkeyState() key=%s, isShifted=%s, on=%s, invalidKey=%s",
443+
getLabel(), mKeyboard.hasModifier(getModifierKeyOnMask()), on, invalidKey);
444+
}
445+
446+
public void printModifierKeyState() {
447+
if (isTrimeModifierKey())
448+
Timber.d(
449+
"\t<TrimeInput>\tkeyState() key=%s, isShifted=%s, on=%s",
450+
getLabel(), mKeyboard.hasModifier(getModifierKeyOnMask()), on);
451+
}
452+
426453
/**
427454
* Returns the drawable state for the key, based on the current state and type of the key.
428455
*
@@ -431,7 +458,10 @@ public int squaredDistanceFrom(int x, int y) {
431458
*/
432459
public int[] getCurrentDrawableState() {
433460
int[] states = KEY_STATE_NORMAL;
434-
boolean isShifted = isShift() && mKeyboard.isShifted(); // 臨時大寫
461+
boolean isShifted = isTrimeModifierKey() && mKeyboard.hasModifier(getModifierKeyOnMask());
462+
// only for modiferKey debug
463+
if (isTrimeModifierKey()) mKeyboard.printModifierKeyState("getCurrentDrawableState");
464+
435465
if (isShifted || on) {
436466
if (pressed) {
437467
states = KEY_STATE_PRESSED_ON;
@@ -454,22 +484,60 @@ public int[] getCurrentDrawableState() {
454484
return states;
455485
}
456486

487+
public int getModifierKeyOnMask() {
488+
return getModifierKeyOnMask(getCode());
489+
}
490+
491+
public int getModifierKeyOnMask(int keycode) {
492+
if (keycode == KeyEvent.KEYCODE_SHIFT_LEFT || keycode == KeyEvent.KEYCODE_SHIFT_RIGHT)
493+
return KeyEvent.META_SHIFT_ON;
494+
if (keycode == KeyEvent.KEYCODE_CTRL_LEFT || keycode == KeyEvent.KEYCODE_CTRL_RIGHT)
495+
return KeyEvent.META_CTRL_ON;
496+
if (keycode == KeyEvent.KEYCODE_META_LEFT || keycode == KeyEvent.KEYCODE_META_RIGHT)
497+
return KeyEvent.META_META_ON;
498+
if (keycode == KeyEvent.KEYCODE_ALT_LEFT || keycode == KeyEvent.KEYCODE_ALT_RIGHT)
499+
return KeyEvent.META_ALT_ON;
500+
if (keycode == KeyEvent.KEYCODE_SYM) return KeyEvent.META_SYM_ON;
501+
return 0;
502+
}
503+
457504
public boolean isShift() {
458505
int c = getCode();
459506
return (c == KeyEvent.KEYCODE_SHIFT_LEFT || c == KeyEvent.KEYCODE_SHIFT_RIGHT);
460507
}
461508

509+
public boolean isCtrl() {
510+
int c = getCode();
511+
return (c == KeyEvent.KEYCODE_CTRL_LEFT || c == KeyEvent.KEYCODE_CTRL_RIGHT);
512+
}
513+
514+
public boolean isMeta() {
515+
int c = getCode();
516+
return (c == KeyEvent.KEYCODE_META_LEFT || c == KeyEvent.KEYCODE_META_RIGHT);
517+
}
518+
519+
public boolean isAlt() {
520+
int c = getCode();
521+
return (c == KeyEvent.KEYCODE_ALT_LEFT || c == KeyEvent.KEYCODE_ALT_RIGHT);
522+
}
523+
524+
public boolean isSys() {
525+
int c = getCode();
526+
return (c == KeyEvent.KEYCODE_SYM);
527+
}
528+
462529
// shift键在点击时是否触发锁定
463530
public boolean isShiftLock() {
464-
switch (getClick().getShiftLock()) {
465-
case "long":
466-
return false;
467-
case "click":
468-
return true;
469-
}
531+
String s = getClick().getShiftLock();
532+
if ("long".equals(s)) return false;
533+
if ("click".equals(s)) return true;
470534
return !Rime.isAsciiMode();
471535
}
472536

537+
/**
538+
* @param type 同文按键模式(点击/长按/滑动)
539+
* @return
540+
*/
473541
public boolean sendBindings(int type) {
474542
Event e = null;
475543
if (type > 0 && type <= EVENT_NUM) e = events[type];

0 commit comments

Comments
 (0)