Commit Graph
8 Commits
Author SHA1 Message Date
fanlusky b3b3b3303c feat(windows): 焦点切换到另一个输入框时提示当前中英文状态
新增开关 general.caret_state_indicator_on_focus(默认关闭,需同时开启光标
状态提示)。

- DLL 把以下情况视为“换了输入框”:焦点窗口变化(Win32 编辑框、对话框、
  其他应用各有自己的窗口);焦点经过一段没有可编辑文档的间隙后落到可
  编辑文档上(Chromium、WPF 等单窗口宿主在字段之间就是先失焦再聚焦);
  焦点会话真正结束后重新开始。Chromium 打字时在两个可编辑文档之间直接
  替换文档管理器,不会触发。从 Win+. 面板返回不计入;线程焦点在真正的
  应用切换后返回计入。一次切换的多次回调由定时器合并为一次提示;组字
  过程中、以及没有光标的控件都保持静默。每次判断在 TSF 诊断日志里记录
  判定标志,不含任何文本
- 协议复用 IMESwitch:wch 改为 FanyImeCaretStateTrigger(UserToggle /
  CapsLockEdge / FocusEntered),CapsLockEdge 保持首发时的 VK_CAPITAL
  取值,Server 对未知值按 UserToggle 处理
- Server 在开关打开时显示当前的有效模式(Caps Lock 开启时为“英”);
  配置项同步写入两份模板和两个设置窗口宿主的读写映射
- 设置页在光标状态提示卡片中增加“切换输入框时提示”开关
2026-09-26 17:09:34 +08:00
fanlusky 597d087580 fix(server): 光标状态提示仅由用户快捷键触发并收紧协议边界
- DLL 只在 Shift/Ctrl 切换、Shift+Space、Ctrl+.、Caps Lock 与
  Ctrl+Shift+F 处显式请求提示;Server 下发的模式同步、宿主转换模式
  同步和激活初始化不再弹出提示,移除 compartment 回调里的推断逻辑
- 恢复文档切换时候选窗的 OnKillThreadFocus,改用 COM 身份比较
- 能力位改名为 CaretStateIndicator,DLL 仅在 Server 确认后发送切换
  事件;Server 端这些事件只驱动提示,不再改写工具栏或状态快照
- 标点提示的中英模式由 DLL 随 PuncSwitch 携带
- UILess 宿主不显示提示,会话转为 UILess 时隐藏已显示的提示
- Ctrl+Shift+F 的锚点就地读取,不再覆盖 Global::Point,且只采信
  协商了该能力的客户端
- 撤回对所有包默认 point 的修改;提示窗口创建失败不再阻断 Server
  启动;提示内容改为结构化 CaretStateBadge
- Caps Lock 在同一按键重复进入 TestKeyDown 时只处理一次
2026-09-26 13:58:22 +08:00
AaGMix a855a9c7f4 feat(windows): 发送光标状态切换事件 2026-09-22 21:20:07 +08:00
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
Jia Sui d4a0796400 feat(windows): 重构智能标点
原「智能标点」是小狼毫 digit_separators 的语义:字母或数字后的 , . : 直出英文,
2 秒内再按同一标点转回中文——后半段靠 SendInput 往应用里补一个 Backspace 再打
字符,落点全靠光标当时在哪。这次换掉主路径:输入中文标点后按空格,用 TSF 编辑
会话就地把它改写成对应英文(。,!?;:、 → . , ! ? ; : /),2 秒内再按同一标点
键撤回中文;原来的直出降为子开关,整个家族默认全关、改为显式开启。

- 按键与会话:转换/撤回是本地文档改写,不进 IPC、不进延迟队列;判据落在
  _IsKeyEaten,OnTestKeyDown 的预判与 _DispatchKeyDown 的第二遍预判共用同一份,
  声称吃掉的键不交还宿主。改写走编辑会话,请求不上时另起一个最小会话把键本身
  的字符写回去,避免已吃掉的键静默丢失。
- 状态:原来散落的九个成员收成一个 SmartPunctuationAction(None / ChineseCommitted
  / AsciiConverted),带焦点令牌、前台窗口和 beforeChar 指纹;清理以分类结果为准,
  丢焦点与上下文栈变化一并清掉。
- 转换范围:。,!?;:、 与单独出现的 “”‘’【】《》() 都是映射表里的单字符
  条目,路径完全一致;成对补全产生的一对(autoClosedPair)不 arm,按空格只落空格,
  不会留下 <》 这类孤儿。
- 开关:总开关 + 中文标点后按空格转换 + 同键转回中文 + 数字后直出 + 字母后直出,
  五键全部默认关;直出拆成数字/字母两个独立子开关(IPC 24 收窄为数字、25 追加为
  字母),TSF 按前字符类型分别查键。
- 命名:子开关「独立符号」改名「中文标点后按空格转换」,配置键
  smart_punctuation_standalone → smart_punctuation_space_convert,IPC 22 只改常量名
  (SmartPunctuationSpaceConvertChanged),编号与语义不变、新旧测试包互通;设置页
  文案同步重写,五处配置链路与死宿主一并跟改。
- 兼容:旧键未出厂、不迁移(升级合并按模板缺键丢弃、取默认 false);编号 23 随
  「按空格整体转换一对」的设计退役并留空不复用。
- 验证:TSF x86/x64 与 Server Release 编译、Server 335 单测、windows_ipc_contract
  x64/x86、设置页 build + 27 测试、clang-format 18.1.8 全绿。真机未跑。

Signed-off-by: Jia Sui <jsfaint@gmail.com>
2026-09-17 09:29:57 +08:00
fanlusky 0febd575ac refactor(windows): clear the TSF /W4 warnings
The bulk of them were left behind when the keystroke latency logging was
removed: PerfTimer objects and *ElapsedMs doubles that nothing reads any more
(C4189). Dropping them also takes the QueryPerformanceCounter calls back out of
the keystroke path. The timers that still feed DebugTsfKeyLatency (Ipc.cpp,
KeyEventSink.cpp, KeyHandlerEditSession.cpp) are untouched.

The rest, all behaviour-preserving:

- C4463: the four CompositionProcessorEngine configuration flags were one-bit
  BOOL fields, so every `= TRUE` stored -1. They are plain BOOLs now.
- C4456: renamed the shadowing inner locals (pLI -> pItem, focusToken ->
  expectedFocusToken).
- C4100: commented out the parameter names that are part of a TSF interface but
  unused in the implementation.
- C4702: dropped the unreachable `return 0;` after FreeLibraryAndExitThread,
  which is __declspec(noreturn).
- C4102: removed the two vestigial NoPresenter labels and the empty branches
  that used to jump to them.
- C4267/C4244: made the narrowing conversions in the pipe write and the offline
  key handler explicit.
- C4996: SharedConfigPath now uses GetEnvironmentVariableW instead of the
  deprecated _wgetenv.

x64 and x86 Release both build clean; ctest passes in both.
2026-09-12 00:55:56 +08:00
Evan 42238a2af6 style: 用 .clang-format 重排 server / windows / ui / log
一次性重排,无任何行为改动。四个目录各自的 .clang-format 放在仓库里已久,但全组织只有
MSIME-Linux 在 CI 里执行 clang-format 检查,这边 149 个文件里有 149 个不符合自己声明的风格。

已逐文件核对语义等价:去掉空白、注释与相邻字符串字面量拆分之后,全部 149 个文件与重排前逐字节
相同。差异只有三类——缩进与换行、clang-format 补的 } // namespace 结尾注释、以及长字符串被拆成
相邻字面量(C++ 保证自动拼接)。

这个提交会写进 .git-blame-ignore-revs。
2026-09-06 12:13:47 +09:00
Evan Hu 253b068984 refactor: move the Windows TSF frontend under windows/
Preparation for folding Server, UI, UiHtml, Installer, ImeLog and TsfEditControl into this repository. The Windows tip's own sources, build files and local build scripts move under windows/ so every component sits at the same level. Product-level files stay at the root: the lock, the release manifest, the shared CI scripts, the integration tests, the docs and the Engine submodule.
2026-09-06 02:24:27 +09:00