added layour swithing by caps key
This commit is contained in:
@@ -7,6 +7,14 @@ namespace CursorLang.Interop;
|
||||
/// </summary>
|
||||
internal static class KeyboardLayoutNative
|
||||
{
|
||||
private const uint WmInputLangChangeRequest = 0x0050;
|
||||
|
||||
/// <summary>Взять следующую раскладку из системного списка.</summary>
|
||||
private static readonly IntPtr InputLangChangeForward = new(0x0002);
|
||||
|
||||
/// <summary>HKL_NEXT — та же просьба на языке старых версий Windows.</summary>
|
||||
private static readonly IntPtr HklNext = new(1);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetForegroundWindow();
|
||||
|
||||
@@ -16,24 +24,53 @@ internal static class KeyboardLayoutNative
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetKeyboardLayout(uint idThread);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
/// <summary>
|
||||
/// Раскладка, которой сейчас печатает пользователь.
|
||||
/// </summary>
|
||||
internal static int GetActiveLocaleId() => GetLocaleIdOf(GetInputWindow());
|
||||
|
||||
/// <summary>
|
||||
/// Просит активное приложение перейти на следующую раскладку из системного списка.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Синтезировать системное сочетание вроде Alt+Shift не годится: его назначение
|
||||
/// пользователь меняет в настройках Windows и может отключить вовсе. Просьба
|
||||
/// сообщением от таких настроек не зависит и работает в чужом процессе.
|
||||
/// </remarks>
|
||||
internal static void RequestNextLayout()
|
||||
{
|
||||
IntPtr target = GetInputWindow();
|
||||
if (target == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Оба параметра означают одно и то же: разные версии Windows и разные
|
||||
// библиотеки интерфейса смотрят то на флаг, то на lParam
|
||||
PostMessage(target, WmInputLangChangeRequest, InputLangChangeForward, HklNext);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Окно, которому принадлежит ввод с клавиатуры.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Спрашиваем окно с фокусом клавиатуры, а не окно верхнего плана: у Блокнота
|
||||
/// Windows 11, меню «Пуск» и прочих приложений на WinUI поле ввода живёт в
|
||||
/// отдельном потоке, и раскладка меняется только у него. У потока главного
|
||||
/// окна она остаётся прежней, и переключение проходит незамеченным.
|
||||
/// </remarks>
|
||||
internal static int GetActiveLocaleId()
|
||||
private static IntPtr GetInputWindow()
|
||||
{
|
||||
if (ForegroundInputNative.TryGetInfo(out ForegroundInputNative.GuiThreadInfo info) &&
|
||||
info.hwndFocus != IntPtr.Zero)
|
||||
{
|
||||
return GetLocaleIdOf(info.hwndFocus);
|
||||
return info.hwndFocus;
|
||||
}
|
||||
|
||||
return GetLocaleIdOf(GetForegroundWindow());
|
||||
return GetForegroundWindow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user