Skip to content

Finalize stranded composition when input source is switched away programmatically (#1140)#1142

Merged
LEOYoon-Tsaw merged 3 commits into
rime:masterfrom
Bo-Feng-1024:finalize-stranded-composition
Jun 12, 2026
Merged

Finalize stranded composition when input source is switched away programmatically (#1140)#1142
LEOYoon-Tsaw merged 3 commits into
rime:masterfrom
Bo-Feng-1024:finalize-stranded-composition

Conversation

@Bo-Feng-1024

@Bo-Feng-1024 Bo-Feng-1024 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Fixes #1140

TL;DR (EN): On macOS 26, switching the input source away from Squirrel via an out-of-process TISSelectInputSource() never triggers deactivateServer, stranding the pending composition with an orphaned candidate panel. The kTISNotifySelectedKeyboardInputSourceChanged notification is still delivered (verified in #1140), so this PR hooks the existing observer to finalize the composition — commit raw input + hide the panel, exactly what deactivateServer would have done.

实现说明(如 #1140 讨论的方案):

  • SquirrelInputController.finalizeStrandedComposition():仅当 session 确有未上屏编码时动作,动作与 deactivateServer 一致(hidePalettes() + commitComposition,即原始编码上屏);
  • SquirrelApplicationDelegate 复用 addObservers()已有的 kTISNotifySelectedKeyboardInputSourceChanged observer,多调一行:当前选中源已非鼠须管时,让 panel.inputControllershowPanel 时即指向正在 composing 的 controller)收口;
  • 正常路径(菜单栏切换,deactivateServer 已触发)下 composition 已空,整个调用是 no-op,不改变现有行为。

验证计划:我手头有 #1140 用的自动化复现 harness(GUI 模拟输入 + CGWindowList 候选框窗口探针 + 程序化/菜单栏双路径对照)。等 CI 出包后我会在 macOS 26.5.1 实机装包跑修复前后对照,把结果贴在这里,然后转出 draft。

…rammatically

macOS 26 does not call deactivateServer when another process switches the
input source via TISSelectInputSource() (as macism, Input Source Pro and
im-select-style vim tools do): the pending composition is stranded and the
candidate panel is left orphaned on screen, while subsequent keystrokes
already go to the new input source. Switching via the menu bar Input menu
still works correctly.

The input-source-changed distributed notification is still delivered on
that path, so hook the existing kTISNotifySelectedKeyboardInputSourceChanged
observer: when the selected source is no longer Squirrel and a composition
is pending, commit the raw input and hide the panel, exactly as
deactivateServer would have. When deactivateServer did run (menu bar
switching), the composition is already empty and this is a no-op.

Fixes rime#1140

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
func finalizeStrandedComposition() {
let id = SquirrelInstaller.currentInputSourceID() ?? ""
guard !id.hasPrefix("im.rime.inputmethod.Squirrel") else { return }
panel?.inputController?.finalizeStrandedComposition()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可调用 deactivateServer

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我給改了

@LEOYoon-Tsaw LEOYoon-Tsaw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to use deactivateServer instead

func finalizeStrandedComposition() {
let id = SquirrelInstaller.currentInputSourceID() ?? ""
guard !id.hasPrefix("im.rime.inputmethod.Squirrel") else { return }
panel?.inputController?.finalizeStrandedComposition()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我給改了

@LEOYoon-Tsaw LEOYoon-Tsaw marked this pull request as ready for review June 12, 2026 14:40

@lotem lotem left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LEOYoon-Tsaw LEOYoon-Tsaw merged commit 52d3bc3 into rime:master Jun 12, 2026
1 check passed
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.

[Bug] macOS 26 Tahoe:程序化切换输入源(TISSelectInputSource)不触发 deactivateServer,候选框残留、composition 不上屏

3 participants