Skip to content
Merged
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
13 changes: 11 additions & 2 deletions entry/src/main/ets/pages/StreamPage.ets
Original file line number Diff line number Diff line change
Expand Up @@ -2146,8 +2146,17 @@ struct StreamPage {
if (result === ThreeFingerImeGestureResult.TRIGGERED) {
this.touchInputHandler.cancelActiveInput();
this.panZoomHandler.cancelActiveGesture();
this.showVirtualKeyboard = false;
this.imeManager.show();
if (this.showKeyboardPanel) {
// 三指再次触发时主动关闭;hide() 会同步解除锁定。
this.imeManager.hide();
} else {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
this.showVirtualKeyboard = false;
// 三指呼出的 IME 默认锁定:画面失焦事件只能触发重新显示,
// 仅再次三指或工具条关闭按钮可以主动关闭。
this.imePanelLocked = true;
this.imeManager.setLocked(true);
this.imeManager.show();
}
}
return result !== ThreeFingerImeGestureResult.PASS_THROUGH;
}
Expand Down
50 changes: 39 additions & 11 deletions entry/src/main/ets/service/streaming/StreamIMEManager.ets
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export interface IMECallbacks {
export class StreamIMEManager {
// ── 输入法控制器 ──
private imeController: inputMethod.InputMethodController | null = null;
private showInProgress: boolean = false;
private showRequestId: number = 0;
private imeReadyTime: number = 0;
/** 锁定模式:开启后点击其他区域不会收起 IME / IME bar,HIDE 事件会被拦截并重新唤起软键盘 */
private locked: boolean = false;
Expand Down Expand Up @@ -60,13 +62,6 @@ export class StreamIMEManager {
return this.imeReadyTime;
}

/**
* 当前 IME 是否正在显示
*/
get isVisible(): boolean {
return this.imeController !== null;
}

/**
* 当前是否处于锁定模式
*/
Expand All @@ -88,17 +83,22 @@ export class StreamIMEManager {
*/
async show(): Promise<void> {
const session = this.viewModel?.getSession();
if (!session) return;
if (!session || this.showInProgress || this.imeController) return;

const requestId = ++this.showRequestId;
this.showInProgress = true;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
let win: window.Window | null = null;
let controller: inputMethod.InputMethodController | null = null;

try {
// 监听键盘高度变化
const win = await window.getLastWindow(this.context);
win = await window.getLastWindow(this.context);
if (requestId !== this.showRequestId) return;
win.on('keyboardHeightChange', (height: number) => {
this.callbacks?.onKeyboardHeightChanged(px2vp(height));
});

const controller = inputMethod.getController();
this.imeController = controller;
controller = inputMethod.getController();

// 先绑定输入法(必须先 attach 才能注册回调)
const textConfig: inputMethod.TextConfig = {
Expand All @@ -108,6 +108,11 @@ export class StreamIMEManager {
}
};
await controller.attach(true, textConfig);
if (requestId !== this.showRequestId) {
controller.detach();
win.off('keyboardHeightChange');
return;
}

// attach 成功后注册输入回调
controller.on('insertText', (text: string) => {
Expand Down Expand Up @@ -143,10 +148,32 @@ export class StreamIMEManager {
}
});

// 完成 attach 和全部回调注册后再发布 controller,避免暴露半初始化状态。
this.imeController = controller;
this.callbacks?.onKeyboardVisibilityChanged(true);
this.imeReadyTime = Date.now();
} catch (err) {
console.error(`[StreamPage] Failed to show IME: ${JSON.stringify(err)}`);
if (controller) {
try {
controller.detach();
} catch (cleanupErr) {
console.warn(`[StreamIME] Failed to detach after show error: ${JSON.stringify(cleanupErr)}`);
}
}
if (win) {
try {
win.off('keyboardHeightChange');
} catch (cleanupErr) {
console.warn(`[StreamIME] Failed to remove height listener: ${JSON.stringify(cleanupErr)}`);
}
}
this.imeController = null;
this.locked = false;
this.callbacks?.onKeyboardVisibilityChanged(false);
this.callbacks?.onKeyboardHeightChanged(0);
} finally {
this.showInProgress = false;
}
}

Expand All @@ -155,6 +182,7 @@ export class StreamIMEManager {
*/
hide(): void {
// 主动 hide 时释放锁定状态,避免下次 show 时锁定误传递
this.showRequestId++;
this.locked = false;
try {
if (this.imeController) {
Expand Down
Loading