Forum Discussion
Windows 11 language switch hot keys don't always work or work slowly.
I have an (2?) update for this:
(1) There is an opensource tool called 'Keyman' (on website of same name), which fixes this. It is a 'bigger brother' of the windows built-in keyboard-layout manager, but as a side-effect, it is also much better and more efficienty/correctly implemented! Since I installed this, I can now switch keyboards like I _used_ to be able to do in windows, for the last 40 years.
(2) I also believe to have found the culprit for the new win-11 behaviour: It appears they are using their own UWP/WinUI framework for new windows features, and this is exactly the level of (lack of) performance that I encounter with UWP applications. TLDR - to fix it properly, they would have to stop developing their own modern UI features with the equivalent of electron :-/.
There is a third alternative if you want.. As of may 2025, it only takes about 40 lines of code, to implement keyboard layout switching in e.g. C#
So we could program our own, and just avoid using UWP..
I include a sample I made here - beware it doesn't have any UI component, so it would just set all top level windows to use a given layout:
using System;
using System.Text;
using System.Runtime.InteropServices;
using HKL = System.IntPtr; //System.Runtime
class Program {
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); // Delegate matching EnumWindows signature
[DllImport("user32.dll")] private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); // Import EnumWindows from user32.dll
[DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); // Import GetWindowText and GetWindowTextLength to retrieve window titles
[DllImport("user32.dll", SetLastError = true)] private static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll")] private static extern bool IsWindowVisible(IntPtr hWnd); // Import IsWindowVisible to filter visible windows
[DllImport("user32.dll", SetLastError = true)] public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")] public static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
static void Main() {
Console.WriteLine("Enumerating top-level windows:\n");
EnumWindows((IntPtr hWnd, IntPtr lParam) => {
if (IsWindowVisible(hWnd)) {
int length = GetWindowTextLength(hWnd);
if (length > 0) {
StringBuilder sb = new StringBuilder(length + 1);
GetWindowText(hWnd, sb, sb.Capacity);
Console.WriteLine($"HWND: {hWnd}, Title: {sb}");
tryToChange(hWnd);
}
}
return true; // continue enumeration
}, IntPtr.Zero);
}
public const int WM_INPUTLANGCHANGEREQUEST = 0x0050; // #define WM_INPUTLANGCHANGEREQUEST 0x0050
public const int KLF_ACTIVATE = 0x00000001; //const uint KLF_ACTIVATE = 0x00000001;
static void tryToChange(IntPtr hWnd) {
HKL hkl = LoadKeyboardLayout("00000409", KLF_ACTIVATE); // "00000409" = English (US)
PostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, 0, hkl); // IntPtr (LPARAM)
}
}