diff --git a/src/Artemis.Core/Models/Surface/ArtemisLed.cs b/src/Artemis.Core/Models/Surface/ArtemisLed.cs index 4cc6d003b..e31594d40 100644 --- a/src/Artemis.Core/Models/Surface/ArtemisLed.cs +++ b/src/Artemis.Core/Models/Surface/ArtemisLed.cs @@ -62,5 +62,11 @@ namespace Artemis.Core (RgbLed.AbsoluteLedRectangle.Size.Height * Device.Surface.Scale).RoundToInt() ); } + + /// + public override string ToString() + { + return RgbLed.ToString(); + } } } \ No newline at end of file diff --git a/src/Artemis.Core/Services/Input/InputService.cs b/src/Artemis.Core/Services/Input/InputService.cs index 191839e7f..c3fb070ab 100644 --- a/src/Artemis.Core/Services/Input/InputService.cs +++ b/src/Artemis.Core/Services/Input/InputService.cs @@ -15,10 +15,6 @@ namespace Artemis.Core.Services { _logger = logger; _surfaceService = surfaceService; - _inputProviders = new List(); - _keyboardModifier = new Dictionary(); - _deviceCache = new Dictionary, ArtemisDevice>(); - _devices = new List(); _surfaceService.ActiveSurfaceConfigurationSelected += SurfaceConfigurationChanged; _surfaceService.SurfaceConfigurationUpdated += SurfaceConfigurationChanged; @@ -38,7 +34,7 @@ namespace Artemis.Core.Services #region Providers - private readonly List _inputProviders; + private readonly List _inputProviders = new List(); public void AddInputProvider(InputProvider inputProvider) { @@ -67,8 +63,8 @@ namespace Artemis.Core.Services #region Identification - private readonly Dictionary, ArtemisDevice> _deviceCache; - private List _devices; + private readonly Dictionary, ArtemisDevice> _deviceCache = new Dictionary, ArtemisDevice>(); + private List _devices = new List(); private ArtemisDevice? _cachedFallbackKeyboard; private ArtemisDevice? _cachedFallbackMouse; private ArtemisDevice? _identifyingDevice; @@ -184,13 +180,18 @@ namespace Artemis.Core.Services #region Keyboard - private readonly Dictionary _keyboardModifier; + private readonly Dictionary> _pressedKeys = new Dictionary>(); + private readonly Dictionary _keyboardModifier = new Dictionary(); private KeyboardModifierKey _globalModifiers; private void InputProviderOnKeyboardDataReceived(object? sender, InputProviderKeyboardEventArgs e) { KeyboardModifierKey keyboardModifierKey = UpdateModifierKeys(e.Device, e.Key, e.IsDown); + // if UpdatePressedKeys is true, the key is already pressed, then we skip this event + if (UpdatePressedKeys(e.Device, e.Key, e.IsDown)) + return; + // Get the LED - TODO: leverage a lookup bool foundLedId = InputKeyUtilities.KeyboardKeyLedIdMap.TryGetValue(e.Key, out LedId ledId); ArtemisLed? led = null; @@ -208,6 +209,31 @@ namespace Artemis.Core.Services // _logger.Verbose("Keyboard data: LED ID: {ledId}, key: {key}, is down: {isDown}, modifiers: {modifiers}, device: {device} ", ledId, e.Key, e.IsDown, keyboardModifierKey, e.Device); } + private bool UpdatePressedKeys(ArtemisDevice? device, KeyboardKey key, bool isDown) + { + if (device != null) + { + // Ensure the device is in the dictionary + _pressedKeys.TryAdd(device, new HashSet()); + // Get the hash set of the device + HashSet pressedDeviceKeys = _pressedKeys[device]; + // See if the key is already pressed + bool alreadyPressed = pressedDeviceKeys.Contains(key); + + // Prevent triggering already down keys again. When a key is held, we don't want to spam events like Windows does + if (isDown && alreadyPressed) + return true; + + // Either add or remove the key depending on its status + if (isDown && !alreadyPressed) + pressedDeviceKeys.Add(key); + else if (!isDown && alreadyPressed) + pressedDeviceKeys.Remove(key); + } + + return false; + } + private KeyboardModifierKey UpdateModifierKeys(ArtemisDevice? device, KeyboardKey key, in bool isDown) { KeyboardModifierKey modifiers = _globalModifiers;