Track keyboard labels from host layout events

This commit is contained in:
Babib3l
2026-03-18 21:19:35 +01:00
parent 84f3ce2ca5
commit 39f58e453b
3 changed files with 56 additions and 19 deletions

View File

@@ -1,19 +0,0 @@
namespace Ryujinx.Common.Configuration.Hid
{
public static class KeyboardKeyExtensions
{
public static Key ToKey(this PhysicalKey key)
{
return key is >= PhysicalKey.Unknown and < PhysicalKey.Count
? (Key)(int)key
: Key.Unknown;
}
public static PhysicalKey ToPhysicalKey(this Key key)
{
return key is >= Key.Unknown and < Key.Count
? (PhysicalKey)(int)key
: PhysicalKey.Unknown;
}
}
}

View File

@@ -1,6 +1,7 @@
using Avalonia.Controls;
using Avalonia.Input;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Input;
using System;
using System.Collections.Generic;
@@ -83,6 +84,7 @@ namespace Ryujinx.Ava.Input
{
UpdateKeyState(_semanticPressedKeys, GetInputKey(args, KeyboardInputMode.Semantic), true);
UpdateKeyState(_physicalPressedKeys, GetInputKey(args, KeyboardInputMode.Physical), true);
PhysicalKeyLabelHelper.UpdateFromEvent(args);
KeyPressed?.Invoke(this, args);
}

View File

@@ -3,6 +3,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
using Ryujinx.Common.Configuration.Hid;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using AvaPhysicalKey = Avalonia.Input.PhysicalKey;
using ConfigPhysicalKey = Ryujinx.Common.Configuration.Hid.PhysicalKey;
@@ -12,6 +13,8 @@ namespace Ryujinx.Ava.UI.Helpers
{
internal static class PhysicalKeyLabelHelper
{
private static readonly ConcurrentDictionary<ConfigPhysicalKey, string> _observedLayoutLabels = new();
private static readonly Dictionary<ConfigPhysicalKey, LocaleKeys> _localizedKeysMap = new()
{
[ConfigPhysicalKey.Unknown] = LocaleKeys.KeyboardLayout_KeyUnknown,
@@ -70,6 +73,11 @@ namespace Ryujinx.Ava.UI.Helpers
return GetLocalizedString(localeKey);
}
if (_observedLayoutLabels.TryGetValue(key, out string observedLabel))
{
return observedLabel;
}
if (TryGetPrintableKeySymbol(key, out string label))
{
return label;
@@ -78,6 +86,25 @@ namespace Ryujinx.Ava.UI.Helpers
return key.ToString();
}
public static void UpdateFromEvent(KeyEventArgs args)
{
if (args.KeyModifiers != KeyModifiers.None)
{
return;
}
InputKey inputKey = AvaloniaKeyboardMappingHelper.ToInputKey(args.PhysicalKey);
if (!TryConvertToConfigPhysicalKey(inputKey, out ConfigPhysicalKey physicalKey) || _localizedKeysMap.ContainsKey(physicalKey))
{
return;
}
if (TryNormalizePrintableSymbol(args.KeySymbol, out string label))
{
_observedLayoutLabels[physicalKey] = label;
}
}
private static bool TryGetPrintableKeySymbol(ConfigPhysicalKey key, out string label)
{
// The legacy enum name for the ISO extra key is misleading, so give it a distinct physical label.
@@ -109,6 +136,33 @@ namespace Ryujinx.Ava.UI.Helpers
return true;
}
private static bool TryNormalizePrintableSymbol(string keySymbol, out string label)
{
if (string.IsNullOrEmpty(keySymbol) || keySymbol.Length != 1 || char.IsControl(keySymbol[0]))
{
label = string.Empty;
return false;
}
label = char.IsLetter(keySymbol[0])
? char.ToUpperInvariant(keySymbol[0]).ToString()
: keySymbol;
return true;
}
private static bool TryConvertToConfigPhysicalKey(InputKey key, out ConfigPhysicalKey physicalKey)
{
if (key is >= InputKey.Unknown and < InputKey.Count)
{
physicalKey = (ConfigPhysicalKey)(int)key;
return true;
}
physicalKey = ConfigPhysicalKey.Unknown;
return false;
}
private static string GetLocalizedString(LocaleKeys localeKey)
{
if (OperatingSystem.IsMacOS())