From 893c87b27bb90cfd3038a611e400273fe8cb9cb5 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 6 Oct 2022 12:10:45 -0700
Subject: [PATCH] Fixed game controller buttons being unresponsive when the
on-screen keyboard is up
Also mapped controller A and B buttons to interact with messagebox dialogs
---
.../main/java/org/libsdl/app/SDLActivity.java | 92 +++++++++++++++----
.../main/java/org/libsdl/app/SDLSurface.java | 70 +-------------
2 files changed, 78 insertions(+), 84 deletions(-)
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index af9265b84d2b..e44cc2d4ea22 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -1232,8 +1232,7 @@ public static boolean getManifestEnvironmentVariables() {
}
// This method is called by SDLControllerManager's API 26 Generic Motion Handler.
- public static View getContentView()
- {
+ public static View getContentView() {
return mLayout;
}
@@ -1304,6 +1303,77 @@ public static boolean isTextInputEvent(KeyEvent event) {
return event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE;
}
+ public static boolean handleKeyEvent(View v, int keyCode, KeyEvent event, InputConnection ic) {
+ int deviceId = event.getDeviceId();
+ int source = event.getSource();
+
+ if (source == InputDevice.SOURCE_UNKNOWN) {
+ InputDevice device = InputDevice.getDevice(deviceId);
+ if (device != null) {
+ source = device.getSources();
+ }
+ }
+
+// if (event.getAction() == KeyEvent.ACTION_DOWN) {
+// Log.v("SDL", "key down: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
+// } else if (event.getAction() == KeyEvent.ACTION_UP) {
+// Log.v("SDL", "key up: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
+// }
+
+ // Dispatch the different events depending on where they come from
+ // Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
+ // So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
+ //
+ // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
+ // SOURCE_JOYSTICK, while its key events arrive from the keyboard source
+ // So, retrieve the device itself and check all of its sources
+ if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) {
+ // Note that we process events with specific key codes here
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ if (SDLControllerManager.onNativePadDown(deviceId, keyCode) == 0) {
+ return true;
+ }
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ if (SDLControllerManager.onNativePadUp(deviceId, keyCode) == 0) {
+ return true;
+ }
+ }
+ }
+
+ if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ if (isTextInputEvent(event)) {
+ if (ic != null) {
+ ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ } else {
+ SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
+ }
+ }
+ onNativeKeyDown(keyCode);
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ onNativeKeyUp(keyCode);
+ return true;
+ }
+ }
+
+ if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
+ // on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
+ // they are ignored here because sending them as mouse input to SDL is messy
+ if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) {
+ switch (event.getAction()) {
+ case KeyEvent.ACTION_DOWN:
+ case KeyEvent.ACTION_UP:
+ // mark the event as handled or it will be handled by system
+ // handling KEYCODE_BACK by system will call onBackPressed()
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
/**
* This method is called by SDL using JNI.
*/
@@ -1486,9 +1556,11 @@ public void onClick(View v) {
// see SDL_messagebox.h
if ((buttonFlags[i] & 0x00000001) != 0) {
mapping.put(KeyEvent.KEYCODE_ENTER, button);
+ mapping.put(KeyEvent.KEYCODE_BUTTON_A, button);
}
if ((buttonFlags[i] & 0x00000002) != 0) {
mapping.put(KeyEvent.KEYCODE_ESCAPE, button); /* API 11 */
+ mapping.put(KeyEvent.KEYCODE_BUTTON_B, button);
}
}
button.setText(buttonTexts[i]);
@@ -1841,21 +1913,7 @@ public boolean onCheckIsTextEditor() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
- /*
- * This handles the hardware keyboard input
- */
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (SDLActivity.isTextInputEvent(event)) {
- ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
- return true;
- }
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
- return false;
+ return SDLActivity.handleKeyEvent(v, keyCode, event, ic);
}
//
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
index 77cf1768b0bc..dcd26d495c87 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java
@@ -189,72 +189,8 @@ public void surfaceChanged(SurfaceHolder holder,
// Key events
@Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
-
- int deviceId = event.getDeviceId();
- int source = event.getSource();
-
- if (source == InputDevice.SOURCE_UNKNOWN) {
- InputDevice device = InputDevice.getDevice(deviceId);
- if (device != null) {
- source = device.getSources();
- }
- }
-
-// if (event.getAction() == KeyEvent.ACTION_DOWN) {
-// Log.v("SDL", "key down: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
-// } else if (event.getAction() == KeyEvent.ACTION_UP) {
-// Log.v("SDL", "key up: " + keyCode + ", deviceId = " + deviceId + ", source = " + source);
-// }
-
- // Dispatch the different events depending on where they come from
- // Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
- // So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
- //
- // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
- // SOURCE_JOYSTICK, while its key events arrive from the keyboard source
- // So, retrieve the device itself and check all of its sources
- if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) {
- // Note that we process events with specific key codes here
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (SDLControllerManager.onNativePadDown(deviceId, keyCode) == 0) {
- return true;
- }
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- if (SDLControllerManager.onNativePadUp(deviceId, keyCode) == 0) {
- return true;
- }
- }
- }
-
- if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (SDLActivity.isTextInputEvent(event)) {
- SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
- }
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
- }
-
- if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
- // on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
- // they are ignored here because sending them as mouse input to SDL is messy
- if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) {
- switch (event.getAction()) {
- case KeyEvent.ACTION_DOWN:
- case KeyEvent.ACTION_UP:
- // mark the event as handled or it will be handled by system
- // handling KEYCODE_BACK by system will call onBackPressed()
- return true;
- }
- }
- }
-
- return false;
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ return SDLActivity.handleKeyEvent(v, keyCode, event, null);
}
// Touch events
@@ -466,4 +402,4 @@ public boolean onCapturedPointerEvent(MotionEvent event)
return false;
}
-}
\ No newline at end of file
+}