The Wayback Machine - https://web.archive.org/web/20260511184701/https://github.com/microsoft/terminal/pull/19738
Skip to content

Remove TF_TMAE_UIELEMENTENABLEDONLY#19738

Merged
DHowett merged 1 commit into
mainfrom
dev/lhecker/19670-ime
Jan 13, 2026
Merged

Remove TF_TMAE_UIELEMENTENABLEDONLY#19738
DHowett merged 1 commit into
mainfrom
dev/lhecker/19670-ime

Conversation

@lhecker
Copy link
Copy Markdown
Member

@lhecker lhecker commented Jan 13, 2026

Closes #19670
Closes #19722

@DHowett DHowett merged commit 58f1f3b into main Jan 13, 2026
20 checks passed
@DHowett DHowett moved this from To Cherry Pick to Cherry Picked in 1.23 Servicing Pipeline Jan 13, 2026
DHowett pushed a commit that referenced this pull request Jan 13, 2026
Closes #19670
Closes #19722

(cherry picked from commit 58f1f3b)
Service-Card-Id: PVTI_lADOAF3p4s4Axadtzgjnf9k
Service-Version: 1.23
@DHowett DHowett moved this from To Cherry Pick to Cherry Picked in 1.24 Servicing Pipeline Jan 13, 2026
DHowett pushed a commit that referenced this pull request Jan 13, 2026
Closes #19670
Closes #19722

(cherry picked from commit 58f1f3b)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgjnf9Y
Service-Version: 1.24
@DHowett DHowett deleted the dev/lhecker/19670-ime branch January 15, 2026 17:10
@DHowett DHowett moved this from Cherry Picked to Shipped in 1.24 Servicing Pipeline Feb 27, 2026
drvoss added a commit to drvoss/terminal that referenced this pull request Mar 30, 2026
…cursor

When composing a new character between two existing characters, the in-progress
composition text was drawn over the character immediately to the right of the
cursor, visually hiding it during composition. This happened because the
tsfPreview overlay used an overwrite-style render, writing the composition text
at the cursor column without preserving the displaced content.

The fix copies the original characters from that position back into the visual
row at the position just after the composition text ends, changing the
appearance from overwrite to insert. The buffer itself is not modified; the
change is local to the temporary row modification that is restored after each
paint frame.

This regression was introduced by commit a3d508a (Remove
TF_TMAE_UIELEMENTENABLEDONLY, microsoft#19738), which caused the Korean IME to switch
from IMM32 (which renders its own floating composition window) to TSF (which
uses the terminal's inline tsfPreview rendering), exposing this rendering flaw.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
drvoss added a commit to drvoss/terminal that referenced this pull request Mar 30, 2026
When an arrow key was pressed during an active Korean IME composition,
_KeyHandler forwarded the key to the PTY immediately via _TrySendKeyEvent,
moving the cursor before the async TSF edit session had a chance to commit
the finalized text. The committed character then landed at the wrong position.

The fix mirrors the existing behavior in the conhost v1 key handler
(src/interactivity/win32/windowio.cpp): suppress all key events from being
forwarded to the PTY while TSF has an active composition. The IME re-injects
navigation and confirmation keys after the composition ends, at which point
HasActiveComposition() returns false and they are forwarded normally.

This regression was introduced by commit a3d508a (Remove
TF_TMAE_UIELEMENTENABLEDONLY, microsoft#19738), which caused the Korean IME to
activate through the TSF path for the first time, exposing the missing guard.
drvoss added a commit to drvoss/terminal that referenced this pull request Mar 30, 2026
…cursor

When composing a new character between two existing characters, the in-progress
composition text was drawn over the character immediately to the right of the
cursor, visually hiding it during composition. This happened because the
tsfPreview overlay used an overwrite-style render, writing the composition text
at the cursor column without preserving the displaced content.

The fix copies the original characters from that position back into the visual
row at the position just after the composition text ends, changing the
appearance from overwrite to insert. The buffer itself is not modified; the
change is local to the temporary row modification that is restored after each
paint frame.

This regression was introduced by commit a3d508a (Remove
TF_TMAE_UIELEMENTENABLEDONLY, microsoft#19738), which caused the Korean IME to switch
from IMM32 (which renders its own floating composition window) to TSF (which
uses the terminal's inline tsfPreview rendering), exposing this rendering flaw.
drvoss added a commit to drvoss/terminal that referenced this pull request Mar 31, 2026
When an arrow key is pressed during an active Korean IME composition,
_KeyHandler was forwarding the key to the PTY immediately via
_TrySendKeyEvent. This moved the cursor before the async TSF edit
session had a chance to commit the finalized text, causing the
committed character to land at the wrong position.

The fix adds a guard that mirrors the existing behavior in the conhost
v1 key handler (src/interactivity/win32/windowio.cpp lines 361-364):
suppress all key events from being forwarded to the PTY while TSF has
an active composition. The IME re-injects navigation and confirmation
keys after the composition ends, at which point HasActiveComposition()
returns false and they are forwarded normally.

Historical note: this guard was not needed before PR microsoft#17067 (v1.22)
because the old TSF implementation used WinRT CoreTextServices via
XAML (TSFInputControl.xaml/.cpp). In that model the XAML framework
handled composition key events before they reached _KeyHandler, so
_KeyHandler never received them during composition. The new custom
Win32 TSF context introduced in microsoft#17067 no longer intercepts keys at
the XAML level, making _KeyHandler responsible for this check.

The bug was not visible in v1.22-v1.23 for Korean because the Korean
IME was excluded from the TSF path by TF_TMAE_UIELEMENTENABLEDONLY.
It became visible in v1.24 when PR microsoft#19738 removed that flag, causing
the Korean IME to activate through TSF for the first time.

Closes microsoft#20038
DHowett pushed a commit that referenced this pull request Mar 31, 2026
Fix a regression introduced in v1.24 where pressing an arrow key during
Korean IME composition caused the committed character to be inserted at
the wrong cursor position.

Before #19738, the Korean IME activated through IMM32 (excluded from TSF
by `TF_TMAE_UIELEMENTENABLEDONLY`) and was not affected by
`TermControl::_KeyHandler` forwarding keys to the PTY during
composition. After #19738, the Korean IME activates through TSF, making
a missing composition guard in `_KeyHandler` visible as a bug.

The sequence of events that causes the bug:

1. User presses Left arrow during active Korean IME composition (e.g.
composing `가`).
2. `_KeyHandler` calls `_TrySendKeyEvent(VK_LEFT)` which enqueues
`\x1b[D` to the PTY input queue. The cursor moves.
3. TSF processes the key. The Korean IME sees the arrow and ends the
composition.
4. `OnEndComposition` schedules `_doCompositionUpdate` with
`TF_ES_ASYNC`.
5. The async session fires, reads finalized text `가`, calls
`HandleOutput("가")`.
6. PTY processes `[\x1b[D, "가"]`: cursor moves left first, then `가` is
inserted at the wrong (already-moved) position.

The fix adds a guard before `_TrySendKeyEvent`, which mirrors the
existing behavior in conhost (windowio.cpp). When TSF has an active
composition, key events are not converted into input. The Korean IME
re-injects navigation and confirmation keys after the composition ends,
at which point `HasActiveComposition()` returns false and they are
forwarded normally.

**Historical note:** This guard was not needed before PR #17067 (v1.22)
because the old implementation used WinRT `CoreTextServices` via XAML
(`TSFInputControl.xaml`). The XAML framework intercepted composition key
events before `_KeyHandler`. The new custom Win32 TSF context in #17067
no longer does this. The bug was latent from v1.22 but only became
visible for Korean in v1.24 when #19738 removed
`TF_TMAE_UIELEMENTENABLEDONLY`.

## Validation Steps Performed

1. Open Windows Terminal with Korean IME (Dubeolsik layout).
2. Type `rk` to begin composing `가` (composition active, syllable not
yet committed).
3. Press the Left arrow key.
4. Before fix: `가` is inserted one cell to the left of the intended
position.
5. After fix: `가` is inserted at the correct position, then cursor moves
left.

Also verified:
- Normal Korean text input (typing without arrow keys) still works
correctly.
- Arrow key navigation when no composition is active still works
correctly.
- English and other IME input is not affected.

Closes #20038
Refs #19738
DHowett pushed a commit that referenced this pull request Mar 31, 2026
Fix a regression introduced in v1.24 where pressing an arrow key during
Korean IME composition caused the committed character to be inserted at
the wrong cursor position.

Before #19738, the Korean IME activated through IMM32 (excluded from TSF
by `TF_TMAE_UIELEMENTENABLEDONLY`) and was not affected by
`TermControl::_KeyHandler` forwarding keys to the PTY during
composition. After #19738, the Korean IME activates through TSF, making
a missing composition guard in `_KeyHandler` visible as a bug.

The sequence of events that causes the bug:

1. User presses Left arrow during active Korean IME composition (e.g.
composing `가`).
2. `_KeyHandler` calls `_TrySendKeyEvent(VK_LEFT)` which enqueues
`\x1b[D` to the PTY input queue. The cursor moves.
3. TSF processes the key. The Korean IME sees the arrow and ends the
composition.
4. `OnEndComposition` schedules `_doCompositionUpdate` with
`TF_ES_ASYNC`.
5. The async session fires, reads finalized text `가`, calls
`HandleOutput("가")`.
6. PTY processes `[\x1b[D, "가"]`: cursor moves left first, then `가` is
inserted at the wrong (already-moved) position.

The fix adds a guard before `_TrySendKeyEvent`, which mirrors the
existing behavior in conhost (windowio.cpp). When TSF has an active
composition, key events are not converted into input. The Korean IME
re-injects navigation and confirmation keys after the composition ends,
at which point `HasActiveComposition()` returns false and they are
forwarded normally.

**Historical note:** This guard was not needed before PR #17067 (v1.22)
because the old implementation used WinRT `CoreTextServices` via XAML
(`TSFInputControl.xaml`). The XAML framework intercepted composition key
events before `_KeyHandler`. The new custom Win32 TSF context in #17067
no longer does this. The bug was latent from v1.22 but only became
visible for Korean in v1.24 when #19738 removed
`TF_TMAE_UIELEMENTENABLEDONLY`.

## Validation Steps Performed

1. Open Windows Terminal with Korean IME (Dubeolsik layout).
2. Type `rk` to begin composing `가` (composition active, syllable not
yet committed).
3. Press the Left arrow key.
4. Before fix: `가` is inserted one cell to the left of the intended
position.
5. After fix: `가` is inserted at the correct position, then cursor moves
left.

Also verified:
- Normal Korean text input (typing without arrow keys) still works
correctly.
- Arrow key navigation when no composition is active still works
correctly.
- English and other IME input is not affected.

Closes #20038
Refs #19738

(cherry picked from commit 14f4271)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgo0JpM
Service-Version: 1.25
DHowett pushed a commit that referenced this pull request Mar 31, 2026
Fix a regression introduced in v1.24 where pressing an arrow key during
Korean IME composition caused the committed character to be inserted at
the wrong cursor position.

Before #19738, the Korean IME activated through IMM32 (excluded from TSF
by `TF_TMAE_UIELEMENTENABLEDONLY`) and was not affected by
`TermControl::_KeyHandler` forwarding keys to the PTY during
composition. After #19738, the Korean IME activates through TSF, making
a missing composition guard in `_KeyHandler` visible as a bug.

The sequence of events that causes the bug:

1. User presses Left arrow during active Korean IME composition (e.g.
composing `가`).
2. `_KeyHandler` calls `_TrySendKeyEvent(VK_LEFT)` which enqueues
`\x1b[D` to the PTY input queue. The cursor moves.
3. TSF processes the key. The Korean IME sees the arrow and ends the
composition.
4. `OnEndComposition` schedules `_doCompositionUpdate` with
`TF_ES_ASYNC`.
5. The async session fires, reads finalized text `가`, calls
`HandleOutput("가")`.
6. PTY processes `[\x1b[D, "가"]`: cursor moves left first, then `가` is
inserted at the wrong (already-moved) position.

The fix adds a guard before `_TrySendKeyEvent`, which mirrors the
existing behavior in conhost (windowio.cpp). When TSF has an active
composition, key events are not converted into input. The Korean IME
re-injects navigation and confirmation keys after the composition ends,
at which point `HasActiveComposition()` returns false and they are
forwarded normally.

**Historical note:** This guard was not needed before PR #17067 (v1.22)
because the old implementation used WinRT `CoreTextServices` via XAML
(`TSFInputControl.xaml`). The XAML framework intercepted composition key
events before `_KeyHandler`. The new custom Win32 TSF context in #17067
no longer does this. The bug was latent from v1.22 but only became
visible for Korean in v1.24 when #19738 removed
`TF_TMAE_UIELEMENTENABLEDONLY`.

## Validation Steps Performed

1. Open Windows Terminal with Korean IME (Dubeolsik layout).
2. Type `rk` to begin composing `가` (composition active, syllable not
yet committed).
3. Press the Left arrow key.
4. Before fix: `가` is inserted one cell to the left of the intended
position.
5. After fix: `가` is inserted at the correct position, then cursor moves
left.

Also verified:
- Normal Korean text input (typing without arrow keys) still works
correctly.
- Arrow key navigation when no composition is active still works
correctly.
- English and other IME input is not affected.

Closes #20038
Refs #19738

(cherry picked from commit 14f4271)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgo0JpQ
Service-Version: 1.24
DHowett pushed a commit that referenced this pull request Apr 17, 2026
This commit fixes a regression in v1.24, where composing Korean text
in-between existing characters causes text to the right to be hidden.
This is problematic for the Korean IME, because it commonly inserts
the composed syllable between existing characters.

The fix compresses (removes/absorbs) available whitespace to the right
of the composition to make space for any existing text. This means
that a composition now virtually acts in insert mode.

Closes #20040
Refs #19738
Refs #20039

## Validation Steps Performed

1. Korean IME: compose `ㄷ` between `가` and `나` → display shows `가ㄷ나`,
`나` visible.
2. TUI box (vim prompt with padding): compose inside padded text box →
border preserved in place.
3. Composition at end of line (no chars to right): unaffected.
4. English and other IME input: not affected (no active composition
row).

Co-authored-by: jason <drvoss@users.noreply.github.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
DHowett pushed a commit that referenced this pull request Apr 17, 2026
This commit fixes a regression in v1.24, where composing Korean text
in-between existing characters causes text to the right to be hidden.
This is problematic for the Korean IME, because it commonly inserts
the composed syllable between existing characters.

The fix compresses (removes/absorbs) available whitespace to the right
of the composition to make space for any existing text. This means
that a composition now virtually acts in insert mode.

Closes #20040
Refs #19738
Refs #20039

## Validation Steps Performed

1. Korean IME: compose `ㄷ` between `가` and `나` → display shows `가ㄷ나`,
`나` visible.
2. TUI box (vim prompt with padding): compose inside padded text box →
border preserved in place.
3. Composition at end of line (no chars to right): unaffected.
4. English and other IME input: not affected (no active composition
row).

Co-authored-by: jason <drvoss@users.noreply.github.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
(cherry picked from commit 7a83c0f)
Service-Card-Id: PVTI_lADOAF3p4s4BQX0-zgo0JpY
Service-Version: 1.25
DHowett pushed a commit that referenced this pull request Apr 30, 2026
This commit fixes a regression in v1.24, where composing Korean text
in-between existing characters causes text to the right to be hidden.
This is problematic for the Korean IME, because it commonly inserts
the composed syllable between existing characters.

The fix compresses (removes/absorbs) available whitespace to the right
of the composition to make space for any existing text. This means
that a composition now virtually acts in insert mode.

Closes #20040
Refs #19738
Refs #20039

1. Korean IME: compose `ㄷ` between `가` and `나` → display shows `가ㄷ나`,
`나` visible.
2. TUI box (vim prompt with padding): compose inside padded text box →
border preserved in place.
3. Composition at end of line (no chars to right): unaffected.
4. English and other IME input: not affected (no active composition
row).

Co-authored-by: jason <drvoss@users.noreply.github.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
(cherry picked from commit 7a83c0f)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgo0Jpc
Service-Version: 1.24
@lhecker lhecker added Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Attention The core contributors need to come back around and look at this ASAP. labels May 7, 2026
@lhecker lhecker added Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Attention The core contributors need to come back around and look at this ASAP. Needs-Tag-Fix Doesn't match tag requirements labels May 7, 2026
Qmoony pushed a commit to Qmoony/terminal that referenced this pull request May 11, 2026
…osoft#20041)

This commit fixes a regression in v1.24, where composing Korean text
in-between existing characters causes text to the right to be hidden.
This is problematic for the Korean IME, because it commonly inserts
the composed syllable between existing characters.

The fix compresses (removes/absorbs) available whitespace to the right
of the composition to make space for any existing text. This means
that a composition now virtually acts in insert mode.

Closes microsoft#20040
Refs microsoft#19738
Refs microsoft#20039

## Validation Steps Performed

1. Korean IME: compose `ㄷ` between `가` and `나` → display shows `가ㄷ나`,
`나` visible.
2. TUI box (vim prompt with padding): compose inside padded text box →
border preserved in place.
3. Composition at end of line (no chars to right): unaffected.
4. English and other IME input: not affected (no active composition
row).

Co-authored-by: jason <drvoss@users.noreply.github.com>
Co-authored-by: Leonard Hecker <lhecker@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Issue-Bug It either shouldn't be doing this or needs an investigation.

Projects

Status: Cherry Picked

2 participants