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

View File

@@ -3,6 +3,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input; using Ryujinx.Ava.Input;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using AvaPhysicalKey = Avalonia.Input.PhysicalKey; using AvaPhysicalKey = Avalonia.Input.PhysicalKey;
using ConfigPhysicalKey = Ryujinx.Common.Configuration.Hid.PhysicalKey; using ConfigPhysicalKey = Ryujinx.Common.Configuration.Hid.PhysicalKey;
@@ -12,6 +13,8 @@ namespace Ryujinx.Ava.UI.Helpers
{ {
internal static class PhysicalKeyLabelHelper internal static class PhysicalKeyLabelHelper
{ {
private static readonly ConcurrentDictionary<ConfigPhysicalKey, string> _observedLayoutLabels = new();
private static readonly Dictionary<ConfigPhysicalKey, LocaleKeys> _localizedKeysMap = new() private static readonly Dictionary<ConfigPhysicalKey, LocaleKeys> _localizedKeysMap = new()
{ {
[ConfigPhysicalKey.Unknown] = LocaleKeys.KeyboardLayout_KeyUnknown, [ConfigPhysicalKey.Unknown] = LocaleKeys.KeyboardLayout_KeyUnknown,
@@ -70,6 +73,11 @@ namespace Ryujinx.Ava.UI.Helpers
return GetLocalizedString(localeKey); return GetLocalizedString(localeKey);
} }
if (_observedLayoutLabels.TryGetValue(key, out string observedLabel))
{
return observedLabel;
}
if (TryGetPrintableKeySymbol(key, out string label)) if (TryGetPrintableKeySymbol(key, out string label))
{ {
return label; return label;
@@ -78,6 +86,25 @@ namespace Ryujinx.Ava.UI.Helpers
return key.ToString(); 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) 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. // 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; 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) private static string GetLocalizedString(LocaleKeys localeKey)
{ {
if (OperatingSystem.IsMacOS()) if (OperatingSystem.IsMacOS())