Skip to content

Commit 776eb0c

Browse files
committed
handle physical keyboard key states
1 parent 4239d32 commit 776eb0c

File tree

8 files changed

+80
-23
lines changed

8 files changed

+80
-23
lines changed

entry/src/main/cpp/napi_init.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ API(toggle) {
3939
}
4040

4141
API(processKey) {
42-
GET_ARGS(3)
42+
GET_ARGS(4)
4343
GET_U32(unicode, 0)
4444
GET_I32(keyCode, 1)
45-
GET_BOOL(isRelease, 2)
46-
auto state = fcitx::processKey(unicode, keyCode, isRelease);
45+
GET_U32(states, 2)
46+
GET_BOOL(isRelease, 3)
47+
auto state = fcitx::processKey(unicode, keyCode, states, isRelease);
4748
OBJECT(ret)
4849
SET(ret, "commit", state.commit)
4950
SET(ret, "preedit", state.preedit)

entry/src/main/cpp/src/fcitx.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "fcitx.h"
2+
#include <cstdint>
23
#include <fcitx-utils/event.h>
34
#include <fcitx-utils/eventdispatcher.h>
45
#include <fcitx-utils/standardpath.h>
@@ -98,9 +99,9 @@ InputContextState reset() {
9899
return with_fcitx([] { return frontend->reset(); });
99100
}
100101

101-
InputContextState processKey(uint32_t unicode, int32_t keyCode, bool isRelease) {
102-
return with_fcitx([unicode, keyCode, isRelease] {
103-
auto key = ohKeyToFcitxKey(unicode, keyCode);
102+
InputContextState processKey(uint32_t unicode, int32_t keyCode, uint32_t states, bool isRelease) {
103+
return with_fcitx([unicode, keyCode, states, isRelease] {
104+
auto key = ohKeyToFcitxKey(unicode, keyCode, states);
104105
return frontend->keyEvent(key, isRelease);
105106
});
106107
}

entry/src/main/cpp/src/fcitx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ void init(const std::string &bundle, const std::string &resfile);
1919
void focusIn(bool clientPreedit);
2020
void focusOut();
2121
InputContextState reset();
22-
InputContextState processKey(uint32_t unicode, int32_t keyCode, bool isRelease);
22+
InputContextState processKey(uint32_t unicode, int32_t keyCode, uint32_t states, bool isRelease);
2323
void selectCandidate(int index);
2424
void askCandidateAction(int index);
2525
void activateCandidateAction(int index, int id);

entry/src/main/cpp/src/keycode.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <cstdint>
12
#include <linux/input-event-codes.h>
23
#include "keycode.h"
34
#include "ohkeycode.h"
@@ -273,8 +274,8 @@ uint16_t ohKeyCodeToFcitxKeyCode(int32_t keyCode) {
273274
return 0;
274275
}
275276

276-
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode) {
277+
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode, uint32_t states) {
277278
auto keysym = unicode ? Key::keySymFromUnicode(unicode) : ohKeyCodeToFcitxKeySym(keyCode);
278-
return Key{keysym, KeyStates{}, ohKeyCodeToFcitxKeyCode(keyCode)};
279+
return Key{keysym, KeyStates{states}, ohKeyCodeToFcitxKeyCode(keyCode)};
279280
}
280281
} // namespace fcitx

entry/src/main/cpp/src/keycode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#pragma once
22

3+
#include <cstdint>
34
#include <fcitx-utils/key.h>
45

56
namespace fcitx {
6-
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode);
7+
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode, uint32_t states);
78
}

entry/src/main/cpp/types/libentry/Index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface InputContextState {
99
cursorPos: number
1010
accepted: boolean
1111
}
12-
export const processKey: (unicode: number, keyCode: number, isRelease: boolean) => InputContextState
12+
export const processKey: (unicode: number, keyCode: number, states: number, isRelease: boolean) => InputContextState
1313
export const reset: () => InputContextState
1414
export const toggle: () => void
1515
export const selectCandidate: (index: number) => void
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { KeyEvent } from "@kit.InputKit";
2+
3+
/**
4+
* translated from
5+
* [fcitx-utils/keysym.h](https://github.com/fcitx/fcitx5/blob/0346e58/src/lib/fcitx-utils/keysym.h)
6+
*/
7+
export enum KeyState {
8+
NO_STATE = 0,
9+
SHIFT = 1 << 0,
10+
CAPS_LOCK = 1 << 1,
11+
CTRL = 1 << 2,
12+
ALT = 1 << 3,
13+
MOD_1 = ALT,
14+
ALT_SHIFT = ALT | SHIFT,
15+
CTRL_SHIFT = CTRL | SHIFT,
16+
CTRL_ALT = CTRL | ALT,
17+
CTRL_ALT_SHIFT = CTRL | ALT | SHIFT,
18+
NUM_LOCK = 1 << 4,
19+
MOD_2 = NUM_LOCK,
20+
HYPER = 1 << 5,
21+
MOD_3 = HYPER,
22+
SUPER = 1 << 6,
23+
MOD_4 = SUPER,
24+
MOD_5 = 1 << 7,
25+
MOUSE_PRESSED = 1 << 8,
26+
HANDLED_MASK = 1 << 24,
27+
IGNORED_MASK = 1 << 25,
28+
SUPER_2 = 1 << 26, // Gtk virtual Super
29+
HYPER_2 = 1 << 27, // Gtk virtual Hyper
30+
META = 1 << 28,
31+
VIRTUAL = 1 << 29,
32+
33+
REPEAT = 1 << 31,
34+
USED_MASK = 0x5c001fff,
35+
SIMPLE_MASK = CTRL_ALT_SHIFT | SUPER | SUPER_2 | HYPER | META
36+
}
37+
38+
export function statesFromKeyEvent(e: KeyEvent): number {
39+
let states = KeyState.NO_STATE
40+
if (e.altKey) states |= KeyState.ALT
41+
if (e.ctrlKey) states |= KeyState.CTRL
42+
if (e.shiftKey) states |= KeyState.SHIFT
43+
if (e.capsLock) states |= KeyState.CAPS_LOCK
44+
if (e.numLock) states |= KeyState.NUM_LOCK
45+
if (e.logoKey) states |= KeyState.META
46+
return states
47+
}

entry/src/main/ets/InputMethodExtensionAbility/model/KeyboardController.ets

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { webview } from '@kit.ArkWeb';
22
import type { InputMethodExtensionContext } from '@kit.IMEKit';
33
import { inputMethodEngine } from '@kit.IMEKit';
44
import { display } from '@kit.ArkUI';
5-
import { KeyCode } from '@kit.InputKit';
5+
import { Action, KeyAction, KeyCode, KeyEvent } from '@kit.InputKit';
66
import { SystemEvent, VirtualKeyboardEvent } from '../../../fcitx5-keyboard-web/src/api';
77
import fcitx, { InputContextState } from 'libentry.so';
88
import { FcitxEvent } from './FcitxEvent';
99
import { convertCode } from './keycode';
1010
import { onTextChange, redo, resetStacks, undo } from './TextOperation';
11+
import { KeyState, statesFromKeyEvent } from './KeyState';
1112

1213
const ability: inputMethodEngine.InputMethodAbility = inputMethodEngine.getInputMethodAbility();
1314
const keyboardDelegate = inputMethodEngine.getKeyboardDelegate() // Physical keyboard
@@ -278,7 +279,7 @@ export class KeyboardController {
278279
}
279280

280281
public handleKey(key: string, keyCode?: number): void {
281-
const res = fcitx.processKey(key ? key.charCodeAt(0) : 0, keyCode ?? 0, false)
282+
const res = fcitx.processKey(key ? key.charCodeAt(0) : 0, keyCode ?? 0, KeyState.VIRTUAL, false)
282283
if (!this.processResult(res)) {
283284
switch (keyCode) { // Check code first as enter has to be handled differently, which has key \r.
284285
case KeyCode.KEYCODE_DEL:
@@ -391,10 +392,19 @@ export class KeyboardController {
391392
})
392393
}
393394

394-
private physicalKeyEventHandler(e: inputMethodEngine.KeyEvent): boolean {
395-
const isRelease = e.keyAction === 3
396-
const res = fcitx.processKey(0, e.keyCode, isRelease)
397-
return this.processResult(res)
395+
private physicalKeyEventHandler(e: KeyEvent): boolean {
396+
const isRelease = e.action.valueOf() === Action.UP
397+
const states = statesFromKeyEvent(e)
398+
const charCode = e.unicodeChar
399+
if (charCode > 0 && charCode !== '\t'.charCodeAt(0) && charCode !== '\n'.charCodeAt(0)) {
400+
const res = fcitx.processKey(charCode, 0, states, isRelease)
401+
return this.processResult(res)
402+
}
403+
if (e.key.code != KeyCode.KEYCODE_UNKNOWN) {
404+
const res = fcitx.processKey(0, e.key.code, states, isRelease)
405+
return this.processResult(res)
406+
}
407+
return false
398408
}
399409

400410
private initHelper() {
@@ -414,10 +424,7 @@ export class KeyboardController {
414424

415425
private registerListener(): void {
416426
this.registerInputListener();
417-
keyboardDelegate.on('keyDown', (e) => {
418-
return this.physicalKeyEventHandler(e)
419-
})
420-
keyboardDelegate.on('keyUp', (e) => {
427+
keyboardDelegate.on('keyEvent', (e) => {
421428
return this.physicalKeyEventHandler(e)
422429
})
423430
// This is not called on focus.
@@ -471,8 +478,7 @@ export class KeyboardController {
471478
ability.off('inputStart');
472479
ability.off('inputStop', () => {
473480
});
474-
keyboardDelegate.off('keyDown')
475-
keyboardDelegate.off('keyUp')
481+
keyboardDelegate.off('keyEvent')
476482
keyboardDelegate.off('textChange')
477483
this.panel?.off('show')
478484
this.panel?.off('hide')

0 commit comments

Comments
 (0)