Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions entry/src/main/cpp/napi_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ API(toggle) {
}

API(processKey) {
GET_ARGS(3)
GET_ARGS(4)
GET_U32(unicode, 0)
GET_I32(keyCode, 1)
GET_BOOL(isRelease, 2)
auto state = fcitx::processKey(unicode, keyCode, isRelease);
GET_U32(states, 2)
GET_BOOL(isRelease, 3)
auto state = fcitx::processKey(unicode, keyCode, states, isRelease);
OBJECT(ret)
SET(ret, "commit", state.commit)
SET(ret, "preedit", state.preedit)
Expand Down
7 changes: 4 additions & 3 deletions entry/src/main/cpp/src/fcitx.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "fcitx.h"
#include <cstdint>
#include <fcitx-utils/event.h>
#include <fcitx-utils/eventdispatcher.h>
#include <fcitx-utils/standardpath.h>
Expand Down Expand Up @@ -98,9 +99,9 @@ InputContextState reset() {
return with_fcitx([] { return frontend->reset(); });
}

InputContextState processKey(uint32_t unicode, int32_t keyCode, bool isRelease) {
return with_fcitx([unicode, keyCode, isRelease] {
auto key = ohKeyToFcitxKey(unicode, keyCode);
InputContextState processKey(uint32_t unicode, int32_t keyCode, uint32_t states, bool isRelease) {
return with_fcitx([unicode, keyCode, states, isRelease] {
auto key = ohKeyToFcitxKey(unicode, keyCode, states);
return frontend->keyEvent(key, isRelease);
});
}
Expand Down
2 changes: 1 addition & 1 deletion entry/src/main/cpp/src/fcitx.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void init(const std::string &bundle, const std::string &resfile);
void focusIn(bool clientPreedit);
void focusOut();
InputContextState reset();
InputContextState processKey(uint32_t unicode, int32_t keyCode, bool isRelease);
InputContextState processKey(uint32_t unicode, int32_t keyCode, uint32_t states, bool isRelease);
void selectCandidate(int index);
void askCandidateAction(int index);
void activateCandidateAction(int index, int id);
Expand Down
5 changes: 3 additions & 2 deletions entry/src/main/cpp/src/keycode.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <cstdint>
#include <linux/input-event-codes.h>
#include "keycode.h"
#include "ohkeycode.h"
Expand Down Expand Up @@ -273,8 +274,8 @@ uint16_t ohKeyCodeToFcitxKeyCode(int32_t keyCode) {
return 0;
}

Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode) {
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode, uint32_t states) {
auto keysym = unicode ? Key::keySymFromUnicode(unicode) : ohKeyCodeToFcitxKeySym(keyCode);
return Key{keysym, KeyStates{}, ohKeyCodeToFcitxKeyCode(keyCode)};
return Key{keysym, KeyStates{states}, ohKeyCodeToFcitxKeyCode(keyCode)};
}
} // namespace fcitx
3 changes: 2 additions & 1 deletion entry/src/main/cpp/src/keycode.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once

#include <cstdint>
#include <fcitx-utils/key.h>

namespace fcitx {
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode);
Key ohKeyToFcitxKey(uint32_t unicode, int32_t keyCode, uint32_t states);
}
2 changes: 1 addition & 1 deletion entry/src/main/cpp/types/libentry/Index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface InputContextState {
cursorPos: number
accepted: boolean
}
export const processKey: (unicode: number, keyCode: number, isRelease: boolean) => InputContextState
export const processKey: (unicode: number, keyCode: number, states: number, isRelease: boolean) => InputContextState
export const reset: () => InputContextState
export const toggle: () => void
export const selectCandidate: (index: number) => void
Expand Down
47 changes: 47 additions & 0 deletions entry/src/main/ets/InputMethodExtensionAbility/model/KeyState.ets
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { KeyEvent } from "@kit.InputKit";

/**
* translated from
* [fcitx-utils/keysym.h](https://github.com/fcitx/fcitx5/blob/0346e58/src/lib/fcitx-utils/keysym.h)
*/
export enum KeyState {
NO_STATE = 0,
SHIFT = 1 << 0,
CAPS_LOCK = 1 << 1,
CTRL = 1 << 2,
ALT = 1 << 3,
MOD_1 = ALT,
ALT_SHIFT = ALT | SHIFT,
CTRL_SHIFT = CTRL | SHIFT,
CTRL_ALT = CTRL | ALT,
CTRL_ALT_SHIFT = CTRL | ALT | SHIFT,
NUM_LOCK = 1 << 4,
MOD_2 = NUM_LOCK,
HYPER = 1 << 5,
MOD_3 = HYPER,
SUPER = 1 << 6,
MOD_4 = SUPER,
MOD_5 = 1 << 7,
MOUSE_PRESSED = 1 << 8,
HANDLED_MASK = 1 << 24,
IGNORED_MASK = 1 << 25,
SUPER_2 = 1 << 26, // Gtk virtual Super
HYPER_2 = 1 << 27, // Gtk virtual Hyper
META = 1 << 28,
VIRTUAL = 1 << 29,

REPEAT = 1 << 31,
USED_MASK = 0x5c001fff,
SIMPLE_MASK = CTRL_ALT_SHIFT | SUPER | SUPER_2 | HYPER | META
}

export function statesFromKeyEvent(e: KeyEvent): number {
let states = KeyState.NO_STATE
if (e.altKey) states |= KeyState.ALT
if (e.ctrlKey) states |= KeyState.CTRL
if (e.shiftKey) states |= KeyState.SHIFT
if (e.capsLock) states |= KeyState.CAPS_LOCK
if (e.numLock) states |= KeyState.NUM_LOCK
if (e.logoKey) states |= KeyState.META
return states
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { webview } from '@kit.ArkWeb';
import type { InputMethodExtensionContext } from '@kit.IMEKit';
import { inputMethodEngine } from '@kit.IMEKit';
import { display } from '@kit.ArkUI';
import { KeyCode } from '@kit.InputKit';
import { Action, KeyAction, KeyCode, KeyEvent } from '@kit.InputKit';
import { SystemEvent, VirtualKeyboardEvent } from '../../../fcitx5-keyboard-web/src/api';
import fcitx, { InputContextState } from 'libentry.so';
import { FcitxEvent } from './FcitxEvent';
import { convertCode } from './keycode';
import { onTextChange, redo, resetStacks, undo } from './TextOperation';
import { KeyState, statesFromKeyEvent } from './KeyState';

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

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

private physicalKeyEventHandler(e: inputMethodEngine.KeyEvent): boolean {
const isRelease = e.keyAction === 3
const res = fcitx.processKey(0, e.keyCode, isRelease)
return this.processResult(res)
private physicalKeyEventHandler(e: KeyEvent): boolean {
const isRelease = e.action.valueOf() === Action.UP
const states = statesFromKeyEvent(e)
const charCode = e.unicodeChar
if (charCode > 0 && charCode !== '\t'.charCodeAt(0) && charCode !== '\n'.charCodeAt(0)) {
const res = fcitx.processKey(charCode, 0, states, isRelease)
return this.processResult(res)
}
if (e.key.code != KeyCode.KEYCODE_UNKNOWN) {
const res = fcitx.processKey(0, e.key.code, states, isRelease)
return this.processResult(res)
}
return false
}

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

private registerListener(): void {
this.registerInputListener();
keyboardDelegate.on('keyDown', (e) => {
return this.physicalKeyEventHandler(e)
})
keyboardDelegate.on('keyUp', (e) => {
keyboardDelegate.on('keyEvent', (e) => {
return this.physicalKeyEventHandler(e)
})
// This is not called on focus.
Expand Down Expand Up @@ -471,8 +478,7 @@ export class KeyboardController {
ability.off('inputStart');
ability.off('inputStop', () => {
});
keyboardDelegate.off('keyDown')
keyboardDelegate.off('keyUp')
keyboardDelegate.off('keyEvent')
keyboardDelegate.off('textChange')
this.panel?.off('show')
this.panel?.off('hide')
Expand Down