Repository navigation
Description
Windows Terminal version (or Windows build number)
Windows 11
Version: 10.0.22000.258
Windows Terminal Preview
Version: 1.11.2731.0
Other Software
Bash (in WSL)
Steps to reproduce
-
Inside a
xtermterminal, override the terminal's colors using escape sequences such as:# Set "red" color to hex(ab4642) printf '\033]4;%d;rgb:%s\033\\' 1 'ab/46/42'; # Set "background" color to hex(181818) printf '\033]%d;rgb:%s\033\\' 11 '18/18/18';
The full theme I use can be applied using the following script https://github.com/fnune/base16-shell/blob/master/scripts/base16-default-dark.sh. This method allows me to conveniently switch between dark and light themes, regardless of the OS I'm currently using.
-
Assuming you have multiple input methods configured in Windows (e.g. I switch between "US" and "US-International" regularly), press either Ctrl+Shift or Win+Space to switch between input methods.
Switching input from the task bar using the mouse also triggers this bug.
Expected Behavior
Switching input methods in Windows has no impact on the configuration of my open Terminal sessions.
Actual Behavior
The terminal's colors get reset to the color scheme configured in Terminal for the current session.


Activity
zadjii-msft commentedon Oct 18, 2021
Hmm. This is a decent point. We reload the settings when we get a keyboard layout change. This is important for things like the actions, who might need to be re-parsed for different keys in the new layout. But this is something that's totally unrelated that's getting blown away.
I'm running into a similar issue with the work in
ragnarokfor #5000. If you set the colors with VT, then hot-reload the settings, we'll remove the changes to those colors. (same with font size, opacity, anything that can get changed at runtime really). The question is - does a change to the settings override a runtime change by the user? And I think I'm leaning "it probably shouldn't". But then you get into weird things like "should 'preview color scheme' still work on top of the user setting the colors with VT" and then I lean "yes it should"antoineco commentedon Oct 18, 2021
I think it is acceptable to expect the settings to be reloaded when certain things change.
I was just surprised to see something, which seemed unrelated to me, cause a reload in Terminal.
If this is not something that can (or should) be avoided, I'm also fine closing as "works as intended". At least the issue should contain enough keywords for someone to find it if they run into a similar issue.
zadjii-msft commentedon Oct 19, 2021
I think I'm actually gonna leave this open. I think I've got an idea in my notes for now to get this to work. Setting the colors with VT will set a runtime "colors have been overridden" flag, and previewing a scheme will clear that flag out. But a plain-old settings reload, that won't touch that flag, so that'll allow the vt-set colors to persist across hot-reloads of the settings. We might be able to get even more precise and determine that the color scheme for a profile changed, and in that scenario, also clear out the flag.
A bunch of work really, but definitely possible.
j4james commentedon Oct 19, 2021
Can't we just make it so that the settings dialog only updates properties that have actually been edited in some way? So if you change the color scheme for a profile, or edit something on the Color Schemes page, that'll override any colors that have been set programmatically, but if you edit something unrelated (like say the Actions page), then we leave the colors as they are.
This applies to other settings as well. If some application has left the cursor switched to an underscore when your preference is a block, you should be able to go to the Appearance page and reapply your preference by toggling the value or perhaps just clicking Save. It doesn't seem reasonable to me for an application to lock in changes to things like colors and the cursor so your only recourse is to close the tab and start again.
Following the principle of least astonishment:
zadjii-msft commentedon Oct 19, 2021
I would love that. Unfortunately we don't really have the architecture in place at the moment to say "this part of the settings changed" 😞
j4james commentedon Oct 19, 2021
I get that, but I thought what you were proposing was going to take a bunch of work anyway, and would be a step backwards for the second scenario I described (assuming I've understood you correctly). So if anyone is going to be spending significant time on trying to fix this, it would be nice to try and get it right (assuming we're in agreement on what "right" is).
It could be something simple like saving the settings we care about (e.g. colors and cursor shapes) when the dialog is opened, and then when the user saves, you only apply those settings to any open tabs if the values have changed from what they were at the start.
33 remaining items
Skydev0h commentedon Apr 11, 2026
Since this has been open for a while and the most recent fix attempts (#14498, #19933) never landed, I spent a day instrumenting the reload path to get hard numbers on what it actually costs. The instrumentation, a self-contained reproducer, and a full writeup live on this branch (not a PR — explicitly a sitting investigation branch):
https://github.com/Skydev0h/terminal/tree/investigation/gh11522-layout-switch-lag
Measured cost
Captured on an i9-14900K / 96 GB DDR5-6600 / Windows 11 24H2 at ~1.15 GB private-bytes stressed state (40 tabs × 10 000 scrollback lines each, reproducible in under a minute via the bundled
stress-tab.ps1):SettingsChanged.raisesynchronously blocks the UI thread for 3400–3700 ms per reload. Saturated at this state — scales with tabs × scrollback × pattern-scanner lock contention againstControlCore::UpdatePatternLocations, not raw memory size.CascadiaSettings/TerminalSettings/ControlSettings/ControlAppearancegenerations get GC'd.Memory bloat and layout-switch lag are the same bug
Multiple comments on this thread and adjacent issues (#19249, #10609) describe the host process growing to gigabytes over days of uptime. The instrumentation makes the connection direct: each reload triggered by
LanguageProfileNotifier::OnActivated(AppLogic.cpp:151-189) leaks through the same path that causes the visible lag. A user who switches layouts several dozen times a day over a week reaches GB-scale accumulation naturally. When theReloadSettingsThrottled()call in that callback is skipped (localWT_GH11522_SKIP=1env-var toggle in the branch), lag drops to unmeasurable and private bytes stay flat at 1165 MB across 40+ rapid layout events at identical state.5-minute reproducer
WindowsTerminalDev_8wekyb3d8bbwe/wtd.exe)1..40 | ForEach-Object { wtd -w 0 nt powershell -NoExit -File stress-tab.ps1; Start-Sleep -Milliseconds 150 }(file path should be adjusted to the absolute path or file should be in your user directory)*GH11522*Win+Space— observe interleavedlayout-change/reload-done elapsed=~3500mspairs and the frozen UIsetx WT_GH11522_SKIP 1, fully restart Dev WT host, re-stress,Win+Space— observe zeroreload-done, stable private bytes, instant layout switchingNote for anyone who doesn't want to build: replacing
wtdwithwtin step 2 runs the same stress against stock Stable Windows Terminal and reproduces the 3+ second freeze identically — you just don't get theelapsednumbers from the instrumentation. If you have at least two different layouts installed and a few minutes, you can verify the symptom without cloning the branch.Full call-chain walkthrough, data tables, DebugView A/B screenshots, and sketches of three escalating fix tiers (including an extension of Jay Cap (@mrjcap)'s approach in #19933 to also cover
VkKeyScanW-based OEM-punct bindings through achar → chordsidecar inActionMap) are in wt-keyboard-layout-lag-investigation.md on the same branch.Suggested next step
#19933's approach was the right direction and mrjcap addressed all review feedback in the same day — it was never clear from outside why it closed without merge two weeks later. A revival (possibly extended to cover OEM-punct for full character-consistency preservation) would kill both the lag and the memory bloat in one change. Happy to help with the OEM-punct extension work if someone with merge authority wants to pick it back up.
Separate finding surfaced by the instrumentation (filing as its own issue, not to derail this one):
til::ThrottledFuncdebounce prevents scheduling multiple reloads while the timer is pending, but does not prevent re-fire for events arriving during the reload function's execution. Rapidly spammingWin+Spaceduring the 3.5 s freeze reliably chains two back-to-back reloads for 7+ seconds of frozen UI. Nine layout-change events in 625 ms → tworeload-doneevents totaling 7.2 s — captured in the writeup linked above.Keep the font size delta across settings reloads (#20230)
DHowett commentedon May 15, 2026
Alright, I have done this issue somewhat of a disservice. For the longest time, we have been closing mostly reports of "the font size resets when xyz happens" as duplicates of this issue. Now I've fixed that in #20320 (which I'll backport to all existing versions, don't worry.)
The problem is, this issue also tracks the color palette.
Font size is easier. The CLI application can't change it, and there's an explicit reset button you can press to undo changes. Cache the zoom level and re-apply it regardless of the underlying settings; this will not overwrite anything except the user's own preferences. Fine.
Color can be changed by the CLI application almost exclusively and the user at the console can't reset the palette to default. I am hesitant to remove what feels like the only way to restore the colors when an application has left them messed up (by jiggling the settings.)
sba923 commentedon Jun 2, 2026
My tab's color gets reset to the default several times a day (so I have to have the script running in that tab change the color again and again), not because I need to change the keyboard layout, but because I have to fix the issue at https://aka.ms/AAjpd0w, using https://gist.github.com/sba923/a71dd721e78ae08842616db244f19437#file-remove-uselesskeyboardlayouts-ps1 which I run from my profile. So basically (almost) every time I launch a new tab the color for some other tab gets reset...
Edit: And, yes, now I know what the cause is: the zoom factor of all tabs is reset to 100%, way more annoying than the aforementioned tab color issue!
Keep the font size delta across settings reloads (#20230)
Keep the font size delta across settings reloads (#20230)
Omenabaka commentedon Jun 14, 2026
Besides colors, there also remains the problem with the cursor, which also resets on IM change. This constantly hinders work with modal text editors like Neovim, which switch between different cursors in different contexts and use them to indicate modes.
sba923 commentedon Jun 15, 2026
That's indeed more than annoying, this just makes those editors very problematic to use!
Microsoft (@microsoft): again, without this bug https://aka.ms/AAjpd0w (490 upvotes today...), the present issue would not be triggered that often! 😒
pavelbe commentedon Sep 15, 2026
Additional reproduction and UI-thread CPU profiling data for the multi-second layout-switch freeze in #20389 / #20517, on Windows Terminal Preview 1.25.1912.0, Windows 11 build 22631.6199 (captured 2026-09-15).
Reproduction and controls
cmd.exe /dtabs, also reproduced it. That window had its own process/UI thread and the input target was confirmed. Existing working WT windows remained open, and the test tabs had explicit tab colors; this was not a test with every other WT process shut down.experimental.detectURLsis confirmedfalsein the installed Preview's active root settings. Splitting the existing tabs across several windows did not resolve the symptom.CPU profile of an actual reproduction
One 60-second WPR capture used GeneralProfile + XAMLAppResponsiveness while more than ten actual EN/RU switches and input stalls were reproduced in the installed Preview. The relevant HWND was mapped to the process and UI thread before analysis. Analysis was restricted to the first 60 seconds, excluding final rundown/merge. TerminalApp symbols matched the installed module's PDB identity.
The CPU-only stack report contains 41,431 samples for that UI thread:
TerminalPage::_updateThemeColors(inclusive)Tab::_ApplyTabColorOnUIThread(inclusive)Tab::_RefreshVisualState(inclusive)Windows.UI.Xaml.dll(exclusive by module)Inclusive rows overlap and must not be added. These are CPU-sample shares, not elapsed freeze durations. Individual physical layout switches were not separately timestamped in this ETW capture, and capture overhead is a limitation.
Source path matching the profile
In tag
v1.25.1912.0:LanguageProfileNotifiercallsReloadSettingsThrottled().PropertyChanged("BackgroundBrush")calls_updateThemeColors()._RefreshVisualState()changesRequestedThemeLight -> Dark -> previous value, followed by visual-state transitions.This suggests that repeated control notifications during a settings reload amplify full tab/theme refresh work. The profile localizes the dominant CPU cost; it does not establish an exact complexity law or number of invalidations per language switch.
Could the repeated theme invalidations be coalesced or unchanged state skipped while the layout-dependent keybinding work is addressed? Would you prefer this profiling evidence to stay under #11522, or should the theme-refresh amplification be tracked separately?
The raw ETL remains local because it was captured during working sessions; only the extracted counts and public source references are included here.
pavelbe commentedon Sep 15, 2026
Follow-up with an actual locally built and manually tested candidate patch for the multi-second EN/RU UI freeze.
Result: on the affected machine, the patched Preview build switches EN/RU normally with 10 tabs, where the ordinary Preview repeatedly freezes. Session restoration also works after enabling it in the portable configuration. This is a daily-workflow blocker: around ten tabs is a normal workload, and a language change should not stop all input for several seconds on a modern desktop. Please prioritize investigating the repeated theme refresh work below.
Reproduction and comparison
cmd.exe /dtabs; it does not require Linux shell configuration or an LLM application.What changed
The preceding comment includes symbol-matched WPR evidence:
_updateThemeColorsaccounted for 96.01% of 41,431 UI-thread CPU samples, inclusive, not 96% of elapsed freeze time.The candidate keeps the language notification/settings reload path and keyboard mapping intact:
TermControl::_coreBackgroundColorChanged, notifyBackgroundBrushonly when the brush identity or relevant color changes. Handle solid and acrylic tint/fallback colors; continue updating the light/dark contrast state even when no notification is needed.The complete three-file diff below is against upstream tag
v1.25.1912.0, base 1cea42d. It exactly matches the patch packaged with the tested local build. It is proposed code for review, not a claim of an upstream-ready fix for every symptom in this issue.Build: Release/x64, MSVC 14.41.34120, Windows SDK 10.0.22621.0; build completed with 0 errors and 70 warnings. Full upstream tests and clean-machine deployment were not run. Further review should include high-contrast/theme changes, acrylic, tab colors, focused/unfocused panes, shortcuts, and notification reentrancy.
Complete candidate patch (3 files)
Could a maintainer review this coalescing/unchanged-notification approach and advise whether it belongs here or in a separate performance PR? A merged fix in an official release would let affected users stop maintaining a private build just to type in more than one language.
Keep the font size delta across settings reloads (microsoft#20230)
pavelbe commentedon Sep 19, 2026
Follow-up to the full patch and ten-tab test: the same user has now tested the patched build with 50 open terminals and reports that the former RU/EN freezes are gone. The user explicitly identified the build containing the layout patch plus our separate clipboard changes. This is user-observed acceptance on one Windows 11 PC, not an instrumented latency benchmark or an upstream regression-suite result.
Automatic URL detection has also been re-enabled; Ctrl+click works and language switching remains responsive. We are no longer relying on disabling URL detection as a workaround.
The layout patch is still the diff in the linked comment, based on
v1.25.1912.0/1cea42d433253d95c4487a3037db48197b5e72f4. It defers redundant window-wide theme updates during settings application, preserves the existing final refresh, and avoids redundant background-brush notifications while retaining actual color/acrylic changes. It does not suppress language-change notifications or settings reload wholesale.Before the patch, ordinary RU/EN switching with many tabs could stall input for around seven seconds; changing language outside Terminal and returning could also trigger it. The earlier WPR sample analysis and its limitations are in the preceding comments. We have preserved the accepted portable runtime and settings for recovery, without claiming a fresh clean-Windows test or a full stock/patched comparison with identical current settings.
As checked on 2026-09-20, the newest published Preview remains
1.25.1912.0and this issue remains open. Could a maintainer review this fix and advise on the required regression coverage/upstream PR? The repeated user tests suggest a substantial usability improvement for people keeping many long-lived terminal sessions open. Happy to follow the project's preferred test approach; this is evidence for the performance fix, not a claim that every color/zoom-reset symptom in this issue is resolved.DHowett commentedon Sep 20, 2026
HARPCODE DEVELOPER (@pavelbe) please follow the AI contributing guidelines on this repo. This applies to your other issue report as well.
Windows Terminal: keep tab colors through Terminal's own color resets…
drweb86 commentedon Oct 12, 2026
Majority of users use bilingual keyboard and Alt+Shift to change language. This bug fires dozens of times an hour.
Example: Far Manager. Far's maintainers confirmed the cause is Terminal and sent users here: FarGroup/FarManager#1138
I understand the concern that a settings reload is the only way to recover a palette an app left broken. But here nothing is broken: the app is still running and relies on the palette it set. The user didn't touch any setting, they only typed in another language.