Files
msime-windows/windows/tests/key_repeat_guard.cpp
T
Jia Sui 62c9f5cf6b fix(windows): Backspace 清空预编辑后长按不外溢(#347)
从组词里起手的那一次 Backspace 按住,一旦 composition 被删空,
同一次按住的后续 auto-repeat 一并吞掉;松开后重新按下才恢复退格。

- 新增 KeyRepeatGuard 纯谓词(repeat 位判定,不依赖 keyup、不用计时器)+ x64/x86 单测
- OnTestKeyDown / _DispatchKeyDown / _ClassifyDeferredKeyDown 三处同判据:
  吞键不发 IPC、不请求编辑会话,命中的排队键完成 replay token
- 延迟投影把 inputLength 打到 0 时置位,慢 Server 下重放不会漏到宿主
- 焦点/上下文清理路径复位(OnSetFocus、_ClearDeferredKeyDowns、
  ThreadFocusSink::OnKillThreadFocus),不在 Chromium 文档切换路径误复位

Refs #347
2026-09-17 21:02:07 +08:00

53 lines
1.8 KiB
C++

#include "Key/KeyRepeatGuard.h"
int main()
{
// Do not use assert: Release builds must execute these checks too.
// Only bit 30 marks a repeat. Bit 31 (up/context) and the scan-code bits
// must not leak into the decision.
if (IsAutoRepeat(0))
return 1;
if (!IsAutoRepeat(static_cast<LPARAM>(0x40000000u)))
return 2;
if (IsAutoRepeat(static_cast<LPARAM>(0x80000000u)))
return 3;
if (!IsAutoRepeat(static_cast<LPARAM>(0x40000000u | 0x80000000u)))
return 4;
if (IsAutoRepeat(static_cast<LPARAM>(0x001d0001u)))
return 5;
if (!IsAutoRepeat(static_cast<LPARAM>(0x001d0001u | 0x40000000u)))
return 6;
// Exhaustive armed x compositionActive x repeat matrix.
for (int mask = 0; mask < 8; ++mask)
{
const bool armed = (mask & 1) != 0;
const bool compositionActive = (mask & 2) != 0;
const bool repeat = (mask & 4) != 0;
const bool expected = armed && repeat && !compositionActive;
if (ShouldSuppressBackspaceRepeat(armed, compositionActive, repeat) != expected)
{
return 10 + mask;
}
}
// A fresh press (no repeat bit) is never swallowed, armed or not: the new
// hold re-evaluates the guard and restores ordinary Backspace.
if (ShouldSuppressBackspaceRepeat(true, false, false))
return 20;
if (ShouldSuppressBackspaceRepeat(true, true, false))
return 21;
// A hold that never touched a composition is not guarded even when the
// composition disappeared for another reason.
if (ShouldSuppressBackspaceRepeat(false, false, true))
return 22;
// While the composition is still alive the repeat belongs to it.
if (ShouldSuppressBackspaceRepeat(true, true, true))
return 23;
return 0;
}