feat: 抬起按键的优先级

This commit is contained in:
unanmed 2026-10-23 00:45:40 +08:00
parent 564f53d82a
commit 3fd339ffcb
2 changed files with 21 additions and 5 deletions

View File

@ -11,8 +11,6 @@ import {
IHotkeySystem
} from './type';
// TODO: 优先级阻断
interface IHotkeyScope {
/** 作用域唯一标识符 */
readonly symbol: symbol;
@ -346,13 +344,15 @@ export class HotkeySystem implements IHotkeySystem, IExcitable<number> {
const index = this.holding.indexOf(key);
this.holding.splice(index, 1);
const toEmit: IHotkeyCommandPending[] = [];
// 需要快照
for (const [command, pending] of new Map(this.holdingCmds)) {
// 对于 KeyUp,如果有可以触发的,那么按规则触发
if (command.mode === HotkeyEmitMode.KeyUp) {
const emit = this.matchKeyUp(pending.keys, key);
if (emit) {
this.emit(pending);
toEmit.push(pending);
this.holdingCmds.delete(command);
}
} else {
@ -380,6 +380,22 @@ export class HotkeySystem implements IHotkeySystem, IExcitable<number> {
}
}
// 抬起事件要看优先级
toEmit.sort((a, b) => b.command.priority - a.command.priority);
let blocking = -Infinity;
for (const pending of toEmit) {
if (pending.command.priority < blocking) break;
if (pending.command.block) {
blocking = pending.command.priority;
}
if (pending.command.timeout === 0) {
this.emit(pending);
} else {
this.waitTimeout.add(pending);
}
}
// 如果有按键可能触发,那么返回 true 来 preventDefault
return this.holdingCmds.size > 0 || this.waitTimeout.size > 0;
}

View File

@ -53,7 +53,7 @@ export interface IHotkeyEmitInfo {
}
export interface IHotkeyCommandInit {
/** 按键指令优先级 */
/** 按键指令优先级,目前仅对抬起触发的按键生效 */
readonly priority: number;
/** 默认按键组合,可设置多组 */
readonly defaults: KeyCode[][];
@ -72,7 +72,7 @@ export interface IHotkeyCommandInit {
export interface IHotkeyCommand {
/** 按键指令的标识符 */
readonly command: string;
/** 按键指令优先级,越高越先执行,如果同优先级,则无法保证顺序 */
/** 按键指令优先级,越高越先执行,如果同优先级,则无法保证顺序,目前仅对抬起触发的按键生效 */
readonly priority: number;
/** 触发后,是否阻断优先级比当前优先级更低的按键的触发 */
readonly block: boolean;