# IME input may break when cursor is adjacent to widget due to cm-widgetBuffer reconstruction

**URL:** https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799
**Category:** v6
**Created:** [June 12, 2026, 9:13am UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799 "2026-06-12T09:13:53Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![somebody](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/somebody/32/5079_2.png) [@somebody](https://discuss.codemirror.net/u/somebody)
#### Post date: [June 12, 2026, 9:13am UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/1 "2026-06-12T09:13:53Z")

</div>

### Description

In Safari, when the cursor is positioned on either side of a widget, IME input may behave unexpectedly.

Even when the widget itself does not change, an IME composition can trigger reconstruction of `cm-widgetBuffer` nodes. This causes the DOM structure around the composition range to change during input, which may lead to abnormal IME behavior.

For example, given the following DOM layout:

```auto
| .cm-widgetBuffer | input | widget | .cm-widgetBuffer |

```

Although the widget content remains unchanged, this unnecessary reconstruction modifies the DOM during composition and can interrupt or corrupt IME input.

### Environment

- Browser: Safari 26.5 (20624.2.5.18.3)

- OS: macOS 15.7.7

### [Demo](https://codemirror.net/try/#c=aW1wb3J0IHsgYmFzaWNTZXR1cCwgRWRpdG9yVmlldyB9IGZyb20gImNvZGVtaXJyb3IiOwppbXBvcnQgeyBWaWV3UGx1Z2luLCBEZWNvcmF0aW9uIH0gZnJvbSAiQGNvZGVtaXJyb3IvdmlldyI7CmltcG9ydCB7IFJhbmdlU2V0IH0gZnJvbSAiQGNvZGVtaXJyb3Ivc3RhdGUiOwppbXBvcnQgeyBtYXJrZG93biB9IGZyb20gIkBjb2RlbWlycm9yL2xhbmctbWFya2Rvd24iOwppbXBvcnQgeyBsYW5ndWFnZXMgfSBmcm9tICJAY29kZW1pcnJvci9sYW5ndWFnZS1kYXRhIjsKCi8vIFRoZSBNYXJrZG93biBwYXJzZXIgd2lsbCBkeW5hbWljYWxseSBsb2FkIHBhcnNlcnMKLy8gZm9yIGNvZGUgYmxvY2tzLCB1c2luZyBAY29kZW1pcnJvci9sYW5ndWFnZS1kYXRhIHRvCi8vIGxvb2sgdXAgdGhlIGFwcHJvcHJpYXRlIGR5bmFtaWMgaW1wb3J0LgpuZXcgRWRpdG9yVmlldyh7CiAgZG9jOiAiSGVsbG8gV29ybGQiLAogIGV4dGVuc2lvbnM6IFsKICAgIGJhc2ljU2V0dXAsCiAgICBtYXJrZG93bih7IGNvZGVMYW5ndWFnZXM6IGxhbmd1YWdlcyB9KSwKICAgIFZpZXdQbHVnaW4uZnJvbUNsYXNzKGNsYXNzIHt9LCB7CiAgICAgIHByb3ZpZGU6ICgpID0+CiAgICAgICAgRWRpdG9yVmlldy5kZWNvcmF0aW9ucy5vZigodmlldykgPT4gewogICAgICAgICAgY29uc3QgbGluZSA9IHZpZXcuc3RhdGUuZG9jLmxpbmVBdCgwKTsKICAgICAgICAgIGNvbnN0IHJhbmdlcyA9IFtdOwogICAgICAgICAgaWYgKGxpbmUudGV4dC5sZW5ndGggPiA1KSB7CiAgICAgICAgICAgIHJhbmdlcy5wdXNoKAogICAgICAgICAgICAgIERlY29yYXRpb24ucmVwbGFjZSh7fSkucmFuZ2UobGluZS5mcm9tICsgMSwgbGluZS5mcm9tICsgMiksCiAgICAgICAgICAgICk7CiAgICAgICAgICB9CgogICAgICAgICAgcmV0dXJuIFJhbmdlU2V0Lm9mKHJhbmdlcywgdHJ1ZSk7CiAgICAgICAgfSksCiAgICB9KSwKICBdLAogIHBhcmVudDogZG9jdW1lbnQuYm9keSwKfSk7Cgpjb25zdCBvYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnMpID0+IHsKICBmb3IgKGNvbnN0IG11dGF0aW9uIG9mIG11dGF0aW9ucykgewogICAgbXV0YXRpb24uYWRkZWROb2Rlcy5mb3JFYWNoKChub2RlKSA9PiB7CiAgICAgIGNvbnNvbGUubG9nKCdbQUREXScsIG5vZGUpOwogICAgfSk7CiAgICBtdXRhdGlvbi5yZW1vdmVkTm9kZXMuZm9yRWFjaCgobm9kZSkgPT4gewogICAgICBjb25zb2xlLmxvZygnW1JFTU9WRV0nLCBub2RlKTsKICAgIH0pOwogIH0KfSk7CgpvYnNlcnZlci5vYnNlcnZlKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jbS1jb250ZW50JyksIHsKICBjaGlsZExpc3Q6IHRydWUsCiAgc3VidHJlZTogdHJ1ZQp9KTsK)

 ![screenshot 2026-06-12 17.12.15](https://discuss.codemirror.net/uploads/default/original/2X/4/46f4301f9f27aa0bfc85d93737b4134f9054aa3c.png)

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/marijn/32/136_2.png) [@marijn](https://discuss.codemirror.net/u/marijn)
#### Post date: [June 12, 2026, 9:54am UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/2 "2026-06-12T09:54:47Z")

</div>

This sounds a lot like [this issue](https://discuss.codemirror.net/t/bug-ime-selection-is-not-updated-when-decoration-mark-contains-multiple-decoration-replace-decorations/9785). Can you still reproduce this with @codemirror/view 6.43.1?

---

<div class="post-metadata">

### Author: ![somebody](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/somebody/32/5079_2.png) [@somebody](https://discuss.codemirror.net/u/somebody)
#### Post date: [June 12, 2026, 11:00am UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/3 "2026-06-12T11:00:38Z")

</div>

Yes, this issue is reproducible on `@codemirror/view@6.43.1`.

It seems related to `CompositeTile.sync`, where the ordering of `tile.children` becomes inconsistent with the actual DOM order.

In the case of:

```auto
| .cm-widgetBuffer | input | widget | .cm-widgetBuffer |

```

`tile.children` is iterated as:

```auto
TextTile → WidgetBufferTile → WidgetTile → WidgetBufferTile

```

but the DOM order is:

```auto
.cm-widgetBuffer → text → widget → .cm-widgetBuffer

```

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/marijn/32/136_2.png) [@marijn](https://discuss.codemirror.net/u/marijn)
#### Post date: [June 22, 2026, 3:31pm UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/4 "2026-06-22T15:31:33Z")

</div>

What your demo is doing is always collapsing the second character of the document. And the screenshot suggests you’re seeing the issue when starting a composition after the first character of the document. Which will then immediately be hidden. That this disrupts the composition seems rather obvious. Am I missing something?

---

<div class="post-metadata">

### Author: ![somebody](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/somebody/32/5079_2.png) [@somebody](https://discuss.codemirror.net/u/somebody)
#### Post date: [June 25, 2026, 3:07pm UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/5 "2026-06-25T15:07:54Z")

</div>

Demo has some issues. The point I wanted to demonstrate is that, during `view.composing`, a DOM update can still be triggered even when the only operation performed is `decorationSet.map(update.changes)`, without any decoration recomputation or recreation.

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.codemirror.net/user_avatar/discuss.codemirror.net/marijn/32/136_2.png) [@marijn](https://discuss.codemirror.net/u/marijn)
#### Post date: [July 2, 2026, 2:19pm UTC](https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799/6 "2026-07-02T14:19:26Z")

</div>

Looking into this, I found two misbehaviors that may be related to what you’re seeing. But since you didn’t provide a clear reproduction, I am not sure whether the patches below help.

> **[Change the order in which tiles are returned from the reuse cache · cb3e24cd46](https://code.haverbeke.berlin/codemirror/view/commit/cb3e24cd462c94a65271c1aee7668a857c31eddc)**
>
> To avoid flipping tiles around, causing needless DOM changes.

> **[Fix a bug in resolveInline that would return a pos after a side=1 widget...](https://code.haverbeke.berlin/codemirror/view/commit/0e9ae97e502933f1b2ce8d2182c1b94039205f8f)**
>
> FIX: Fix an issue that could cause the DOM cursor to be drawn on the wrong side of
> a collapsing decoration.
> 
> See https://discuss.codemirror.net/t/ime-input-may-break-when-cursor-is-adjacent-to-widget-due-to-cm-widgetbuffer-reconstruction/9799
