feat: initial release of SplitOverlay (KeyOverlay 1.0.0)
CI / build-and-test (push) Canceled after 0s

Semi-transparent always-on-top Windows overlay that shows the keymap of a
Vial/QMK split keyboard (Silakka54).

- draws all layers from a Vial .vil layout, transparent keys fall through
- detects the active layer from the keyboard via a Raw HID command (firmware/)
- shows characters of the active Windows input language
- can split the two halves into separate, independently movable windows
- highlights pressed keys; tray menu for opacity, size and options
- Inno Setup installer and portable build; GitHub-style CI workflow
This commit is contained in:
2026-10-20 09:43:17 +03:00
commit 292d61bb47
48 changed files with 2952 additions and 0 deletions
@@ -0,0 +1,103 @@
using KeyOverlay.Core;
using Xunit;
namespace KeyOverlay.Core.Tests;
public class KeyLocalizerTests
{
// Pretends to be a Russian layout: only a few keys are mapped.
private static string? FakeRussian(string keycode, bool shift) => (keycode, shift) switch
{
("KC_Q", false) => "й",
("KC_Q", true) => "Й",
("KC_1", true) => "!",
("KC_SLASH", true) => ",",
("KC_COMMA", false) => "б",
_ => null,
};
[Fact]
public void Letter_IsShownUppercaseInTheActiveLanguage()
{
var localized = KeyLocalizer.Localize(Keycodes.Describe("KC_Q"), FakeRussian);
Assert.Equal("Й", localized.Main);
}
[Fact]
public void ShiftWrappedKey_UsesShiftedCharacter()
{
var localized = KeyLocalizer.Localize(Keycodes.Describe("LSFT(KC_SLASH)"), FakeRussian);
Assert.Equal(",", localized.Main);
}
[Fact]
public void Punctuation_IsReplacedWithLayoutCharacter()
{
var localized = KeyLocalizer.Localize(Keycodes.Describe("KC_COMMA"), FakeRussian);
Assert.Equal("Б", localized.Main); // a letter on a punctuation key is still shown uppercase
}
[Fact]
public void Localizing_KeepsBaseKeycodeForHighlighting()
{
var localized = KeyLocalizer.Localize(Keycodes.Describe("KC_Q"), FakeRussian);
Assert.Equal("KC_Q", localized.BaseKeycode);
}
[Fact]
public void ModTap_KeepsModifierHintAndLocalizesTapKey()
{
var localized = KeyLocalizer.Localize(Keycodes.Describe("LCTL_T(KC_Q)"), FakeRussian);
Assert.Equal("Й", localized.Main);
Assert.Equal("Ctrl", localized.Sub);
}
[Theory]
[InlineData("KC_ESCAPE")]
[InlineData("KC_SPACE")]
[InlineData("KC_LSHIFT")]
[InlineData("KC_RIGHT")]
[InlineData("MO(2)")]
[InlineData("LCTL(KC_Q)")]
public void NonCharacterKeys_AreLeftUntouched(string code)
{
var original = Keycodes.Describe(code);
Assert.Equal(original, KeyLocalizer.Localize(original, FakeRussian));
}
[Fact]
public void UnknownCharacter_FallsBackToDefaultLabel()
{
var original = Keycodes.Describe("KC_W"); // FakeRussian has no mapping for W
Assert.Equal(original, KeyLocalizer.Localize(original, FakeRussian));
}
[Fact]
public void ControlCharacterResult_FallsBackToDefaultLabel()
{
var original = Keycodes.Describe("KC_Q");
var localized = KeyLocalizer.Localize(original, (_, _) => "\u0011");
Assert.Equal(original, localized);
}
[Theory]
[InlineData("KC_A", true)]
[InlineData("KC_5", true)]
[InlineData("KC_GRAVE", true)]
[InlineData("KC_SCOLON", true)]
[InlineData("KC_F1", false)]
[InlineData("KC_ENTER", false)]
public void IsCharacterKey_CoversLettersDigitsAndPunctuation(string code, bool expected) =>
Assert.Equal(expected, Keycodes.IsCharacterKey(code));
[Theory]
[InlineData("KC_A", 0x1E)]
[InlineData("KC_1", 0x02)]
[InlineData("KC_SLASH", 0x35)]
public void ToScanCode_ReturnsPhysicalKeyCode(string code, int expected) =>
Assert.Equal(expected, ScanCodes.ToScanCode(code));
[Fact]
public void ToScanCode_ReturnsNullForUnknownKeycode() =>
Assert.Null(ScanCodes.ToScanCode("KC_NOPE"));
}