Skip to content

[Problem/Bug]: IME composition window jumps to the top-left of the screen after the host window is resized #5675

Description

What happened?

What happened?

Resize the host window, then start typing with a Korean IME. The in-progress composition is drawn in
a floating window at the top-left corner of the screen instead of at the caret. The committed text
still goes into the input correctly, it's only the composition that's displaced.

It doesn't sort itself out. It stays wrong until you move the window with the mouse, or click away to
another window and come back. Then the next resize does it again.

The input is a plain <input>. No canvas editor, no EditContext, nothing custom.

Edge and Chrome don't do this. Only WebView2.


Things I checked that turned out not to be it

Posting these so nobody has to redo them:

  • The child windows keeping up with the parent. Chrome_RenderWidgetHostHWND picks up the new
    geometry 28ms after the parent resize. (Intermediate D3D Window takes ~1.2s, but that one has no
    caret in it.)
  • My app blocking the main thread and delaying a caret update. Longest frame gap over the two
    seconds after a resize was 0ms.
  • The page-side caret being in the wrong place. I logged the focused element's rect across resizes,
    it tracks the caret and stays inside the window every time.
  • MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC) after the resize. No effect.
  • NotifyParentWindowPositionChanged() after the resize. I called it ten times spread over
    0-1100ms so the timing couldn't be the reason it missed. Still no effect.

It isn't specific to one UI framework either. The stock Tauri repro above keeps the default window
decorations, and #2241 reports the same thing from WinUI3. And since the browser doesn't do it but
WebView2 does, my guess is it sits in the hosting layer rather than the Chromium IME code they share.
I can't see inside the runtime to confirm that though.

If it helps as a starting point: in Chromium the caret position reaches TSF through
InputMethodWinTSF::OnCaretBoundsChanged -> TSFBridge::OnTextLayoutChanged ->
TSFTextStore::SendOnLayoutChange -> ITextStoreACPSink::OnLayoutChange. If that doesn't fire after
a host resize, GetTextExt would go on returning a stale rect or TS_E_NOLAYOUT, and a floating
composition window at the screen origin is what you'd expect to see. That's a guess, I haven't been
able to verify it.

Related

Checked the open bug list first. Closest ones, and why I filed separately:

If you think these are all one defect, feel free to fold this in. The repro and the checks above
should still be useful.

Importance

Moderate. My app's user experience is affected, but still usable.

Runtime Channel

Stable release (WebView2 Runtime)

Runtime Version

151.0.4129.86

SDK Version

webview2-com 0.38.2 (Rust bindings via Tauri 2.11.5 / wry 0.55.1)

Framework

Win32

Operating System

Windows 11

OS Version

10.0.26200

Repro steps

I hit this in my own app but it reproduces in a stock Tauri project, so there's no custom code involved:

pnpm create tauri-app imetest --template vanilla --manager pnpm --yes
cd imetest && pnpm install
pnpm tauri dev

Replace src/index.html with this, that's the whole page:

  <!doctype html>
  <html><head><meta charset="UTF-8" /></head>
  <body style="padding:24px;font-family:system-ui">
	<input style="width:90%;font-size:20px;padding:12px" />
  </body></html>

Steps:

  1. Set the OS input method to a composition IME. I used the Korean Microsoft IME (0412).
  2. Click the input, type a syllable so a composition happens.
  3. Resize the window.
  4. Type again straight away. Don't press anything else first and don't move the mouse.

Expected: the composition appears at the caret.
Actual: it appears at the top-left corner of the screen, outside the window.

Image

One thing worth knowing if you try to reproduce it: moving the mouse or clicking anywhere in the
window clears it. So if you do either between steps 3 and 4 you won't see it, and it looks like it
fixes itself after a moment. It doesn't. Hands off the keyboard and mouse, it stays wrong
indefinitely.

Repros in Edge Browser

No, issue does not reproduce in the corresponding Edge version

Regression

Don't know

Last working version (if regression)

n/a

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions