Skip to content

Commit 4a1fc6e

Browse files
committed
fix(core,web): resolve focus chain and signal propagation in multi-layered iframes
1 parent 8a13e8f commit 4a1fc6e

File tree

2 files changed

+19
-6
lines changed

2 files changed

+19
-6
lines changed

packages/core/src/entities/TargetZoneCore.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,19 @@ export class TargetZoneCore
131131
public handleSignal(signal: InputActionSignal): void {
132132
const { type, payload } = signal;
133133

134-
// 每一条信号触发前,先确保焦点回归游戏区域 / Ensure focus is reclaimed before processing any signal
135-
this.ensureFocus();
134+
// 只有离散的意图性动作才触发回焦检查,确保焦点回归游戏区域:
135+
// 键盘按键、鼠标按下、或者是第一次移动时
136+
// Only discrete, intentional actions trigger a focus check to ensure the focus returns to the game area:
137+
// keyboard presses, mouse clicks, or the first movement.
138+
const isIntentionalAction =
139+
type === ACTION_TYPES.KEYDOWN ||
140+
type === ACTION_TYPES.MOUSEDOWN ||
141+
type === ACTION_TYPES.CLICK ||
142+
(type === ACTION_TYPES.MOUSEMOVE && !this.state.isPointerDown && !this.state.isVisible);
143+
144+
if (isIntentionalAction) {
145+
this.ensureFocus();
146+
}
136147

137148
// 调度执行不同的输入动作 / Dispatch and execute different input actions
138149
switch (type) {

packages/web/src/dom/action.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ export const reclaimFocusAtPos = (x: number, y: number, callback?: () => void):
6969
const target = getDeepElement(x, y) as HTMLElement;
7070
if (!target) return;
7171

72+
// If an iframe is found, first send a reclaim request to the iframe
73+
// 如果找到的是 iframe,先往 iframe 发送回焦请求
74+
if (target.tagName.toLowerCase() === 'iframe') {
75+
IframeManager.getInstance().forwardFocusReclaim(target as HTMLIFrameElement, x, y);
76+
}
77+
7278
// Identify the current truly active element across all Shadow Roots
7379
// 识别当前页面中真正获得焦点的最深层元素(跨越所有 Shadow Root)
7480
const currentActive = getDeepActiveElement();
@@ -78,10 +84,6 @@ export const reclaimFocusAtPos = (x: number, y: number, callback?: () => void):
7884
if (currentActive !== target) {
7985
focusElement(target);
8086

81-
if (target.tagName.toLowerCase() === 'iframe') {
82-
IframeManager.getInstance().forwardFocusReclaim(target as HTMLIFrameElement, x, y);
83-
}
84-
8587
callback?.();
8688
}
8789
};

0 commit comments

Comments
 (0)