Fix key release events with modifiers not getting handled correctly (#3402)

This commit is contained in:
Moritz Bender 2022-11-25 11:00:44 +01:00 committed by GitHub
parent bae71326bf
commit 1df6ce4e38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 33 deletions

View File

@ -1,7 +1,7 @@
#nullable enable
using System.Linq;
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
@ -20,8 +20,11 @@ namespace BizHawk.Client.Common
Buttons[button] = state;
ProcessSubsets(button, state);
if (state) return;
// when a button is released, all modified variants of it are released as well
foreach (var k in Buttons.Keys.Where(k => k.EndsWith($"+{ie.LogicalButton.Button}")).ToList()) Buttons[k] = false;
// when a button or modifier key is released, all modified key variants with it are released as well
foreach (var k in Buttons.Keys.Where(k =>
k.EndsWith($"+{ie.LogicalButton.Button}") || k.StartsWith($"{ie.LogicalButton.Button}+") || k.Contains($"+{ie.LogicalButton.Button}+"))
.ToArray())
Buttons[k] = false;
}
}
@ -29,6 +32,13 @@ namespace BizHawk.Client.Common
{
protected override void ProcessSubsets(string button, bool state)
{
// we don't want a release of e.g. "Ctrl+E" to release Ctrl as well
if (!state)
{
Buttons[button.SubstringAfterLast('+')] = state;
return;
}
// For controller input, we want Shift+X to register as both Shift and X (for Keyboard controllers)
foreach (var s in button.Split('+')) Buttons[s] = state;
}

View File

@ -64,7 +64,6 @@ namespace BizHawk.Client.EmuHawk
_updateThread.Start();
}
private readonly Dictionary<string, LogicalButton> _modifierState = new Dictionary<string, LogicalButton>();
private readonly WorkingDictionary<string, bool> _lastState = new WorkingDictionary<string, bool>();
private readonly WorkingDictionary<string, int> _axisValues = new WorkingDictionary<string, int>();
private readonly WorkingDictionary<string, float> _axisDeltas = new WorkingDictionary<string, float>();
@ -129,35 +128,6 @@ namespace BizHawk.Client.EmuHawk
};
_lastState[button1] = newState;
// track the pressed events with modifiers that we send so that we can send corresponding unpresses with modifiers
// this is an interesting idea, which we may need later, but not yet.
// for example, you may see this series of events: press:ctrl+c, release:ctrl, release:c
// but you might would rather have press:ctrl+c, release:ctrl+c
// this code relates the releases to the original presses.
// UPDATE - this is necessary for the frame advance key, which has a special meaning when it gets stuck down
// so, i am adding it as of 11-sep-2011
if (newState)
{
_modifierState[button1] = ie.LogicalButton;
}
else
{
if (_modifierState.TryGetValue(button1, out var buttonModifierState))
{
if (buttonModifierState != ie.LogicalButton && !_ignoreEventsNextPoll)
{
_newEvents.Add(
new InputEvent
{
LogicalButton = buttonModifierState,
EventType = InputEventType.Release,
Source = source
});
}
_modifierState.Remove(button1);
}
}
if (!_ignoreEventsNextPoll)
{
_newEvents.Add(ie);