diff --git a/osu.Framework.Android/Input/AndroidInputExtensions.cs b/osu.Framework.Android/Input/AndroidInputExtensions.cs
index c0c8c796ec..0cb1e4a63a 100644
--- a/osu.Framework.Android/Input/AndroidInputExtensions.cs
+++ b/osu.Framework.Android/Input/AndroidInputExtensions.cs
@@ -172,6 +172,12 @@ public static bool TryGetMouseButton(this Keycode keycode, out MouseButton butto
return false;
}
+ public static bool IsKeyboard(this InputSourceType source)
+ {
+ // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
+ return source is InputSourceType.Keyboard or (InputSourceType.Keyboard | InputSourceType.Dpad);
+ }
+
public static bool TryGetJoystickButton(this KeyEvent e, out JoystickButton button)
{
var keycode = e.KeyCode;
@@ -192,7 +198,7 @@ public static bool TryGetJoystickButton(this KeyEvent e, out JoystickButton butt
case Keycode.DpadDown:
case Keycode.DpadLeft:
case Keycode.DpadRight:
- case Keycode.Back when e.Source == InputSourceType.Keyboard:
+ case Keycode.Back when e.Source.IsKeyboard():
default:
button = JoystickButton.FirstButton;
return false;
diff --git a/osu.Framework.Android/Input/AndroidInputHandler.cs b/osu.Framework.Android/Input/AndroidInputHandler.cs
index 6e3507f7ed..3c6fa554ca 100644
--- a/osu.Framework.Android/Input/AndroidInputHandler.cs
+++ b/osu.Framework.Android/Input/AndroidInputHandler.cs
@@ -100,7 +100,7 @@ protected virtual bool OnHover(MotionEvent hoverEvent)
/// Subscribe to . to receive events here.
/// Whether the event was handled. Unhandled events are logged.
///
- protected virtual bool OnKeyDown(Keycode keycode, KeyEvent e)
+ protected virtual ReturnCode OnKeyDown(Keycode keycode, KeyEvent e)
{
throw new NotSupportedException($"{nameof(HandleKeyDown)} subscribed to {nameof(View.KeyDown)} but the relevant method was not overriden.");
}
@@ -112,7 +112,7 @@ protected virtual bool OnKeyDown(Keycode keycode, KeyEvent e)
/// Subscribe to . to receive events here.
/// Whether the event was handled. Unhandled events are logged.
///
- protected virtual bool OnKeyUp(Keycode keycode, KeyEvent e)
+ protected virtual ReturnCode OnKeyUp(Keycode keycode, KeyEvent e)
{
throw new NotSupportedException($"{nameof(HandleKeyUp)} subscribed to {nameof(View.KeyUp)} but the relevant method was not overriden.");
}
@@ -191,7 +191,7 @@ protected void HandleKeyDown(Keycode keycode, KeyEvent e)
{
if (ShouldHandleEvent(e))
{
- if (!OnKeyDown(keycode, e))
+ if (OnKeyDown(keycode, e) == ReturnCode.Unhandled)
logUnhandledEvent(nameof(OnKeyDown), e);
}
}
@@ -203,7 +203,7 @@ protected void HandleKeyUp(Keycode keycode, KeyEvent e)
{
if (ShouldHandleEvent(e))
{
- if (!OnKeyUp(keycode, e))
+ if (OnKeyUp(keycode, e) == ReturnCode.Unhandled)
logUnhandledEvent(nameof(OnKeyUp), e);
}
}
@@ -228,5 +228,29 @@ private void logUnhandledEvent(string methodName, InputEvent inputEvent)
{
Log($"Unknown {GetType().ReadableName()}.{methodName} event: {inputEvent}");
}
+
+ protected enum ReturnCode
+ {
+ ///
+ /// Denotes an event that was handled by this handler.
+ ///
+ Handled,
+
+ ///
+ /// Denotes an event that this handler did not handle.
+ ///
+ ///
+ /// Since all events are first put through the filter, an unhandled event is considered a bug and is logged.
+ ///
+ Unhandled,
+
+ ///
+ /// Same as , but will not be logged.
+ ///
+ ///
+ /// Used when an event might also be handled by another handler, but that cannot be determined purely on .
+ ///
+ UnhandledSuppressLogging,
+ }
}
}
diff --git a/osu.Framework.Android/Input/AndroidJoystickHandler.cs b/osu.Framework.Android/Input/AndroidJoystickHandler.cs
index a6d68d1d20..a9942cbce4 100644
--- a/osu.Framework.Android/Input/AndroidJoystickHandler.cs
+++ b/osu.Framework.Android/Input/AndroidJoystickHandler.cs
@@ -64,28 +64,34 @@ public override bool Initialize(GameHost host)
return true;
}
- protected override bool OnKeyDown(Keycode keycode, KeyEvent e)
+ private ReturnCode returnCodeForSource(InputSourceType source)
+ {
+ // keyboard only events are handled in AndroidKeyboardHandler
+ return source.IsKeyboard()
+ ? ReturnCode.UnhandledSuppressLogging
+ : ReturnCode.Unhandled;
+ }
+
+ protected override ReturnCode OnKeyDown(Keycode keycode, KeyEvent e)
{
if (e.TryGetJoystickButton(out var button))
{
enqueueButtonDown(button);
- return true;
+ return ReturnCode.Handled;
}
- // keyboard only events are handled in AndroidKeyboardHandler
- return e.Source == InputSourceType.Keyboard;
+ return returnCodeForSource(e.Source);
}
- protected override bool OnKeyUp(Keycode keycode, KeyEvent e)
+ protected override ReturnCode OnKeyUp(Keycode keycode, KeyEvent e)
{
if (e.TryGetJoystickButton(out var button))
{
enqueueButtonUp(button);
- return true;
+ return ReturnCode.Handled;
}
- // keyboard only events are handled in AndroidKeyboardHandler
- return e.Source == InputSourceType.Keyboard;
+ return returnCodeForSource(e.Source);
}
///
diff --git a/osu.Framework.Android/Input/AndroidKeyboardHandler.cs b/osu.Framework.Android/Input/AndroidKeyboardHandler.cs
index 8aa5f4372c..163bbe8cd9 100644
--- a/osu.Framework.Android/Input/AndroidKeyboardHandler.cs
+++ b/osu.Framework.Android/Input/AndroidKeyboardHandler.cs
@@ -13,7 +13,12 @@ namespace osu.Framework.Android.Input
{
public class AndroidKeyboardHandler : AndroidInputHandler
{
- protected override IEnumerable HandledEventSources => new[] { InputSourceType.Keyboard };
+ protected override IEnumerable HandledEventSources => new[]
+ {
+ InputSourceType.Keyboard,
+ // Some physical keyboards report as (Keyboard | Dpad)
+ InputSourceType.Dpad,
+ };
public AndroidKeyboardHandler(AndroidGameView view)
: base(view)
@@ -44,30 +49,38 @@ public override bool Initialize(GameHost host)
public override bool IsActive => true;
- protected override bool OnKeyDown(Keycode keycode, KeyEvent e)
+ private ReturnCode returnCodeForKeycode(Keycode keycode)
+ {
+ // gamepad buttons are handled in AndroidJoystickHandler
+ return KeyEvent.IsGamepadButton(keycode)
+ ? ReturnCode.UnhandledSuppressLogging
+ : ReturnCode.Unhandled;
+ }
+
+ protected override ReturnCode OnKeyDown(Keycode keycode, KeyEvent e)
{
var key = GetKeyCodeAsKey(keycode);
if (key != Key.Unknown)
{
enqueueInput(new KeyboardKeyInput(key, true));
- return true;
+ return ReturnCode.Handled;
}
- return false;
+ return returnCodeForKeycode(keycode);
}
- protected override bool OnKeyUp(Keycode keycode, KeyEvent e)
+ protected override ReturnCode OnKeyUp(Keycode keycode, KeyEvent e)
{
var key = GetKeyCodeAsKey(keycode);
if (key != Key.Unknown)
{
enqueueInput(new KeyboardKeyInput(key, false));
- return true;
+ return ReturnCode.Handled;
}
- return false;
+ return returnCodeForKeycode(keycode);
}
///
diff --git a/osu.Framework.Android/Input/AndroidMouseHandler.cs b/osu.Framework.Android/Input/AndroidMouseHandler.cs
index 625f2f82ec..21cb95acb0 100644
--- a/osu.Framework.Android/Input/AndroidMouseHandler.cs
+++ b/osu.Framework.Android/Input/AndroidMouseHandler.cs
@@ -136,27 +136,27 @@ private void updatePointerCapture()
View.PointerCapture = shouldCapture;
}
- protected override bool OnKeyDown(Keycode keycode, KeyEvent e)
+ protected override ReturnCode OnKeyDown(Keycode keycode, KeyEvent e)
{
// some implementations might send Mouse1 and Mouse2 as keyboard keycodes, so we handle those here.
if (keycode.TryGetMouseButton(out var button))
{
handleMouseButton(button, true);
- return true;
+ return ReturnCode.Handled;
}
- return false;
+ return ReturnCode.Unhandled;
}
- protected override bool OnKeyUp(Keycode keycode, KeyEvent e)
+ protected override ReturnCode OnKeyUp(Keycode keycode, KeyEvent e)
{
if (keycode.TryGetMouseButton(out var button))
{
handleMouseButton(button, false);
- return true;
+ return ReturnCode.Handled;
}
- return false;
+ return ReturnCode.Unhandled;
}
protected override bool OnHover(MotionEvent hoverEvent)