Browse Source

Fix KeyboardInputFilter filtering out repeat events

Equbuxu 2 years ago
parent
commit
e8c375c191

+ 25 - 19
src/PixiEditor/Models/Controllers/KeyboardInputFilter.cs

@@ -1,5 +1,6 @@
 using System.Windows.Input;
 using PixiEditor.Models.Events;
+using TerraFX.Interop.Windows;
 
 namespace PixiEditor.Models.Controllers;
 #nullable enable
@@ -75,17 +76,11 @@ internal class KeyboardInputFilter
         if (key == Key.System)
             key = args.SystemKey;
 
-        if (!UpdateKeyState(key, KeyStates.Down, keyboardState))
-            return;
-
-        key = ConvertRightKeys(key);
-
-        bool raiseConverted = UpdateKeyState(key, KeyStates.Down, converterdKeyboardState);
-
         var (shift, ctrl, alt) = GetModifierStates();
-        OnAnyKeyDown?.Invoke(this, new FilteredKeyEventArgs(key, key, KeyStates.Down, args.IsRepeat, shift, ctrl, alt));
-        if (raiseConverted)
-            OnConvertedKeyDown?.Invoke(this, new FilteredKeyEventArgs(key, key, KeyStates.Down, args.IsRepeat, shift, ctrl, alt));
+        
+        MaybeUpdateKeyState(key, args.IsRepeat, KeyStates.Down, keyboardState, OnAnyKeyDown, shift, ctrl, alt);
+        key = ConvertRightKeys(key);
+        MaybeUpdateKeyState(key, args.IsRepeat, KeyStates.Down, converterdKeyboardState, OnConvertedKeyDown, shift, ctrl, alt);
     }
 
     public void KeyUpInlet(KeyEventArgs args)
@@ -94,16 +89,27 @@ internal class KeyboardInputFilter
         if (key == Key.System)
             key = args.SystemKey;
 
-        if (!UpdateKeyState(key, KeyStates.None, keyboardState))
-            return;
-
+        var (shift, ctrl, alt) = GetModifierStates();
+        
+        MaybeUpdateKeyState(key, args.IsRepeat, KeyStates.None, keyboardState, OnAnyKeyUp, shift, ctrl, alt);
         key = ConvertRightKeys(key);
+        MaybeUpdateKeyState(key, args.IsRepeat, KeyStates.None, converterdKeyboardState, OnConvertedKeyUp, shift, ctrl, alt);
+    }
 
-        bool raiseConverted = UpdateKeyState(key, KeyStates.None, converterdKeyboardState);
-
-        var (shift, ctrl, alt) = GetModifierStates();
-        OnAnyKeyUp?.Invoke(this, new FilteredKeyEventArgs(key, key, KeyStates.None, args.IsRepeat, shift, ctrl, alt));
-        if (raiseConverted)
-            OnConvertedKeyUp?.Invoke(this, new FilteredKeyEventArgs(key, key, KeyStates.None, args.IsRepeat, shift, ctrl, alt));
+    private void MaybeUpdateKeyState(
+        Key key,
+        bool isRepeatFromArgs,
+        KeyStates newKeyState,
+        Dictionary<Key, KeyStates> targetKeyboardState,
+        EventHandler<FilteredKeyEventArgs>? eventToRaise,
+        bool shift,
+        bool ctrl,
+        bool alt)
+    {
+        bool keyWasUpdated = UpdateKeyState(key, newKeyState, targetKeyboardState);
+        bool isRepeat = isRepeatFromArgs && !keyWasUpdated;
+        if (!isRepeat && !keyWasUpdated)
+            return;
+        eventToRaise?.Invoke(this, new FilteredKeyEventArgs(key, key, newKeyState, isRepeat, shift, ctrl, alt));
     }
 }

+ 2 - 2
src/PixiEditor/Models/Events/FilteredKeyEventArgs.cs

@@ -5,12 +5,12 @@ namespace PixiEditor.Models.Events;
 internal class FilteredKeyEventArgs : EventArgs
 {
     public FilteredKeyEventArgs(
-        Key unfilteredKey, Key key, KeyStates state, bool IsRepeat, bool isShiftDown, bool isCtrlDown, bool isAltDown)
+        Key unfilteredKey, Key key, KeyStates state, bool isRepeat, bool isShiftDown, bool isCtrlDown, bool isAltDown)
     {
         UnfilteredKey = unfilteredKey;
         Key = key;
         State = state;
-        this.IsRepeat = IsRepeat;
+        IsRepeat = isRepeat;
 
         ModifierKeys modifiers = ModifierKeys.None;
         if (isShiftDown)