diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java index 3bd9b6704..dea4fbe0a 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java @@ -7,9 +7,12 @@ import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.hardware.input.InputManager; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Vibrator; import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.View; import android.widget.FrameLayout; @@ -209,7 +212,11 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde mContentView = findViewById(R.id.fullscreen_content); mContentView.getHolder().addCallback(this); + mContentView.setFocusableInTouchMode(true); mContentView.setFocusable(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + mContentView.setFocusedByDefault(true); + } mContentView.requestFocus(); // Hook up controller input. @@ -265,6 +272,27 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde showMenu(); } + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN) { + if (mContentView.onKeyDown(event.getKeyCode(), event)) + return true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + if (mContentView.onKeyUp(event.getKeyCode(), event)) + return true; + } + + return super.dispatchKeyEvent(event); + } + + @Override + public boolean dispatchGenericMotionEvent(MotionEvent ev) { + if (mContentView.onGenericMotionEvent(ev)) + return true; + + return super.dispatchGenericMotionEvent(ev); + } + @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationSurfaceView.java b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationSurfaceView.java index f121a7d1a..dae19de45 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationSurfaceView.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationSurfaceView.java @@ -31,31 +31,53 @@ public class EmulationSurfaceView extends SurfaceView { (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK; } + private boolean isExternalKeyCode(int keyCode) { + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + case KeyEvent.KEYCODE_HOME: + case KeyEvent.KEYCODE_MENU: + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_MUTE: + case KeyEvent.KEYCODE_POWER: + case KeyEvent.KEYCODE_CAMERA: + case KeyEvent.KEYCODE_CALL: + case KeyEvent.KEYCODE_ENDCALL: + case KeyEvent.KEYCODE_VOICE_ASSIST: + return true; + + default: + return false; + } + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 && - handleControllerKey(event.getDeviceId(), keyCode, true)) { - return true; - } + if (!isDPadOrButtonEvent(event) || isExternalKeyCode(keyCode)) + return false; - return super.onKeyDown(keyCode, event); + if (event.getRepeatCount() == 0) + handleControllerKey(event.getDeviceId(), keyCode, true); + + return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - if (isDPadOrButtonEvent(event) && event.getRepeatCount() == 0 && - handleControllerKey(event.getDeviceId(), keyCode, false)) { - return true; - } + if (!isDPadOrButtonEvent(event) || isExternalKeyCode(keyCode)) + return false; - return super.onKeyDown(keyCode, event); + if (event.getRepeatCount() == 0) + handleControllerKey(event.getDeviceId(), keyCode, false); + + return true; } @Override public boolean onGenericMotionEvent(MotionEvent event) { final int source = event.getSource(); - if ((source & InputDevice.SOURCE_JOYSTICK) == 0) - return super.onGenericMotionEvent(event); + if ((source & (InputDevice.SOURCE_JOYSTICK | InputDevice.SOURCE_GAMEPAD | InputDevice.SOURCE_DPAD)) == 0) + return false; final int deviceId = event.getDeviceId(); for (AxisMapping mapping : mControllerAxisMapping) { diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java index 19b7961f0..6ac5a724f 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java @@ -41,6 +41,8 @@ public class TouchscreenControllerView extends FrameLayout { public TouchscreenControllerView(Context context) { super(context); + setFocusable(false); + setFocusableInTouchMode(false); } public TouchscreenControllerView(Context context, AttributeSet attrs) {