Add UI keyboard trace logs for key state and rebinding

This commit is contained in:
Babib3l
2026-03-30 20:07:22 +02:00
parent cd1ce67f89
commit 25306c221d
2 changed files with 43 additions and 3 deletions

View File

@@ -1,3 +1,5 @@
using Ryujinx.Common.Logging;
namespace Ryujinx.Input.Assigner namespace Ryujinx.Input.Assigner
{ {
/// <summary> /// <summary>
@@ -24,7 +26,21 @@ namespace Ryujinx.Input.Assigner
{ {
_keyboardState = _keyboard.GetKeyboardStateSnapshot(); _keyboardState = _keyboard.GetKeyboardStateSnapshot();
_pressedButton ??= GetPressedButtonFromState() ?? GetPressedButtonFromBufferedPress(); if (_pressedButton is not null)
{
return;
}
Button? buttonFromState = GetPressedButtonFromState();
Button? buttonFromBufferedPress = buttonFromState is null ? GetPressedButtonFromBufferedPress() : null;
_pressedButton = buttonFromState ?? buttonFromBufferedPress;
if (_pressedButton is not null)
{
string source = buttonFromState is not null ? "state" : "buffered-press";
Logger.Debug?.Print(LogClass.UI, $"Keyboard assigner registered key={_pressedButton.Value.AsHidType<Key>()}, source={source}, cancelPressed={ShouldCancel()}");
}
} }
public bool IsAnyButtonPressed() public bool IsAnyButtonPressed()

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.Common.Logging;
using Ryujinx.Input; using Ryujinx.Input;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -12,6 +13,13 @@ namespace Ryujinx.Ava.Input
{ {
internal class AvaloniaKeyboardDriver : IKeyboardModeDriver internal class AvaloniaKeyboardDriver : IKeyboardModeDriver
{ {
private enum PhysicalKeySource
{
Direct,
ObservedFallback,
Unknown,
}
private static readonly string[] _keyboardIdentifers = ["0"]; private static readonly string[] _keyboardIdentifers = ["0"];
private readonly Control _control; private readonly Control _control;
private readonly HashSet<Key> _semanticPressedKeys; private readonly HashSet<Key> _semanticPressedKeys;
@@ -193,9 +201,11 @@ namespace Ryujinx.Ava.Input
{ {
Key semanticKey = AvaloniaKeyboardMappingHelper.ToInputKey(args.Key); Key semanticKey = AvaloniaKeyboardMappingHelper.ToInputKey(args.Key);
Key resolvedSemanticKey = AvaloniaKeyboardMappingHelper.ToInputKey(args.PhysicalKey, args.Key); Key resolvedSemanticKey = AvaloniaKeyboardMappingHelper.ToInputKey(args.PhysicalKey, args.Key);
ConfigPhysicalKey physicalKey = GetPhysicalInputKey(args, semanticKey); ConfigPhysicalKey physicalKey = GetPhysicalInputKey(args, semanticKey, out PhysicalKeySource physicalKeySource);
bool semanticWasPressed = _semanticPressedKeys.Contains(resolvedSemanticKey); bool semanticWasPressed = _semanticPressedKeys.Contains(resolvedSemanticKey);
bool physicalWasPressed = _physicalPressedKeys.Contains(physicalKey); bool physicalWasPressed = _physicalPressedKeys.Contains(physicalKey);
bool bufferedSemanticPress = false;
bool bufferedPhysicalPress = false;
UpdateKeyState(_semanticPressedKeys, resolvedSemanticKey, isPressed); UpdateKeyState(_semanticPressedKeys, resolvedSemanticKey, isPressed);
UpdateKeyState(_physicalPressedKeys, physicalKey, isPressed); UpdateKeyState(_physicalPressedKeys, physicalKey, isPressed);
@@ -207,11 +217,13 @@ namespace Ryujinx.Ava.Input
if (!semanticWasPressed && resolvedSemanticKey is not Key.Unknown and not Key.Unbound) if (!semanticWasPressed && resolvedSemanticKey is not Key.Unknown and not Key.Unbound)
{ {
_semanticPressedKeyQueue.Enqueue(resolvedSemanticKey); _semanticPressedKeyQueue.Enqueue(resolvedSemanticKey);
bufferedSemanticPress = true;
} }
if (!physicalWasPressed && physicalKey is not ConfigPhysicalKey.Unknown and not ConfigPhysicalKey.Unbound) if (!physicalWasPressed && physicalKey is not ConfigPhysicalKey.Unknown and not ConfigPhysicalKey.Unbound)
{ {
_physicalPressedKeyQueue.Enqueue((Key)(int)physicalKey); _physicalPressedKeyQueue.Enqueue((Key)(int)physicalKey);
bufferedPhysicalPress = true;
} }
} }
} }
@@ -222,26 +234,38 @@ namespace Ryujinx.Ava.Input
{ {
_observedPhysicalKeysBySemanticKey[semanticKey] = physicalKey; _observedPhysicalKeysBySemanticKey[semanticKey] = physicalKey;
} }
Logger.Trace?.Print(
LogClass.UI,
$"Keyboard {(isPressed ? "down" : "up")}: avaloniaKey={args.Key}, avaloniaPhysical={args.PhysicalKey}, keySymbol={FormatKeySymbol(args.KeySymbol)}, modifiers={args.KeyModifiers}, semantic={semanticKey}, resolvedSemantic={resolvedSemanticKey}, physical={physicalKey}, physicalSource={physicalKeySource}, bufferedSemantic={bufferedSemanticPress}, bufferedPhysical={bufferedPhysicalPress}, semanticPressed={_semanticPressedKeys.Count}, physicalPressed={_physicalPressedKeys.Count}");
} }
private ConfigPhysicalKey GetPhysicalInputKey(KeyEventArgs args, Key semanticKey) private ConfigPhysicalKey GetPhysicalInputKey(KeyEventArgs args, Key semanticKey, out PhysicalKeySource source)
{ {
Key key = AvaloniaKeyboardMappingHelper.ToInputKey(args.PhysicalKey); Key key = AvaloniaKeyboardMappingHelper.ToInputKey(args.PhysicalKey);
if (key is >= Key.Unknown and < Key.Count) if (key is >= Key.Unknown and < Key.Count)
{ {
source = PhysicalKeySource.Direct;
return (ConfigPhysicalKey)(int)key; return (ConfigPhysicalKey)(int)key;
} }
if (semanticKey is not Key.Unknown and not Key.Unbound && if (semanticKey is not Key.Unknown and not Key.Unbound &&
_observedPhysicalKeysBySemanticKey.TryGetValue(semanticKey, out ConfigPhysicalKey observedPhysicalKey)) _observedPhysicalKeysBySemanticKey.TryGetValue(semanticKey, out ConfigPhysicalKey observedPhysicalKey))
{ {
source = PhysicalKeySource.ObservedFallback;
return observedPhysicalKey; return observedPhysicalKey;
} }
source = PhysicalKeySource.Unknown;
return ConfigPhysicalKey.Unknown; return ConfigPhysicalKey.Unknown;
} }
private static string FormatKeySymbol(string keySymbol)
{
return string.IsNullOrEmpty(keySymbol) ? "<none>" : keySymbol;
}
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);