Dismiss timing must be consistent, or leftover overlays remain
Aliases: leftover candidate window · overlay not closed · IME ghost window
What it is
The candidate window should vanish as soon as composition ends, focus leaves, or the user cancels. If only some of Esc, outside click, window switch, and successful commit close it, a ghost overlay remains: the word is already in the buffer, the list still sits there, still eating clicks, still covering. Inconsistent dismiss is harder to reproduce than a bad position, because it depends on which exit path was taken.
Why it happens
The candidate window is often a separate top-level window in the IME process, driven by IME messages, not by a page DOM unmount. If the app handles blur without notifying the IME, or the Web compositionend event is incomplete, the window is orphaned. Fullscreen switches, virtual-desktop jumps, and remote-desktop reconnects are boundaries where messages drop. The leftover still hit-tests; a click on “empty space” lands on candidates from hours ago. Unlike covering text under edit, which happens during composition, leftovers happen after.
Studying it
List exit paths: commit, Esc, outside click, Alt-Tab, closing a laptop lid, browser navigation, iframe teardown, and check whether the window remains. Automation can enumerate top-level windows and assert the IME candidate handle is gone after composition. Test cross-process (browser renderer versus IME) separately. Field tickets about “invisible click blockers” should suspect leftovers before mis-computed hit regions.
Where it stops holding
Some IMEs deliberately linger after commit to allow a chained pick; that is a design, but the next keystroke or a timeout must still close it. A soft keyboard that dismisses independently of candidates may drop the keyboard and leave the list. Crash leftovers need an IME watchdog; the app cannot clear them. Assistive tools that inject focus changes may skip compositionend.
Applying it
- Make “close the candidate window” one function used by every exit path: commit, blur, cancel, page unload.
- Listen for compositionend and window deactivation, and force-destroy if still visible after a timeout.
- Do not hide a fake candidate strip in page CSS while leaving the system IME window open—two copies.
- Verify each exit path ten times, enumerate windows to confirm no leftover candidate top-level after composition, then click the old location and confirm the click lands on the app beneath.
Related
- Same group: C6.27.1 Candidate lists usually float near the caret and easily cover the text being edited · C6.27.2 Candidate windows must flip with the caret's distance to the screen edge · C6.27.3 A candidate window that covers controls below the field blocks what comes next
- Adjacent: C6.12 IME candidates · C6.25 IME state and switching
- Search:
IME dismiss·orphan overlay·compositionend