Skip to content

fix(ui): 首次显示候选窗时等待光标位置就绪,避免先画在旧位置 - #1967

Draft
doublemarkpro wants to merge 1 commit into
rime:masterfrom
doublemarkpro:fix/defer-candidate-show
Draft

doublemarkpro wants to merge 1 commit into
rime:masterfrom
doublemarkpro:fix/defer-candidate-show

Conversation

@doublemarkpro

Copy link
Copy Markdown

问题

Electron / Chromium 宿主里,聚焦输入框后第一次输入时,候选窗会先在上一段输入的位置显示一帧,再跳到光标处(#1966)。UI throttle 修复(#1869)降低了概率,但没有消除。

原因

TSF 侧的光标矩形是异步取回的:

  • WeaselTSF/Composition.cpp 的 CGetTextExtentEditSession::DoEditSession:GetTextExt 成功后才 _SetCompositionPosition(rc)
  • WeaselTSF::_UpdateCompositionWindow 用 RequestEditSession(..., TF_ES_ASYNCDONTCARE | TF_ES_READ, ...),结果要等下一个 UI tick

而 CCandidateList::Show(TRUE) → UI::Show() 在同一次按键处理里就执行了,此时 WeaselPanel::m_inputPos 还是上一段 composition 的值,于是首帧画在旧位置。

改动

  • UIImpl 增加 has_position:记录本次输入是否已收到有效光标位置
  • Show() 在位置未就绪时只置 pending_show,不再立即 ShowWindow
  • UI::UpdateInputPosition() 到达后补上显示
  • WeaselPanel::ShowDeferred(80ms) 作为兜底:始终拿不到光标矩形的宿主仍然会显示
  • Hide() / 正常 ShowWindow(SW_SHOWNA) 时清理挂起状态与定时器

改动共 3 个文件、+45 行。

说明

  • 这个补丁没有在本地编译验证(本机缺 v142/v143 工具链),麻烦 CI 跑一下;需要的话我可以按 review 意见调整
  • 行为变化:首帧不再绘制,等位置到达(通常同一帧或下一帧)再显示;极端情况(宿主不提供 rect)80ms 后照常显示
  • 如果方向可以,我可以再加一个 debug 日志点,方便在真实宿主里验证时序

关联:#1966,#1869

TSF 侧的光标矩形是异步取回的(WeaselTSF/Composition.cpp 的
RequestEditSession(TF_ES_ASYNCDONTCARE)),而候选窗的 Show 在同一次
按键处理里就发生了,导致首帧按上一段输入的位置绘制,随后再跳到光标。

- UIImpl 记录本次输入是否已收到有效位置;未收到时 Show() 先挂起
- UI::UpdateInputPosition 到达后补上显示
- WeaselPanel::ShowDeferred 提供 80ms 兜底,避免拿不到 rect 的宿主不显示

关联 rime#1966
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant