Skip to content

Commit 023ab45

Browse files
committed
Use PInvoke instead of DllImport & Several adjustments
1 parent aa3ad10 commit 023ab45

File tree

4 files changed

+87
-92
lines changed

4 files changed

+87
-92
lines changed

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ GetMonitorInfo
4646
MONITORINFOEXW
4747

4848
WM_ENTERSIZEMOVE
49-
WM_EXITSIZEMOVE
49+
WM_EXITSIZEMOVE
50+
51+
GetKeyboardLayout
52+
GetWindowThreadProcessId
53+
ActivateKeyboardLayout
54+
GetKeyboardLayoutList

Flow.Launcher.Infrastructure/Win32Helper.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
using System;
22
using System.ComponentModel;
3+
using System.Linq;
34
using System.Runtime.InteropServices;
45
using System.Windows;
56
using System.Windows.Interop;
67
using System.Windows.Media;
78
using Windows.Win32;
89
using Windows.Win32.Foundation;
910
using Windows.Win32.Graphics.Dwm;
11+
using Windows.Win32.UI.Input.KeyboardAndMouse;
1012
using Windows.Win32.UI.WindowsAndMessaging;
1113
using Flow.Launcher.Infrastructure.UserSettings;
14+
using Point = System.Windows.Point;
1215

1316
namespace Flow.Launcher.Infrastructure
1417
{
@@ -317,5 +320,81 @@ internal static HWND GetWindowHandle(Window window, bool ensure = false)
317320
}
318321

319322
#endregion
323+
324+
#region Keyboard Layout
325+
326+
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f
327+
private static readonly uint[] EnglishLanguageIds =
328+
{
329+
0x0009, 0x0409, 0x0809, 0x0C09, 0x1000, 0x1009, 0x1409, 0x1809, 0x1C09, 0x2009, 0x2409, 0x2809, 0x2C09,
330+
0x3009, 0x3409, 0x3C09, 0x4009, 0x4409, 0x4809, 0x4C09,
331+
};
332+
333+
// Store the previous keyboard layout
334+
private static HKL _previousLayout;
335+
336+
private static unsafe HKL FindEnglishKeyboardLayout()
337+
{
338+
// Get the number of keyboard layouts
339+
int count = PInvoke.GetKeyboardLayoutList(0, null);
340+
if (count <= 0) return HKL.Null;
341+
342+
// Get all keyboard layouts
343+
var handles = new HKL[count];
344+
fixed (HKL* h = handles)
345+
{
346+
_ = PInvoke.GetKeyboardLayoutList(count, h);
347+
}
348+
349+
// Look for any English keyboard layout
350+
foreach (var hkl in handles)
351+
{
352+
// The lower word contains the language identifier
353+
var langId = (uint)hkl.Value & 0xFFFF;
354+
355+
// Check if it's an English layout
356+
if (EnglishLanguageIds.Contains(langId))
357+
{
358+
return hkl;
359+
}
360+
}
361+
362+
return HKL.Null;
363+
}
364+
365+
public static unsafe void SetEnglishKeyboardLayout(bool backupPrevious)
366+
{
367+
// Find an installed English layout
368+
var enHKL = FindEnglishKeyboardLayout();
369+
370+
// No installed English layout found
371+
if (enHKL == HKL.Null) return;
372+
373+
// Get the current window thread ID
374+
uint threadId = 0;
375+
var result = PInvoke.GetWindowThreadProcessId(PInvoke.GetForegroundWindow(), &threadId);
376+
if (result == 0 || threadId == 0) throw new Win32Exception(Marshal.GetLastWin32Error());
377+
378+
// Backup current keyboard layout
379+
if (backupPrevious)
380+
{
381+
_previousLayout = PInvoke.GetKeyboardLayout(threadId);
382+
}
383+
384+
// Switch to English layout
385+
PInvoke.ActivateKeyboardLayout(enHKL, 0);
386+
}
387+
388+
public static void SetPreviousKeyboardLayout()
389+
{
390+
if (_previousLayout != HKL.Null)
391+
{
392+
PInvoke.ActivateKeyboardLayout(_previousLayout, 0);
393+
394+
_previousLayout = HKL.Null;
395+
}
396+
}
397+
398+
#endregion
320399
}
321400
}

Flow.Launcher/Helper/KeyboardLayoutHelper.cs

Lines changed: 0 additions & 88 deletions
This file was deleted.

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
using CommunityToolkit.Mvvm.DependencyInjection;
1515
using CommunityToolkit.Mvvm.Input;
1616
using Flow.Launcher.Core.Plugin;
17-
using Flow.Launcher.Helper;
1817
using Flow.Launcher.Infrastructure;
1918
using Flow.Launcher.Infrastructure.Hotkey;
2019
using Flow.Launcher.Infrastructure.Image;
@@ -1377,7 +1376,7 @@ public void Show()
13771376

13781377
if (StartWithEnglishMode)
13791378
{
1380-
KeyboardLayoutHelper.SetEnglishKeyboardLayout();
1379+
Win32Helper.SetEnglishKeyboardLayout(true);
13811380
}
13821381
});
13831382
}
@@ -1450,7 +1449,7 @@ public async void Hide()
14501449

14511450
if (StartWithEnglishMode)
14521451
{
1453-
KeyboardLayoutHelper.SetPreviousKeyboardLayout();
1452+
Win32Helper.SetPreviousKeyboardLayout();
14541453
}
14551454

14561455
await Task.Delay(50);

0 commit comments

Comments
 (0)