Skip to content

Commit 7606dc4

Browse files
committed
Revert "Preserve Windows key shortcuts"
This reverts commit bfddac1.
1 parent bfddac1 commit 7606dc4

4 files changed

Lines changed: 35 additions & 70 deletions

File tree

AGENTS.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ Primary goals:
2323
risk or complexity.
2424
- Preserve the low-level keyboard hook behavior in `Program.cs`.
2525
- Do not send `Win+Space` as the switching implementation.
26-
- Windows-key shortcuts such as `Win+L` and `Win+Shift+S` must always pass
27-
through untouched.
2826
- Prefer Win32/UI Automation APIs over simulated key chords for language
2927
switching, caret detection, and state management.
3028
- Keyboard-triggered indicators should anchor to the text insertion caret when

CapsLang.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
<Authors>NakornCode</Authors>
1515
<Company>NakornCode</Company>
1616
<Copyright>Copyright © NakornCode</Copyright>
17-
<Version>0.1.2</Version>
18-
<FileVersion>0.1.2.0</FileVersion>
19-
<AssemblyVersion>0.1.2.0</AssemblyVersion>
17+
<Version>0.1.1</Version>
18+
<FileVersion>0.1.1.0</FileVersion>
19+
<AssemblyVersion>0.1.1.0</AssemblyVersion>
2020
</PropertyGroup>
2121
<ItemGroup>
2222
<PackageReference Include="Interop.UIAutomationClient" Version="10.19041.0" />

Program.cs

Lines changed: 32 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@ internal static class Program
2121
private const int VK_CAPITAL = 0x14;
2222
private const int VK_SHIFT = 0x10;
2323
private const int VK_CONTROL = 0x11;
24-
private const int VK_LWIN = 0x5B;
25-
private const int VK_RWIN = 0x5C;
2624
private const int WM_INPUTLANGCHANGEREQUEST = 0x0050;
2725
private const int INPUTLANGCHANGE_FORWARD = 0x0002;
28-
private const int LLKHF_INJECTED = 0x10;
2926
private static readonly IntPtr HKL_NEXT = new(1);
3027

3128
private static IntPtr hookId = IntPtr.Zero;
@@ -170,52 +167,44 @@ private static IntPtr SetHook(LowLevelKeyboardProc proc)
170167

171168
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
172169
{
173-
if (nCode < 0 || IsWindowsKeyDown())
174-
{
175-
return CallNextHookEx(hookId, nCode, wParam, lParam);
176-
}
177-
178170
if (!appSettings.IsCapsLangEnabled)
179171
{
180172
return CallNextHookEx(hookId, nCode, wParam, lParam);
181173
}
182174

183-
var message = wParam.ToInt32();
184-
var keyboardEvent = Marshal.PtrToStructure<KBDLLHOOKSTRUCT>(lParam);
185-
var vkCode = keyboardEvent.vkCode;
186-
187-
if (vkCode == VK_CAPITAL)
175+
if (nCode >= 0)
188176
{
189-
if ((keyboardEvent.flags & LLKHF_INJECTED) != 0)
190-
{
191-
return CallNextHookEx(hookId, nCode, wParam, lParam);
192-
}
177+
var message = wParam.ToInt32();
178+
var vkCode = Marshal.ReadInt32(lParam);
193179

194-
if (message is WM_KEYDOWN or WM_SYSKEYDOWN)
180+
if (vkCode == VK_CAPITAL)
195181
{
196-
if (IsKeyDown(VK_CONTROL))
182+
if (message is WM_KEYDOWN or WM_SYSKEYDOWN)
197183
{
198-
ForceCapsLockOff();
199-
ShowIndicator("CAPS OFF", force: true);
200-
}
201-
else if (IsKeyDown(VK_SHIFT))
202-
{
203-
SetCapsLockState(!IsCapsLockOn());
204-
ShowIndicator(IsCapsLockOn() ? "CAPS ON" : "CAPS OFF", force: true);
184+
if (IsKeyDown(VK_CONTROL))
185+
{
186+
ForceCapsLockOff();
187+
ShowIndicator("CAPS OFF", force: true);
188+
}
189+
else if (IsKeyDown(VK_SHIFT))
190+
{
191+
ToggleCapsLock();
192+
ShowIndicator(IsCapsLockOn() ? "CAPS ON" : "CAPS OFF", force: true);
193+
}
194+
else
195+
{
196+
ForceCapsLockOff();
197+
SwitchToNextInputLanguage();
198+
languagePopupTimer?.Stop();
199+
languagePopupTimer?.Start();
200+
}
205201
}
206-
else
202+
203+
if (message is WM_KEYDOWN or WM_KEYUP or WM_SYSKEYDOWN or WM_SYSKEYUP)
207204
{
208-
ForceCapsLockOff();
209-
SwitchToNextInputLanguage();
210-
languagePopupTimer?.Stop();
211-
languagePopupTimer?.Start();
205+
return new IntPtr(1);
212206
}
213207
}
214-
215-
if (message is WM_KEYDOWN or WM_KEYUP or WM_SYSKEYDOWN or WM_SYSKEYUP)
216-
{
217-
return new IntPtr(1);
218-
}
219208
}
220209

221210
return CallNextHookEx(hookId, nCode, wParam, lParam);
@@ -232,7 +221,10 @@ private static void SwitchToNextInputLanguage()
232221

233222
private static void ForceCapsLockOff()
234223
{
235-
SetCapsLockState(false);
224+
if (IsCapsLockOn())
225+
{
226+
ToggleCapsLock();
227+
}
236228
}
237229

238230
private static bool IsCapsLockOn()
@@ -245,20 +237,7 @@ private static bool IsKeyDown(int virtualKey)
245237
return (GetAsyncKeyState(virtualKey) & 0x8000) != 0;
246238
}
247239

248-
private static bool IsWindowsKeyDown()
249-
{
250-
return IsKeyDown(VK_LWIN) || IsKeyDown(VK_RWIN);
251-
}
252-
253-
private static void SetCapsLockState(bool enabled)
254-
{
255-
if (IsCapsLockOn() != enabled)
256-
{
257-
SetKeyboardStateCapsLock(enabled);
258-
}
259-
}
260-
261-
private static void SetKeyboardStateCapsLock(bool enabled)
240+
private static void ToggleCapsLock()
262241
{
263242
keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero);
264243
keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, UIntPtr.Zero);
@@ -528,16 +507,6 @@ private static Point GetPointerPopupAnchor()
528507

529508
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
530509

531-
[StructLayout(LayoutKind.Sequential)]
532-
private struct KBDLLHOOKSTRUCT
533-
{
534-
public int vkCode;
535-
public int scanCode;
536-
public int flags;
537-
public int time;
538-
public UIntPtr dwExtraInfo;
539-
}
540-
541510
[StructLayout(LayoutKind.Sequential)]
542511
private struct GUITHREADINFO
543512
{
@@ -581,10 +550,10 @@ private struct RECT
581550
private static extern short GetAsyncKeyState(int vKey);
582551

583552
[DllImport("user32.dll")]
584-
private static extern IntPtr GetForegroundWindow();
553+
private static extern void keybd_event(int bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
585554

586555
[DllImport("user32.dll")]
587-
private static extern void keybd_event(int bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
556+
private static extern IntPtr GetForegroundWindow();
588557

589558
[DllImport("user32.dll")]
590559
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ shortcuts such as `Win+Space+1` or `Win+Space+D`.
1212

1313
- Use `CapsLock` to switch to the next Windows input language.
1414
- Keep real CapsLock off during normal typing.
15-
- Leave normal Windows-key shortcuts such as `Win+L` and `Win+Shift+S`
16-
untouched.
1715
- Show the active Windows input language code near the text insertion caret
1816
when the active app exposes caret geometry through Windows UI Automation.
1917
- Avoid mouse-pointer based typing feedback.

0 commit comments

Comments
 (0)