glazewm
glazewm copied to clipboard
feat: keyboard language component
Component for showing current input language (keyboard layout).
Works for en-US and ja-JP but not for Ukrainian for some reason. It just returns an empty string. Locale ID shows 61608 and LCIDToLocaleName returns an empty string for Ukrainian.
And ukrainian is supposed to be 1058 (0x422) according to https://www.ryadel.com/en/microsoft-windows-lcid-list-decimal-and-hex-all-locale-codes-ids/
For some reason the value from GetKeyboardLayout doesn't follow the same "format" as swedish and us that I tested with. Will try to figure it out.
uk-UA (0x422): 0xfffffffff0a80422; sv-SE (0x41d): 0x00000000041d0809; en-US (0x409): 0x0000000004092000;
Not sure if this will work for every possible language. But added a few at random, and those I tried seem to work fine with this solution. Feels a bit hacky, but seems to be working pretty good.
@jawee I actually just wanted to post another solution right before your commit. Worked for me so far. Haven't tested it extensively though.
private const uint LOCALE_SNAME = 0x0000005c;
private static string GetInputLanguage()
{
var layout = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero));
var sb = new StringBuilder();
GetLocaleInfoW((uint)layout & 0xFFFF, LOCALE_SNAME, sb, sb.Capacity);
return sb.ToString();
}
[DllImport("kernel32.dll")]
public static extern IntPtr GetLocaleInfoW(uint locale, uint LCType, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpLCData, int cchData);
It also might be a good idea to expose the updateInterval for the Observable as a config option, similar to how CpuComponent handles it. 1 second is way too slow for me, and 250 milliseconds feels more responsive, but people might want to configure that themselves.
Your solution looks cleaner in my opinion, I'm open to using that. I'll try to do some more testing sometime within the next few days.
Had a few minutes before having to start work, so I made the refresh interval configureable, I defaulted it to 1 second though, but open to change that to 250ms as well if that's preferable. Once a second works fine for my use case :)
I feel like 1 second is a reasonable default value. Feel free to update the code with the solution I provided if you find it acceptable. Thanks for the component 👍
Did some more testing, with more languages, and my solution seems fine for the all languages I've tried. I also tried your solution, but it didn't work for swedish, so I think my solution is a decent starting point for now. :)
@jawee Very strange. I tested it on Swedish and it worked on my end.
In any case, if it works it works 👍
Probably because I use english language, but swedish keyboard layout. :) (probably really weird..)
Due to the C# -> Rust rewrite, some of these older PRs aren't compatible anymore. Can't merge as is, and I'm sorry about not finding the time to get this in while the C# version was active. Nevertheless, thank you for contributing to GlazeWM 🙏
Ps if you're interested in updating this to be a zebar provider in rust, just lmk!