Compare commits

...

3 Commits

Author SHA1 Message Date
Babib3l
0a59f8d154 Clear stuck keyboard input when windows lose focus 2026-04-08 19:48:37 +02:00
Babib3l
031cd90048 Log keyboard UI events only on key state changes 2026-04-08 18:19:19 +02:00
Babib3l
8d5adfed14 Gate keyboard event logs behind the Avalonia UI log setting 2026-04-08 17:59:16 +02:00
2 changed files with 32 additions and 5 deletions

View File

@@ -2,6 +2,7 @@ using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Input;
using System;
@@ -23,6 +24,7 @@ namespace Ryujinx.Ava.Input
private static readonly string[] _keyboardIdentifers = ["0"];
private readonly Control _control;
private readonly Window _window;
private readonly HashSet<Key> _semanticPressedKeys;
private readonly HashSet<ConfigPhysicalKey> _physicalPressedKeys;
private readonly Dictionary<Key, ConfigPhysicalKey> _observedPhysicalKeysBySemanticKey;
@@ -41,6 +43,7 @@ namespace Ryujinx.Ava.Input
public AvaloniaKeyboardDriver(Control control, KeyboardInputMode defaultMode = KeyboardInputMode.Semantic)
{
_control = control;
_window = control as Window ?? TopLevel.GetTopLevel(control) as Window;
_semanticPressedKeys = [];
_physicalPressedKeys = [];
_observedPhysicalKeysBySemanticKey = [];
@@ -55,6 +58,12 @@ namespace Ryujinx.Ava.Input
_control.AddHandler(InputElement.KeyDownEvent, OnKeyPress, RoutingStrategies.Tunnel, true);
_control.AddHandler(InputElement.KeyUpEvent, OnKeyRelease, RoutingStrategies.Tunnel, true);
_control.TextInput += Control_TextInput;
_window?.Deactivated += Window_Deactivated;
}
private void Window_Deactivated(object sender, EventArgs e)
{
Clear();
}
private void Control_TextInput(object sender, TextInputEventArgs e)
@@ -98,6 +107,10 @@ namespace Ryujinx.Ava.Input
_control.RemoveHandler(InputElement.KeyDownEvent, OnKeyPress);
_control.RemoveHandler(InputElement.KeyUpEvent, OnKeyRelease);
_control.TextInput -= Control_TextInput;
if (_window != null)
{
_window.Deactivated -= Window_Deactivated;
}
}
}
@@ -208,6 +221,8 @@ namespace Ryujinx.Ava.Input
ConfigPhysicalKey physicalKey = GetPhysicalInputKey(args, semanticKey, out PhysicalKeySource physicalKeySource);
bool semanticWasPressed = _semanticPressedKeys.Contains(resolvedSemanticKey);
bool physicalWasPressed = _physicalPressedKeys.Contains(physicalKey);
bool semanticStateChanged = resolvedSemanticKey is not Key.Unknown and not Key.Unbound && semanticWasPressed != isPressed;
bool physicalStateChanged = physicalKey is not ConfigPhysicalKey.Unknown and not ConfigPhysicalKey.Unbound && physicalWasPressed != isPressed;
bool bufferedSemanticPress = false;
bool bufferedPhysicalPress = false;
@@ -239,9 +254,13 @@ namespace Ryujinx.Ava.Input
_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}");
if (ConfigurationState.Instance.Logger.EnableAvaloniaLog &&
(semanticStateChanged || physicalStateChanged))
{
Logger.Info?.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, out PhysicalKeySource source)

View File

@@ -1234,9 +1234,17 @@ namespace Ryujinx.Ava.Systems
return false;
}
bool hasModalFocusLoss = _viewModel.Window is MainWindow mainWindow &&
mainWindow.SettingsWindow?.IsActive == true;
if (!_viewModel.IsActive || hasModalFocusLoss)
{
_inputManager.KeyboardDriver.Clear();
}
NpadManager.Update(ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat());
if (_viewModel.IsActive)
if (_viewModel.IsActive && !hasModalFocusLoss)
{
bool isCursorVisible = true;
@@ -1369,7 +1377,7 @@ namespace Ryujinx.Ava.Systems
// Touchscreen.
bool hasTouch = false;
if (_viewModel.IsActive && !ConfigurationState.Instance.Hid.EnableMouse.Value)
if (_viewModel.IsActive && !hasModalFocusLoss && !ConfigurationState.Instance.Hid.EnableMouse.Value)
{
hasTouch = TouchScreenManager.Update(true, (_inputManager.MouseDriver as AvaloniaMouseDriver).IsButtonPressed(MouseButton.Button1), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToFloat());
}