Skip to content

[FEAT]: Tie some key binds to a keyboard layout #84

@claudio4

Description

@claudio4

Is your feature request related to a problem? Please describe.
When switching between different keyboard layouts (e.g., US and Spanish) on Windows, whkd keybindings break because the physical key assigned to a virtual key code changes its reported name.

For example, the key that's Oem4 (left square bracket [) in the US layout becomes Oem1 in the Spanish layout. Similarly, Oem6 (right square bracket ]) in US becomes OemPlus in Spanish. This makes it difficult to maintain consistent keybinds when frequently switching layouts for different tasks like programming and writing.

Describe the solution you'd like
It would be ideal to be able to tie some key combination to a keyboard layout, so it is only enabled when the associated layout is the currently active layout in Windows.

Describe alternatives you've considered
The key binds can be duplicated for those keys that are different between layouts but no are not conflicting. Meanwhile, for those that do conflict, as whkd can run pwsh commands, this monstrosity can be used to determine the active layout and perform a different action.

Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WinKB {
  [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
  [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr p);
  [DllImport("user32.dll")] public static extern IntPtr GetKeyboardLayout(uint idThread);
  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  public static extern bool GetKeyboardLayoutName(System.Text.StringBuilder sb);
}
"@

# get HKL for the thread owning the foreground window
$hkl = [WinKB]::GetKeyboardLayout(
        [WinKB]::GetWindowThreadProcessId([WinKB]::GetForegroundWindow(), [IntPtr]::Zero))

$sb  = New-Object System.Text.StringBuilder 9
[WinKB]::GetKeyboardLayoutName($sb) | Out-Null
$klid = $sb.ToString()            # 

# all Spanish KLIDs ends with 0A
if ($klid.Substring(6,2) -eq "0A") {
  Write-Output "Spanish layout detected – running command A"
  # komorebic A
} else {
  Write-Output "Non-Spanish layout detected – running command B"
  # komorebic B
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions